# Tool Contracts ## Naming ```text .. ``` Examples: ```text project.status.get gitea.repository.list gitea.file.read knowledge.document.search unraid.container.list unraid.container.inspect unraid.container.logs ``` Names are lowercase ASCII, dot-separated, stable, and globally unique within the Hub. Do not include project names in canonical tool names; project scope comes from the virtual server and identity context. ## Required manifest fields - canonical name and semantic version; - title and managed description; - connector type; - input and output JSON Schema; - risk class; - required capability and scopes; - allowed environment classes; - timeout, rate, row/item, and byte limits; - redaction profile; - idempotency and side-effect annotation; - lifecycle status and replacement when deprecated. ## Inputs - reject unknown fields by default; - use enums and bounded strings; - use opaque registered references rather than raw paths/URLs; - pagination uses bounded `limit` and opaque cursor; - environment/project are not accepted when endpoint context already determines them. ## Outputs - structured data first; - stable machine-readable error code; - explicit truncation and cursor; - source and generated time metadata; - no secrets, raw auth headers, or unbounded logs; - validate against the output schema before returning. ## Side effects Every v1.0 tool is `readOnly: true`. The v1.1 Gitea exception is an exact R2 allowlist of six tools: branch, issue, comment, bounded file and pull-request creation/update. MCP annotations must truthfully mark them non-read-only and the client must confirm the external action. The server independently enforces the project binding, R2 policy, separate write credential, safe change-branch namespace, input budgets and target allowlist. A tool whose target API might mutate through a GET-like endpoint remains prohibited.