mcpField
S
stitch-sdk-domain-design

stitch-sdk-domain-design

github.com/google-labs-code開発1.8k185 回インストール4 週間前に更新
リポジトリ

stitch-sdk-domain-design について

Stitch SDKパイプラインの第2段階向け設計スキルです。MCPツールスキーマを検証済み中間表現 `domain-map.json` に対応付ける方法を案内します。

主な機能

  1. 01ドメインクラス設計の指針
  2. 02MCPツールのバインディングと引数ルーティング
  3. 03レスポンス投影の設計
  4. 04キャッシュ対応メソッドのマッピング
  5. 05スキーマと投影の検証

活用シーン

  1. 01新しいMCPツールをドメインメソッドに対応付け
  2. 02引数の取得元と戻り値の形を決定
  3. 03キャッシュ対象のレスポンス経路を追加
  4. 04無効なdomain-map投影を診断

MCP 対応

`tools-manifest.json`に取得されたMCPツールスキーマを扱い、`domain-map.json`のドメインクラスやメソッドへの対応付けを定義します。

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/google-labs-code/stitch-sdk --skill stitch-sdk-domain-design

インストール後、Claude Code で/stitch-sdk-domain-designを入力して読み込まれたか確認します。

詳細

Stitch SDK ドメイン設計

このスキルでは、生成パイプラインの Stage 2 の実行方法、つまりツールスキーマを読み取り、コード生成を駆動する中間表現 domain-map.json を作成する方法を説明します。


入力

  1. tools-manifest.json — サーバーから取得した MCP ツールスキーマの生データ(outputSchema を含みます)
  2. ir-schema.ts — 有効な domain-map 構造を定義する Zod スキーマ(正式な契約です)
  3. 既存の domain-map.json — 現在の IR(新規作成ではなく拡張する場合)
  4. stitch-sdk-development スキル — パイプラインの背景を理解するために使用します

出力

classes と bindings の 2 つのセクションを含む、有効な domain-map.json。ir-schema.ts によって検証されます。

重要

出力はコード生成によって 2 回 検証されます。構造検証(Zod IR スキーマ)と意味検証(ツールマニフェストの outputSchema に対する projection ステップの検証)です。


クラスの設計

各クラスはドメインエンティティを表します。「ユーザーが操作する名詞は何か?」と考えてください。

{
  "Stitch": {
    "description": "Main entry point. Manages projects.",
    "constructorParams": [],
    "isRoot": true,
    "factories": [
      {
        "method": "project",
        "returns": "Project",
        "description": "Create a Project handle from an ID."
      }
    ]
  }
}
主な判断事項:
フィールド用途例
constructorParamsインスタンスに保存されるフィールド["projectId", "screenId"]
referenceアイデンティティマップのキー(.id は最後のキーのエイリアスです){ "keys": ["projectId", "screenId"] }
parentField親クラスから注入されるパラメーター"projectId"
factoriesローカルファクトリーメソッド(API 呼び出しなし)[{ "method": "project", "returns": "Project" }]
sideEffects手書きの拡張メソッド(宣言のみで、生成されません)[{ "method": "upload", "reason": "private_rest", "specPath": "src/spec/upload.ts" }]
extensionPath手書きメソッドを含むクラスを再エクスポートするモジュール"../../src/project-ext.js"

重要

IR スキーマは厳密です。 不明なキーは無視されず、検証エラーになります。以前のドキュメントに記載されていたフィールドごとのソースマッピングヘルパーは実装されたことがなく、存在しません。アイデンティティフィールドは、reference.keys、リソースの name の解析、および id のフォールバックから EntityManager によって設定されます。存在すると思っていたキーが検証で拒否された場合、その機能は存在しません。回避策を試さないでください。


バインディングの設計

各バインディングは、1 つの MCP ツールを 1 つのクラスメソッドに対応付けます。「このアクションを所有するのは誰か?」と考えてください。

引数のルーティング
型意味生成されるコード
selfthis.field から取得projectId: this.projectId
paramメソッドのパラメーターから取得prompt: prompt
computedtemplate の補間("template": "projects/{projectId}")name: \projects/${this.projectId}/screens/${screenId}``
selfArrayself フィールドを配列としてラップselectedScreenIds: [this.screenId]

省略可能なパラメーターには "optional": true を指定します。名前を変更するパラメーターには "rename": "newName" を指定します。 呼び出し元が値を省略した場合、"default": "VALUE"(optional: true が必要)が送信されます:deviceType: options?.deviceType ?? "DESKTOP"。

重要

メソッドシグネチャの形式(D12): 必須パラメーターは IR の順序で位置引数として渡します。すべての省略可能なパラメーターは、末尾の単一の options?: { ... } オブジェクトにまとめられます。generate(prompt, options?) とし、generate(prompt, deviceType?) とはしません。

レスポンスの射影

returns.projection 配列は、コード生成が API レスポンスをどのようにたどるかを指定します。各ステップは ProjectionStep です:

{ prop: string; index?: number; each?: boolean; find?: string; acknowledgeSingle?: boolean }
射影生成されるコード用途
[](空)raw直接返す(レスポンス全体)
[{ "prop": "projects" }]raw.projectsオブジェクト内の配列
[{ "prop": "outputComponents", "index": 0 }, { "prop": "design" }, { "prop": "screens", "index": 0 }]raw.outputComponents[0].design.screens[0]深くネストされた単一項目
[{ "prop": "outputComponents", "each": true }, { "prop": "design" }, { "prop": "screens", "each": true }]flatMap チェーン配列全体からすべての項目を収集
[{ "prop": "screenshot" }, { "prop": "downloadUrl" }]raw.screenshot.downloadUrlネストされたプロパティをたどる

判断基準: 単一の項目を抽出する場合は "index": 0 を使います。すべての項目を収集する場合(配列の結果)は "each": true を使います。同じステップで両方を使うことはできません。"find": "a.b" は配列を検索し、ネストされたパスが null でない最初の要素を取得します。

ヒント

射影内のすべての prop は、コード生成時にツールの outputSchema に照らして検証されます。プロパティ名を誤入力すると、使用可能なプロパティの一覧を示す診断メッセージとともにコード生成が失敗します。index/each/find を指定せずに配列の先へ進むこともコード生成エラーになります。生成されるチェーンは実行時に undefined になるためです。

警告

切り捨ての lint: 上限のない配列に index または find を使うと警告が出ます。ほかの要素はすべて暗黙に破棄されます(このパターンが原因で、project.generate() が複数の画面のうち1つだけを返したことがあります)。"each": true と "array": true の組み合わせを推奨します。結果が意味的に単一の場合に限り、そのステップに "acknowledgeSingle": true を指定して明示してください。

戻り値のクラスによるラップ

returns.class が設定されている場合、抽出されたデータはドメインクラスのコンストラクターでラップされます。

{
  "returns": {
    "class": "Screen",
    "projection": [{ "prop": "screens" }],
    "array": true
  }
}

子クラスで parentField が宣言されている場合、コード生成では自動的に parentField がデータに展開されます。

キャッシュを考慮したメソッド

構造化された projection を持つ cache フィールドを追加し、API を呼び出す前に this.data を確認します。

{
  "cache": {
    "projection": [{ "prop": "htmlCode" }, { "prop": "downloadUrl" }],
    "description": "Use cached HTML download URL from generation response if available"
  }
}

キャッシュされたプロパティがネストされたオブジェクト(downloadUrl を持つ File など)の場合、複数の projection ステップを使ってその内部をたどります。

生成されるコード:

if (this.data?.htmlCode?.downloadUrl) return this.data?.htmlCode?.downloadUrl;
// ... else call API

判断の指針

新しいツールをマッピングする際は、次の質問に答えてください。

  1. どのクラスにするか? ツールが必要とするフィールドを確認します。self から projectId が必要な場合は、Project または Screen に配置します。self から何も必要としない場合は、Stitch に配置します。

  2. メソッド名は何にするか? ツール名に含まれる動詞を簡潔にします。generate_screen_from_text → generate。edit_screens → edit。

  3. 引数は self と param のどちらから取得するか? 呼び出し元がすでにデータを持っている場合(自分自身のメソッドを呼び出している場合)は、self を使います。データを呼び出し元から渡す必要がある場合は、param を使います。

  4. 戻り値はどの深さにあるか? tools-manifest.json でツールの outputSchema を確認します。利用するデータまでたどるため、projection 配列をステップごとに構築します。

  5. キャッシュするか? データが以前のレスポンス(生成処理など)から取得できる場合は、projection のパスを含む cache フィールドを追加します。


検証

domain-map.json を編集した後:

bun scripts/generate-sdk.ts     # Validates IR + projections, then generates
npx tsc --noEmit                 # Type check
npx vitest run                   # Unit tests
bun scripts/e2e-test.ts          # E2E tests
bun scripts/validate-generated.ts  # Lock integrity

projection が無効な場合、次のように表示されます。

❌ Binding "Project.generate" projection step 2:
   property "screenz" not found in outputSchema.
   Available properties: screens, components, metadata

コメント