コンテンツにスキップ

MCP v2 - I/O 定義

このページは guinness-backend/apps/mcp-v2 の公式 I/O コントラクトである。headers、tool schema、PostgreSQL authentication、backend internal API delegation、backend producer payload、AI-v2 read payload、error shape を変更する場合は、このページと テストケース設計 を更新する。


Transport と認証

POST /mcp HTTP/1.1
Host: <mcp-v2-domain>
Content-Type: application/json
Accept: application/json, text/event-stream
X-MCP-Token: <cloudfront-secret-header-value>
MCP-API-Key: guinness_<prefix>_<secret>

MCP-API-Key を送れない client のために Authorization: Bearer guinness_<prefix>_<secret> も受け付ける。

ヘッダー 必須 備考
X-MCP-Token local 以外は yes CLOUDFRONT_SECRET_HEADER と定数時間比較
MCP-API-Key or Authorization yes guinness_<prefix>_<secret> key を PostgreSQL mcp_api_keys で検証
Content-Type POST では yes application/json
Accept recommended streamable HTTP 互換のため text/event-stream を含める

API key format: guinness_([a-zA-Z0-9_-]+)_([a-zA-Z0-9]+)。

PostgreSQL lookup:

フィールド 用途
key_prefix 抽出した prefix による lookup
key_hash, salt scrypt verification
project_id, user_id, permission authorization scope
revoked_at, expires_at, deleted_at validity checks
last_used_at async non-blocking update

リクエストフロー

sequenceDiagram
    participant Client as MCP client
    participant MCP as apps/mcp-v2
    participant AuthDB as PostgreSQL mcp_api_keys
    participant Backend as apps/app internal API
    participant AI as guinness-ai-v2 read API
    participant Worker as guinness-ai-v2 des2code
    participant S3 as S3

    Client->>MCP: POST /mcp tools/call
    MCP->>AuthDB: key_prefix lookup と scrypt hash verify
    MCP->>Backend: X-MCP-Project-ID 付きで /internal/* を呼び出す
    alt trigger-des2code
        Backend->>Worker: SQS des2code message
        Worker->>S3: result artifact を保存
        Worker->>Backend: POST /v1/webhooks/ai-status
    else design/code source read
        Backend->>AI: X-AI-Service-Token read request
    else get-des2code
        Backend->>Backend: latest PostgreSQL result を読む
    end
    Backend-->>MCP: JSON result
    MCP-->>Client: MCP content and structuredContent

MCP v2 は stateless である。request ごとに新しい McpServer と streamable HTTP transport を作る。


JSON-RPC リクエスト

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "trigger-des2code",
    "arguments": {
      "design_id": "42_hDDA9BNori9OTXSClduXqR_40002029:37033",
      "project_id": 42,
      "organization_id": 1
    }
  }
}

Tool 入力

trigger-des2code

backend internal API 経由で des2code job を queue する。

フィールド 型 必須 検証
design_id string yes ^[a-zA-Z0-9_:-]+$, length 1-255
project_id integer yes > 0
organization_id integer yes > 0

get-des2code

backend internal API から design の最新 des2code summary を読む。

フィールド 型 必須 検証
design_id string yes ^[a-zA-Z0-9_:-]+$, length 1-255

list-designs / list-code

project の design/code source の compact metadata を一覧する。

フィールド 型 必須 検証
project_id integer yes > 0
organization_id integer no 指定時 > 0
limit integer no default 20, max 100
offset integer no default 0, >= 0

get-design-detail

vector embedding を除いた design source を読む。

フィールド 型 必須 検証
design_id string yes ^[a-zA-Z0-9_:-]+$, length 1-255

get-code-detail

vector embedding を除いた code source を読む。

フィールド 型 必須 検証
code_id string yes backend code UUID、length 1-255

処理コントラクト

  1. streamable HTTP JSON-RPC request を受信する。
  2. local development 以外では X-MCP-Token を検証する。
  3. MCP-API-Key または Authorization から API key を parse する。
  4. PostgreSQL mcp_api_keys を key_prefix と deleted_at IS NULL で読む。
  5. scrypt (N=16384, r=8, p=1, keylen=64) で full API key を検証する。
  6. revoked, expired, soft-deleted key を拒否する。
  7. Zod で tool arguments を検証する。
  8. backend internal API I/O 前に authenticated project/user scope を強制する。
  9. backend internal API 経由で tool を実行する:
  10. trigger-des2code: POST /internal/des2code。backend が PostgreSQL の design/project/org scope を検証し、SQS message を送る。
  11. get-des2code: GET /internal/des2code/{design_id}。backend が PostgreSQL-backed latest result を返す。
  12. list-designs: GET /internal/designs。backend が scope を検証し、AI-v2 design source metadata を proxy する。
  13. list-code: GET /internal/code。backend が scope を検証し、AI-v2 code source metadata を proxy する。
  14. get-design-detail: GET /internal/designs/{design_id}。backend が scope を検証し、AI-v2 design detail を proxy する。
  15. get-code-detail: GET /internal/code/{code_id}。backend が scope を検証し、AI-v2 code detail を proxy する。
  16. last_used_at を非同期更新する。
  17. MCP content と structuredContent を返す。

MCP から Backend Internal API

MCP v2 は auth 以外のすべての tool operation で BACKEND_INTERNAL_URL を呼び出す。

MCP tool Backend internal request Body/query
trigger-des2code POST /internal/des2code design_id, project_id, organization_id を含む JSON body
get-des2code GET /internal/des2code/{design_id} path design_id
list-designs GET /internal/designs project_id, optional organization_id, limit, offset
list-code GET /internal/code project_id, optional organization_id, limit, offset
get-design-detail GET /internal/designs/{design_id} path design_id
get-code-detail GET /internal/code/{code_id} path code_id

Backend に送る 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 が未設定の場合、X-API-Key は省略する。API key が project scope を持たない場合、X-MCP-Project-ID は省略する。

Backend internal API は raw JSON payload または { "ok": true, "data": ... } envelope を返してよい。MCP v2 は envelope を unwrap し、non-2xx response を MCP isError: true に map する。


Backend が生成する payload

これらの payload は backend REST/internal API が produce し、guinness-ai-v2 が consume する。MCP v2 は backend internal API 経由で、結果として保存された backend state と AI-v2 source read に依存する。Des2Code result は DocumentDB に書かず、timestamp 付き S3 artifact として保存し、artifact metadata とともに backend webhook 経由で PostgreSQL に保存する。

design-import

{
  "organization_id": 1,
  "project_id": 42,
  "img_url": "s3://bucket/designs/42_hDDA9BNori9OTXSClduXqR_40002029:37033.png",
  "node_id": "40002029:37033",
  "file_id": "hDDA9BNori9OTXSClduXqR",
  "design_id": "42_hDDA9BNori9OTXSClduXqR_40002029:37033",
  "design_name": "Landing Page",
  "json_schema_url": "s3://bucket/figma_json_schema/42_hDDA9BNori9OTXSClduXqR_40002029:37033.json"
}

figma_url は design-import worker payload に含めない。backend は user-facing Figma URL を enqueue 前に parse し、scope ID、asset URL、file_id、node_id、composite design_id のみを送る。

code-import

{
  "code_id": "0192a3b4-c5d6-4e8f-9a0b-1c2d3e4f5a6b",
  "organization_id": 1,
  "project_id": 42,
  "name": "Button Primary",
  "type": 1,
  "based_on": 0,
  "source_code": "export function ButtonPrimary() { ... }",
  "css_code": ".buttonPrimary { ... }",
  "img_url": "s3://bucket/code/0192a3b4-c5d6-4e8f-9a0b-1c2d3e4f5a6b.png"
}

code_id は backend PostgreSQL code identity を mirror し、DocumentDB code._id になる。

des2code

Backend はこの body を des2code SQS queue に送る。AWS は guinness-ai-v2/apps/des2code を invoke する前に通常の SQS event envelope で wrap する。

{
  "design_id": "42_hDDA9BNori9OTXSClduXqR_40002029:37033",
  "project_id": 42,
  "organization_id": 1
}
フィールド 型 備考
design_id string backend design ID。DocumentDB design._id として mirror する
project_id integer PostgreSQL project ID と AI search scope
organization_id integer tenant scope

custom_prompt は MCP v2 目標 payload に含めない。Des2Code は ranked code results を返し、source code は生成しない。


Backend から AI-v2 Read API

Design/code source tools は backend internal API を consume する。その後 backend が guinness-ai-v2 の service-token protected internal API を呼び出す。

Backend operation AI-v2 target read レスポンスデータ
list design sources GET /internal/designs?project_id=...&organization_id=...&limit=...&offset=... compact design metadata
list code sources GET /internal/code?project_id=...&organization_id=...&limit=...&offset=... compact code metadata
get design detail GET /internal/designs/{design_id} embedding なしの design source
get code detail GET /internal/code/{code_id} embedding なしの code source

Backend-to-AI-v2 call に含める:

X-AI-Service-Token: <shared-secret>

成功 envelope:

{
  "ok": true,
  "data": {},
  "error": null
}

エラー envelope:

{
  "ok": false,
  "data": null,
  "error": {
    "code": "NOT_FOUND",
    "message": "Design not found"
  }
}

MCP 出力

trigger-des2code 成功

{
  "content": [
    {
      "type": "text",
      "text": "Successfully triggered des2code matching for design ID: 42_hDDA9BNori9OTXSClduXqR_40002029:37033"
    }
  ],
  "structuredContent": {
    "success": true,
    "design_id": "42_hDDA9BNori9OTXSClduXqR_40002029:37033",
    "project_id": 42,
    "organization_id": 1,
    "timestamp": "2026-06-28T00:00:00.000Z"
  }
}

get-des2code 成功

{
  "structuredContent": {
    "design_id": "42_hDDA9BNori9OTXSClduXqR_40002029:37033",
    "status": "success",
    "matched_code_count": 1,
    "matched_codes": [
      {
        "code_id": "0192a3b4-c5d6-4e8f-9a0b-1c2d3e4f5a6b",
        "name": "Button Primary",
        "semantic_value": ["button", "primary", "cta"],
        "similarity": 0.92,
        "visual_similarity": 0.95,
        "semantic_similarity": 0.89
      }
    ],
    "artifact": {
      "bucket": "dev-guinness-backend",
      "key": "1/42/des2code/42_hDDA9BNori9OTXSClduXqR_40002029%3A37033-20260628T000000000000Z-result.json",
      "content_type": "application/json",
      "expires_at": "2026-07-28T00:00:00.000Z"
    },
    "error": null,
    "processed_at": 1782604800000
  }
}

list-designs / list-code 成功

{
  "structuredContent": {
    "project_id": 42,
    "organization_id": 1,
    "total_count": 2,
    "returned_count": 2,
    "limit": 20,
    "offset": 0,
    "items": [
      {
        "_id": "42_hDDA9BNori9OTXSClduXqR_40002029:37033",
        "name": "Landing Page",
        "project_id": 42,
        "organization_id": 1,
        "file_id": "hDDA9BNori9OTXSClduXqR",
        "page_id": "page",
        "node_id": "40002029:37033",
        "component_id": null
      }
    ]
  }
}

Detail 成功

get-design-detail は { "design": { ... } } を返す。get-code-detail は { "code": { ... } } を返す。Vector embedding fields は AI-v2 / backend internal read path で省略する。

Error response

{
  "content": [
    {
      "type": "text",
      "text": "Failed to retrieve des2code result: Des2Code result not found for this design"
    }
  ],
  "structuredContent": {
    "error": "Des2Code result not found for this design",
    "timestamp": "2026-06-28T00:00:00.000Z"
  },
  "isError": true
}
シナリオ 結果
missing/invalid X-MCP-Token local 以外では HTTP 401
malformed API key HTTP 401
unknown/revoked/expired/deleted API key HTTP 401
project/user scope mismatch MCP isError: true。backend internal API は呼び出さない
invalid tool arguments field-level validation text 付きの MCP isError: true
backend internal API が scope を拒否 mapped validation message 付きの MCP isError: true
backend SQS dispatch failure backend internal API が failure を返し、MCP は isError: true に map する
backend result API returns not found mapped not-found message 付きの MCP isError: true
backend internal API unreachable service-unavailable text 付きの MCP isError: true
backend downstream AI-v2 read returns ok: false backend が mapped failure を返し、MCP は isError: true に map する

冪等性と整合性

  • MCP v2 は request ごとに stateless である。
  • SQS delivery は at least once である。成功した worker attempt ごとに timestamp 付き S3 artifact を書き、backend webhook persistence が design_id 単位の latest PostgreSQL-backed result/artifact reference を上書きする。
  • 同じ design の再 trigger は許可し、最新の backend des2code result と artifact reference を置き換える。
  • Read tools は冪等である。
  • match が空の場合も matched_code_count = 0 の成功 result として扱う。