# Resident Notice Generator

> Enter the facts once. Get a clear notice for email, messaging, and the notice board.

Human page: https://tools.rodri.ai/tools/resident-notice
Skill: https://tools.rodri.ai/.well-known/skills/resident-notice/SKILL.md
Category: communication
Exports: text, print

## Operations

| Operation | Engine | Cost |
| --- | --- | --- |
| `resident_notice.generate` | ai | 1 AI credit |

### `resident_notice.generate`

Draft notice. Needs an API key. Spends 1 AI credit from the key owner's monthly allowance.

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

Input JSON Schema:

```json
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "noticeType": {
      "type": "string",
      "enum": [
        "maintenance_outage",
        "meeting_invitation",
        "rule_reminder",
        "event",
        "project_update",
        "assessment_update"
      ]
    },
    "audience": {
      "type": "string",
      "minLength": 1,
      "maxLength": 120
    },
    "summary": {
      "type": "string",
      "minLength": 1,
      "maxLength": 20000
    },
    "facts": {
      "default": [],
      "maxItems": 40,
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 40
          },
          "label": {
            "type": "string",
            "minLength": 1,
            "maxLength": 80
          },
          "kind": {
            "type": "string",
            "enum": [
              "text",
              "date",
              "time_range",
              "amount",
              "location",
              "count"
            ]
          },
          "value": {
            "type": "string",
            "maxLength": 400
          },
          "originalWording": {
            "type": "string",
            "maxLength": 400
          },
          "origin": {
            "type": "string",
            "enum": [
              "user",
              "source",
              "tool_result"
            ]
          },
          "confirmed": {
            "default": true,
            "type": "boolean"
          },
          "citationIds": {
            "default": [],
            "maxItems": 5,
            "type": "array",
            "items": {
              "type": "string",
              "maxLength": 64
            }
          },
          "conflictsWith": {
            "type": "string",
            "maxLength": 400
          }
        },
        "required": [
          "id",
          "label",
          "kind",
          "value",
          "origin"
        ]
      }
    },
    "requestedAction": {
      "type": "string",
      "maxLength": 400
    },
    "informationalOnly": {
      "default": false,
      "type": "boolean"
    },
    "contactDetails": {
      "type": "string",
      "maxLength": 300
    },
    "signature": {
      "type": "string",
      "maxLength": 120
    },
    "communityName": {
      "type": "string",
      "maxLength": 120
    },
    "timeZone": {
      "type": "string",
      "maxLength": 64
    },
    "tone": {
      "default": "clear_friendly",
      "type": "string",
      "enum": [
        "clear_friendly",
        "neutral_formal",
        "concise_direct"
      ]
    },
    "language": {
      "default": "en",
      "type": "string",
      "enum": [
        "en",
        "es",
        "bilingual"
      ]
    },
    "currency": {
      "default": "USD",
      "type": "string",
      "maxLength": 8
    },
    "allowPlaceholders": {
      "default": false,
      "type": "boolean"
    },
    "sourceSetId": {
      "type": "string",
      "format": "uuid",
      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
    },
    "sourceSetVersion": {
      "type": "integer",
      "exclusiveMinimum": 0,
      "maximum": 9007199254740991
    },
    "locale": {
      "default": "en",
      "type": "string",
      "enum": [
        "en",
        "es"
      ]
    }
  },
  "required": [
    "noticeType",
    "audience",
    "summary"
  ]
}
```

### 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.
