Files
MCP-Project-bus/docs/TOOL_CONTRACT.md
T
2026-07-30 02:14:43 +02:00

80 lines
3.3 KiB
Markdown

# MCP Tool Contract
Protocol version: `2025-03-26`
Endpoint: `POST /mcp`
Transport profile: stateless Streamable HTTP with JSON responses
`initialize`, `ping`, and `tools/list` do not require credentials. Every
`tools/call` requires `Authorization: Bearer …`. The server does not implement
server-to-client SSE notifications in this MVP; `GET /mcp` returns `405`.
## Common rules
- Every project-scoped call resolves the authenticated principal to one active
membership.
- Every mutation requires a stable `idempotency_key`.
- Reusing a key with the same operation and canonical arguments replays the
original response. Reusing it with different input returns `conflict`.
- IDs use letters, numbers, `.`, `_`, `:`, `/`, or `-`, up to 128 characters.
- Tool domain failures are MCP tool results with `isError: true`.
- JSON-RPC syntax/method failures use JSON-RPC error objects.
- Missing or invalid credentials return HTTP `401`.
## Tools
| Tool | Allowed role / invariant | Primary event |
|---|---|---|
| `create_project` | SYSTEM only | `project.created` |
| `register_actor` | SYSTEM, PO, PM; PM cannot appoint PO | `actor.registered` |
| `issue_work_package` | PO, PM | `work_package.issued` |
| `claim_work_package` | Architect, Lead Engineer, Implementer; atomic OPEN claim | `work_package.claimed` |
| `submit_result` | claiming actor only | `work_package.result_submitted` |
| `request_review` | PO, PM, PA, implementation/design roles; reviewer independent | `review.requested` |
| `submit_review` | assigned independent review actor | `review.submitted` |
| `record_decision` | product: PO; other kinds: PO/PM; never PA | `decision.recorded` |
| `raise_escalation` | every active member | `escalation.raised` |
| `resolve_escalation` | PO, PM | `escalation.resolved` |
| `link_commit` | every active member; valid hexadecimal object ID | `commit.linked` |
| `link_artifact` | every active member | `artifact.linked` |
| `close_gate` | PO, PM; ACCEPT needs independent approval | `gate.closed` |
| `baseline_release` | PO, PM; included work packages accepted | `baseline.released` |
| `sync_since` | every active member; max 500 events | none |
| `list_pending_actions` | every active member, role-filtered reviews/escalations | none |
| `get_work_package` | every active member | none |
| `get_project` | every active member; includes actor-role roster | none |
The authoritative argument schema is returned by `tools/list`. Clients should
discover it instead of hard-coding optional defaults.
## Event envelope
`sync_since` returns:
```json
{
"cursor": 42,
"event_id": "evt_...",
"project_id": "example",
"event_type": "review.submitted",
"actor_id": "reviewer-1",
"actor_role": "REVIEWER",
"aggregate_type": "review",
"aggregate_id": "rev_...",
"correlation_id": "WP-001",
"causation_event_id": null,
"created_at": "2026-07-30T00:00:00.000Z",
"payload": {}
}
```
Event payloads are version-zero MVP structures. Consumers should ignore
unknown fields and key behavior off `event_type`, not prose.
## MCP interoperability limits
The transport implements the required request/response subset used by MCP
tools over Streamable HTTP. It is stateless, does not issue `Mcp-Session-Id`,
does not accept JSON-RPC batches, and provides no resumable SSE channel.
Interoperability must be checked against the concrete ChatGPT and Claude Code
clients during activation.