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 |
処理コントラクト
- streamable HTTP JSON-RPC request を受信する。
- local development 以外では
X-MCP-Tokenを検証する。 MCP-API-KeyまたはAuthorizationから API key を parse する。- PostgreSQL
mcp_api_keysをkey_prefixとdeleted_at IS NULLで読む。 - scrypt (
N=16384,r=8,p=1,keylen=64) で full API key を検証する。 - revoked, expired, soft-deleted key を拒否する。
- Zod で tool arguments を検証する。
- backend internal API I/O 前に authenticated project/user scope を強制する。
- backend internal API 経由で tool を実行する:
trigger-des2code:POST /internal/des2code。backend が PostgreSQL の design/project/org scope を検証し、SQS message を送る。get-des2code:GET /internal/des2code/{design_id}。backend が PostgreSQL-backed latest result を返す。list-designs:GET /internal/designs。backend が scope を検証し、AI-v2 design source metadata を proxy する。list-code:GET /internal/code。backend が scope を検証し、AI-v2 code source metadata を proxy する。get-design-detail:GET /internal/designs/{design_id}。backend が scope を検証し、AI-v2 design detail を proxy する。get-code-detail:GET /internal/code/{code_id}。backend が scope を検証し、AI-v2 code detail を proxy する。last_used_atを非同期更新する。- 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 |
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 に含める:
成功 envelope:
エラー envelope:
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 として扱う。