# Meeting Quorum & Participation Calculator

> See whether the participation you entered reaches your rule, and how much more is needed.

Human page: https://tools.rodri.ai/tools/meeting-quorum
Skill: https://tools.rodri.ai/.well-known/skills/meeting-quorum/SKILL.md
Category: operations
Exports: text, csv, print

## Operations

| Operation | Engine | Cost |
| --- | --- | --- |
| `meeting_quorum.calculate` | deterministic | free, no key |

### `meeting_quorum.calculate`

Calculate participation. No credential needed. Deterministic arithmetic, so it costs no allowance and is rate limited by address.

Input schema version 1, output schema version 1.
MCP tool name: `meeting_quorum_calculate`

Input JSON Schema:

```json
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "communityName": {
      "type": "string",
      "maxLength": 120
    },
    "meetingType": {
      "default": "owner",
      "type": "string",
      "enum": [
        "owner",
        "board"
      ]
    },
    "snapshotKind": {
      "default": "planning",
      "type": "string",
      "enum": [
        "planning",
        "opening",
        "during"
      ]
    },
    "snapshotLabel": {
      "type": "string",
      "maxLength": 80
    },
    "measurement": {
      "default": "equal_votes",
      "type": "string",
      "enum": [
        "equal_votes",
        "weighted_power"
      ]
    },
    "totalEligible": {
      "type": "string",
      "pattern": "^\\d{1,9}(\\.\\d{1,6})?$"
    },
    "representedPower": {
      "anyOf": [
        {
          "type": "string",
          "pattern": "^\\d{1,9}(\\.\\d{1,6})?$"
        },
        {
          "type": "string",
          "const": ""
        }
      ]
    },
    "pendingPower": {
      "anyOf": [
        {
          "type": "string",
          "pattern": "^\\d{1,9}(\\.\\d{1,6})?$"
        },
        {
          "type": "string",
          "const": ""
        }
      ]
    },
    "quorumRule": {
      "oneOf": [
        {
          "type": "object",
          "properties": {
            "kind": {
              "type": "string",
              "const": "fraction"
            },
            "numerator": {
              "type": "string",
              "pattern": "^\\d{1,9}$"
            },
            "denominator": {
              "type": "string",
              "pattern": "^\\d{1,9}$"
            },
            "comparison": {
              "type": "string",
              "enum": [
                "at_least",
                "more_than"
              ]
            }
          },
          "required": [
            "kind",
            "numerator",
            "denominator",
            "comparison"
          ]
        },
        {
          "type": "object",
          "properties": {
            "kind": {
              "type": "string",
              "const": "fixed"
            },
            "amount": {
              "type": "string",
              "pattern": "^\\d{1,9}(\\.\\d{1,6})?$"
            },
            "comparison": {
              "type": "string",
              "enum": [
                "at_least",
                "more_than"
              ]
            }
          },
          "required": [
            "kind",
            "amount",
            "comparison"
          ]
        }
      ]
    },
    "denominatorDisputed": {
      "type": "boolean"
    },
    "rosterMode": {
      "default": "none",
      "type": "string",
      "enum": [
        "none",
        "full",
        "represented_subset"
      ]
    },
    "roster": {
      "maxItems": 1000,
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "identifier": {
            "type": "string",
            "minLength": 1,
            "maxLength": 80
          },
          "weight": {
            "type": "string",
            "pattern": "^\\d{1,9}(\\.\\d{1,6})?$"
          },
          "represented": {
            "type": "boolean"
          },
          "participationNote": {
            "type": "string",
            "maxLength": 80
          }
        },
        "required": [
          "identifier",
          "weight",
          "represented"
        ]
      }
    },
    "ruleReference": {
      "type": "string",
      "maxLength": 1000
    },
    "approval": {
      "anyOf": [
        {
          "type": "object",
          "properties": {
            "threshold": {
              "oneOf": [
                {
                  "type": "object",
                  "properties": {
                    "kind": {
                      "type": "string",
                      "const": "fraction"
                    },
                    "numerator": {
                      "type": "string",
                      "pattern": "^\\d{1,9}$"
                    },
                    "denominator": {
                      "type": "string",
                      "pattern": "^\\d{1,9}$"
                    },
                    "comparison": {
                      "type": "string",
                      "enum": [
                        "at_least",
                        "more_than"
                      ]
                    }
                  },
                  "required": [
                    "kind",
                    "numerator",
                    "denominator",
                    "comparison"
                  ]
                },
                {
                  "type": "object",
                  "properties": {
                    "kind": {
                      "type": "string",
                      "const": "fixed"
                    },
                    "amount": {
                      "type": "string",
                      "pattern": "^\\d{1,9}(\\.\\d{1,6})?$"
                    },
                    "comparison": {
                      "type": "string",
                      "enum": [
                        "at_least",
                        "more_than"
                      ]
                    }
                  },
                  "required": [
                    "kind",
                    "amount",
                    "comparison"
                  ]
                }
              ]
            },
            "basis": {
              "type": "string",
              "enum": [
                "yes_no",
                "represented",
                "all_eligible"
              ]
            },
            "yes": {
              "type": "string",
              "pattern": "^\\d{1,9}(\\.\\d{1,6})?$"
            },
            "no": {
              "type": "string",
              "pattern": "^\\d{1,9}(\\.\\d{1,6})?$"
            },
            "abstain": {
              "default": "0",
              "anyOf": [
                {
                  "type": "string",
                  "pattern": "^\\d{1,9}(\\.\\d{1,6})?$"
                },
                {
                  "type": "string",
                  "const": ""
                }
              ]
            },
            "notVoting": {
              "default": "0",
              "anyOf": [
                {
                  "type": "string",
                  "pattern": "^\\d{1,9}(\\.\\d{1,6})?$"
                },
                {
                  "type": "string",
                  "const": ""
                }
              ]
            },
            "tallyComplete": {
              "default": false,
              "type": "boolean"
            }
          },
          "required": [
            "threshold",
            "basis",
            "yes",
            "no"
          ]
        },
        {
          "type": "null"
        }
      ]
    },
    "locale": {
      "default": "en",
      "type": "string",
      "enum": [
        "en",
        "es"
      ]
    }
  },
  "required": [
    "totalEligible",
    "quorumRule"
  ]
}
```

### Running an operation

Two ways in, and the difference is what an operation costs.

**No credential.** The four calculators are pure arithmetic — no model, nothing
stored, no allowance spent. Rate limited to 30 requests a minute per address.

```http
POST https://tools.rodri.ai/api/agent/tools/{toolId}/runs
Content-Type: application/json

{"operation": "meeting_quorum.calculate", "input": { ... }}
```

**With an API key.** Everything else, including every AI operation. The key's
owner creates it at https://tools.rodri.ai/account. It carries exactly their entitlements: a
free account has 20 AI credits a month and unlimited use of the calculators.
A key grants nothing its owner does not already have.

```http
POST https://tools.rodri.ai/api/agent/tools/{toolId}/runs
Authorization: Bearer hpt_live_…
Content-Type: application/json

{"operation": "resident_notice.generate", "input": { ... }}
```

Errors come back as `{"error": {"code", "message", "retryable"}}`. Branch on
`code` — `QUOTA_EXHAUSTED`, `RATE_LIMITED`, `REGISTRATION_REQUIRED`,
`VALIDATION_ERROR` — not on the sentence, which is written for people and is
translated.

**MCP.** The same operations are exposed at `https://tools.rodri.ai/api/mcp` over Streamable
HTTP. It is stateless, so POST JSON-RPC and read the JSON reply; the same
`Authorization` header applies.
