Skip to content

MCP v2 Overview

guinness-backend/apps/mcp-v2 is the Model Context Protocol server for the V2 design-to-code workflow. It exposes six project-scoped design, code, and Des2Code tools to coding assistants.

MCP v2 owns transport, CloudFront token validation, PostgreSQL-backed MCP API key authentication, project/write permission checks, and request-scoped tool registration. All domain operations are delegated to guinness-backend/apps/app internal APIs. MCP v2 does not call SQS, DocumentDB, AI-v2, or S3 directly.

Target Architecture

flowchart TD
    Client["MCP client"] --> CF["CloudFront<br/>X-MCP-Token"]
    CF --> MCP["apps/mcp-v2<br/>stateless HTTP /mcp"]
    MCP --> Auth["PostgreSQL mcp_api_keys"]
    MCP -->|"X-API-Key + X-MCP-Project-ID"| Backend["apps/app internal API"]
    Backend --> PG[("PostgreSQL<br/>design/code/project scope")]
    Backend -->|"trigger"| Q["SQS des2code"]
    Q --> Worker["guinness-ai-v2 apps/des2code"]
    Worker --> DocDB[("DocumentDB<br/>design/code/variation/graph/index")]
    Worker --> S3[("S3 request artifacts")]
    Worker -->|"AI-status webhook"| Backend
    Backend -->|"source/index reads"| AIAPI["guinness-ai-v2 internal API"]
    AIAPI --> DocDB
    Backend -->|"latest result read"| S3
Area Owner Rule
MCP transport and edge auth apps/mcp-v2 Fresh McpServer/transport per request; CloudFront token required outside local.
MCP API-key auth apps/mcp-v2 + PostgreSQL Authenticate active mcp_api_keys, require a valid project scope, enforce write permission for trigger.
Domain authorization/orchestration apps/app Revalidate project/org/design scope, design readiness, current AI-v2 index readiness, and SQS dispatch.
Source detail/list AI-v2 DocumentDB through backend MCP calls backend; backend proxies AI-v2 service-token routes and strips vectors.
Des2Code execution AI-v2 worker Scoped canonical retrieval/matching, S3 artifact, webhook.
Des2Code result Backend + S3 Backend authorizes design scope and returns newest contract-valid request artifact; no result row in PostgreSQL.

MCP Tools

Tool Purpose MCP v2 downstream
trigger-des2code Queue matching for an imported design POST /internal/des2code
get-des2code Read newest success/failure artifact for one design GET /internal/des2code/{design_id}
list-designs List imported design sources GET /internal/designs
list-code List imported code sources GET /internal/code
get-design-detail Read one design source without vectors GET /internal/designs/{design_id}
get-code-detail Read one code source without vectors GET /internal/code/{code_id}

trigger-des2code requires an MCP key with WRITE permission. Every MCP API key accepted by the server must be project-scoped. Code-index rebuild/status and codebase-rule CRUD are not MCP v2 tools in the current implementation.


MCP Auth Contract

MCP v2 authenticates API keys with PostgreSQL mcp_api_keys.

flowchart LR
    Header["MCP-API-Key<br/>or Authorization: Bearer"] --> Parse["Parse guinness_prefix_secret"]
    Parse --> PG["PostgreSQL lookup by key_prefix"]
    PG --> Verify["scrypt verify"]
    Verify --> State["deleted/revoked/expired checks"]
    State --> Scope["positive project_id required"]
    Scope --> LastUsed["async last_used_at update"]
Requirement Behavior
Edge token X-MCP-Token must match CLOUDFRONT_SECRET_HEADER outside ENVIRONMENT=local; constant-time comparison
API-key headers Prefer MCP-API-Key; accept Authorization: Bearer <api-key>
Database PostgreSQL/Drizzle, table mcp_api_keys
Lookup key_prefix with deleted_at IS NULL
Verification Stored salt/hash using the configured scrypt contract
Validity Reject revoked, expired, deleted, malformed, or unknown keys
Scope Reject keys without a positive project ID; every tool is constrained to it
Permission trigger-des2code requires WRITE; read tools use authenticated project scope
Audit Update last_used_at asynchronously; update failure is logged and non-blocking

Schema reference: PostgreSQL mcp_api_keys.


Backend Internal API Contract

MCP v2 sends the authenticated project ID to backend. Backend repeats scope validation before PostgreSQL, SQS, AI-v2, or S3 access.

sequenceDiagram
    participant Client as MCP client
    participant MCP as apps/mcp-v2
    participant Backend as apps/app internal API
    participant AI as guinness-ai-v2 internal API/worker
    participant S3 as S3

    Client->>MCP: tools/call
    MCP->>MCP: edge + API-key auth, schema, permission/scope
    MCP->>Backend: X-API-Key + X-MCP-Project-ID
    alt trigger-des2code
        Backend->>Backend: authorize design and require completed import
        Backend->>AI: read current code_index; require ready
        Backend->>AI: SQS flat design/scope/request payload
        AI->>S3: write request artifact
        AI->>Backend: AI-status webhook
    else get-des2code
        Backend->>S3: list authorized design prefix
        Backend-->>MCP: newest strict artifact projection
    else list/detail source
        Backend->>AI: service-token scoped read
        AI-->>Backend: source without vectors
    end
    Backend-->>MCP: JSON result
    MCP-->>Client: text + structuredContent

Required MCP-to-backend headers:

Header Required Purpose
X-API-Key Yes backend internal service authentication
X-MCP-Project-ID Yes repeat authenticated project-scope enforcement

Backend internal routes consumed by MCP v2:

Route Backend responsibility
POST /internal/des2code Validate design/project/org and MCP scope, require completed design + ready AI-v2 index, generate request ID, send SQS.
GET /internal/des2code/{design_id} Authorize design, find newest canonical S3 artifact, validate full scope/shape.
GET /internal/designs Validate project scope and proxy paginated AI-v2 design summaries.
GET /internal/designs/{design_id} Validate design/project scope and proxy detail without vectors.
GET /internal/code Validate project scope and proxy paginated AI-v2 code summaries.
GET /internal/code/{code_id} Validate code/project/optional org scope and proxy detail without vectors.

Backend, SQS, and AI-v2 Contract

Backend sends exactly this worker body after all readiness checks:

{
  "design_id": "42_file_node:1",
  "project_id": 42,
  "organization_id": 1,
  "request_id": "0192a3b4-c5d6-7e8f-9a0b-1c2d3e4f5a6b"
}

There is no schema_version, operation, or codebase_index_token. Backend checks the current AI-v2 DocumentDB code_index through its internal read API, but the worker independently loads and requires the current scoped index to be ready before retrieval.

The worker writes {organization_id}/{project_id}/des2code/{design_id}/{request_id}.json (or {request_id}-failed.json) and sends the shared AI-status webhook. The webhook validates design scope and logs operational status; it does not store the Des2Code result or artifact pointer in PostgreSQL.

Design/code list and detail reads follow this path only:

MCP v2 -> backend internal API -> AI-v2 internal API -> DocumentDB

MCP v2 never receives DocumentDB credentials or embedding vectors.


Backend API Handoff

get-des2code returns implementation and occurrence evidence in structuredContent: matched_codes, usage_matches, code_index_id, request_id, retrieval/usage diagnostics, matcher configuration, model summary, artifact metadata, status, processed time, and error.

For implementation work, the client should:

  1. use list-designs to discover a design ID when necessary;
  2. call trigger-des2code with exact design/project/organization scope;
  3. poll get-des2code until an artifact is returned;
  4. inspect usage_matches for Figma-node/state mappings;
  5. call get-code-detail for each selected code_id to retrieve full source/CSS;
  6. use Figma MCP separately to inspect the referenced node geometry/content.

Environment Variables

Variable Required Purpose
CLOUDFRONT_SECRET_HEADER Yes Expected X-MCP-Token value
ENVIRONMENT No local skips mandatory edge-token presence
DATABASE_RDS_PROXY_ENDPOINT or DATABASE_HOST Yes outside local PostgreSQL connection
DATABASE_PORT Deployment-specific PostgreSQL port
DATABASE_NAME Yes PostgreSQL database
DATABASE_USER Yes PostgreSQL user
DATABASE_PASSWORD Yes PostgreSQL password
DATABASE_CONNECTION_LIMIT No Pool limit
BACKEND_INTERNAL_URL Yes Backend internal API base URL
BACKEND_INTERNAL_API_KEY Yes X-API-Key sent to backend
BACKEND_INTERNAL_TIMEOUT_MS No Positive timeout, default 10000, max 120000

MCP v2 does not need AWS, SQS, S3, DocumentDB, AI provider, Figma, or webhook credentials.


Migration Checklist

  • [x] Use PostgreSQL API-key authentication and require a positive project scope.
  • [x] Delegate all six domain tools to backend internal APIs.
  • [x] Keep SQS, S3, DocumentDB, provider, Figma, and webhook access out of MCP v2.
  • [x] Require backend and worker code-index readiness checks before matching.
  • [x] Use flat request payloads and immutable request-scoped artifacts.
  • [x] Return component and variation evidence through backend-normalized results.