3.3 KiB
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:
{
"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.