MCP v2 - I/O Definition
This page defines the implemented wire contract for
guinness-backend/apps/mcp-v2. MCP v2 exposes six tools and delegates every
domain operation to backend internal APIs.
Transport and Authentication
Endpoint:
Deployed request headers:
Content-Type: application/json
X-MCP-Token: <cloudfront-secret-header-value>
MCP-API-Key: guinness_<prefix>_<secret>
Authorization: Bearer <mcp-api-key> is accepted instead of MCP-API-Key.
| Header | Required | Validation |
|---|---|---|
X-MCP-Token |
yes outside ENVIRONMENT=local |
non-empty and constant-time equal to CLOUDFRONT_SECRET_HEADER |
MCP-API-Key |
one API-key header required | preferred source of MCP API key |
Authorization |
alternative | Bearer token used only when MCP-API-Key is absent |
Content-Type |
POST JSON-RPC | application/json |
MCP API-key authentication:
- Parse the
guinness_<prefix>_<secret>key. - Read PostgreSQL
mcp_api_keysby prefix withdeleted_at IS NULL. - Verify the stored salted scrypt hash.
- Reject revoked, expired, deleted, malformed, or unknown keys.
- Require a positive project scope; unscoped keys receive HTTP 403.
- Update
last_used_atasynchronously.
Each HTTP request creates a fresh McpServer and
StreamableHTTPTransport(sessionIdGenerator: undefined) to keep concurrent
clients isolated.
Request Flow
sequenceDiagram
participant Client
participant MCP as MCP v2
participant PG as PostgreSQL
participant Backend as Backend internal API
participant AI as AI-v2/SQS worker
participant S3
Client->>MCP: JSON-RPC tools/call
MCP->>MCP: validate X-MCP-Token
MCP->>PG: authenticate API key
MCP->>MCP: require project scope + validate arguments
MCP->>Backend: X-API-Key + X-MCP-Project-ID
alt trigger-des2code
Backend->>Backend: authorize completed design
Backend->>AI: require current code_index ready
Backend->>AI: send flat SQS payload
AI->>S3: request artifact
AI->>Backend: AI-status webhook
else get-des2code
Backend->>S3: newest scoped request artifact
else source list/detail
Backend->>AI: scoped internal read
end
Backend-->>MCP: JSON
MCP-->>Client: content + structuredContent
MCP v2 has no AWS, DocumentDB, AI-provider, Figma, S3, or webhook client.
JSON-RPC Request
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "trigger-des2code",
"arguments": {
"design_id": "42_file_node:1",
"project_id": 42,
"organization_id": 1
}
}
}
Validation failures return an MCP response with isError: true. They do not
call backend.
Tool Inputs
trigger-des2code
| Field | Type | Required | Validation |
|---|---|---|---|
design_id |
string | yes | length 1-500; alphanumeric, _, :, - |
project_id |
integer | yes | > 0; must equal authenticated project scope |
organization_id |
integer | yes | > 0; backend revalidates against design scope |
The authenticated key must have WRITE permission.
get-des2code
| Field | Type | Required | Validation |
|---|---|---|---|
design_id |
string | yes | same design ID constraints; project parsed from ID is checked when available |
list-designs and list-code
| Field | Type | Required | Validation |
|---|---|---|---|
project_id |
integer | yes | > 0; equals authenticated scope |
organization_id |
integer | no | > 0 when present |
limit |
integer | no | default 20; 1..100 |
offset |
integer | no | default 0; >= 0 |
get-design-detail
| Field | Type | Required | Validation |
|---|---|---|---|
design_id |
string | yes | same design ID constraints |
get-code-detail
| Field | Type | Required | Validation |
|---|---|---|---|
code_id |
string | yes | UUID v4 |
project_id |
integer | yes | > 0; equals authenticated scope |
organization_id |
integer | no | > 0 when present |
The current server does not register codebase-rule or code-index tools.
Processing Contract
- Create a fresh MCP server/transport for the HTTP request.
- Validate
X-MCP-Tokenoutside local development. - Read the MCP API key from
MCP-API-Keyor Bearer auth. - Authenticate the PostgreSQL key and require a positive project scope.
- Validate tool arguments with strict Zod schemas.
- Require
WRITEpermission fortrigger-des2code. - Enforce project scope before backend I/O.
- Call the mapped backend internal API with
X-API-KeyandX-MCP-Project-ID. - Map non-2xx/invalid backend results to MCP
isError: true. - Return human-readable
contentplus machine-readablestructuredContent. - Update key
last_used_atasynchronously.
The server returns six tools from tools/list. No operation bypasses backend
authorization to call AI-v2 or storage directly.
MCP to Backend Internal API
| MCP tool | Backend request | Body/query |
|---|---|---|
trigger-des2code |
POST /internal/des2code |
{design_id, project_id, organization_id} |
get-des2code |
GET /internal/des2code/{design_id} |
path ID |
list-designs |
GET /internal/designs |
project, optional org, limit, offset |
list-code |
GET /internal/code |
project, optional org, limit, offset |
get-design-detail |
GET /internal/designs/{design_id} |
path ID |
get-code-detail |
GET /internal/code/{code_id} |
project and optional org query |
Headers:
Accept: application/json
Content-Type: application/json
X-API-Key: <BACKEND_INTERNAL_API_KEY>
X-MCP-Project-ID: <authenticated-project-id>
BACKEND_INTERNAL_API_KEY and project scope are required by current MCP-v2
configuration/authentication. Requests use
BACKEND_INTERNAL_TIMEOUT_MS (default 10000, maximum 120000).
Backend may return raw JSON or { "ok": true, "data": ... }; MCP unwraps the
success envelope.
Backend Producer Payloads
MCP v2 does not produce worker messages. Backend owns readiness and SQS.
design-import
Design import is outside MCP-v2 transport. The resulting canonical AI-v2
design is discoverable through list-designs/get-design-detail. Detail
responses omit all vector_embedding fields.
code-import
Code and Storybook imports are outside MCP-v2 transport. Imported code is
discoverable through list-code/get-code-detail; detail responses return
source/CSS and metadata without embedding vectors.
des2code
Backend validates PostgreSQL design scope/status and the current AI-v2
DocumentDB index, generates UUIDv7 request_id, and sends:
{
"design_id": "42_file_node:1",
"project_id": 42,
"organization_id": 1,
"request_id": "0192a3b4-c5d6-7e8f-9a0b-1c2d3e4f5a6b"
}
The worker independently requires its current scoped code_index to be
ready. The payload has no schema version, operation, index token, model,
prompt, or bound override.
Backend Downstream AI-v2 Read API
Backendโnot MCPโcalls service-token-protected AI-v2 internal routes for:
- current code-index readiness;
- paginated design/code source summaries;
- one design/code source detail without vectors.
Backend also reads Des2Code results directly from the backend AI S3 bucket. It
authorizes the design, lists only canonical filenames under the scoped design
prefix, selects the newest LastModified/key, validates artifact scope and
shape, and returns the normalized result.
MCP Outputs
trigger-des2code success
{
"content": [{"type": "text", "text": "Successfully triggered des2code matching for design ID: 42_file_node:1"}],
"structuredContent": {
"success": true,
"design_id": "42_file_node:1",
"project_id": 42,
"organization_id": 1,
"request_id": "0192a3b4-c5d6-7e8f-9a0b-1c2d3e4f5a6b",
"timestamp": "2026-08-11T10:00:00.000Z"
},
"isError": false
}
get-des2code success
structuredContent includes:
{
"design_id": "42_file_node:1",
"status": "success",
"matched_code_count": 1,
"matched_codes": [{
"code_id": "0192a3b4-c5d6-4e8f-9a0b-1c2d3e4f5a6b",
"name": "Button",
"semantic_similarity": 0.89,
"context_similarity": 0.84,
"region_similarity": 0.91,
"variation_similarity": 0.95,
"variation_mode": "state_required"
}],
"matched_usage_count": 1,
"usage_matches": [{
"node_id": "40002029:37101",
"code_id": "0192a3b4-c5d6-4e8f-9a0b-1c2d3e4f5a6b",
"variation_id": "visual_primary",
"variation_name": "Primary",
"confidence": 0.97
}],
"code_index_id": "code-index-scope-hash",
"request_id": "0192a3b4-c5d6-7e8f-9a0b-1c2d3e4f5a6b",
"retrieval_diagnostics": {},
"usage_diagnostics": {},
"matcher_configuration": {},
"model_summary": {},
"artifact": {
"bucket": "dev-guinness-backend",
"key": "1/42/des2code/42_file_node:1/request.json",
"content_type": "application/json",
"expires_at": "2026-09-10T10:00:00Z"
},
"processed_at": 1786442400000,
"error": null
}
Human-readable text intentionally summarizes matched implementations and tells the client to use detail tools for complete source/CSS.
list-designs / list-code success
The structured result preserves:
{
"project_id": 42,
"organization_id": 1,
"total_count": 563,
"returned_count": 20,
"limit": 20,
"offset": 0,
"items": []
}
Detail success
Design/code detail is returned under design or code with timestamp.
Vector fields are omitted. Code detail includes source/CSS; design detail
includes canonical visual/semantic/structure metadata.
Error response
{
"content": [{"type": "text", "text": "Failed to trigger des2code matching: ..."}],
"structuredContent": {
"error": "...",
"timestamp": "2026-08-11T10:00:00.000Z"
},
"isError": true
}
| Condition | Result |
|---|---|
| Missing/invalid edge token | HTTP 401 outside local |
| Missing/invalid MCP API key | HTTP 401 |
| Unscoped API key | HTTP 403 |
| Cross-project tool arguments | MCP isError: true before backend call |
| Read-only trigger | MCP isError: true before backend call |
| Design import/index not ready | MCP error mapped from backend 409 |
| Backend timeout/non-2xx/invalid JSON | MCP isError: true |
Idempotency and Consistency
- MCP server/transport state is request-local; no cross-client session state is reused.
- Authentication
last_used_atupdates are non-blocking and do not change tool output. - One trigger creates one backend UUIDv7 request ID. Backend SQS retries preserve it.
- The worker writes one request-scoped artifact key; retrying the same message reuses that key.
- Re-triggering the same design creates another request artifact.
get-des2codereturns the newest contract-valid success or failure artifact by S3 ordering, not a PostgreSQL run/status row.- Backend and worker both enforce current code-index readiness; the worker stores the used DocumentDB
_idascodeIndexId.