mcpField
A
Ajisai

Ajisai

ローカル
masamoto1982.github.io科学・教育06 日前に更新

Ajisai について

Ajisaiは、厳密な有理数・代数計算と機械可読なWordコントラクトを必要とするエージェント向けのMCPサーバーです。実行制限、静的検査、コントラクトレジストリにより、計算と検証を区別します。

主な機能

  1. 01厳密な有理数・代数計算
  2. 02制限付きソース実行
  3. 03コントラクト宣言の検査
  4. 04Wordコントラクトの推論と照会
  5. 05構造化された診断結果

活用シーン

  1. 01厳密な数値計算
  2. 02実行前のWord宣言の検査
  3. 03推論済み・標準コントラクトの確認

MCP 対応

compute、check、infer_contracts、word_contractの4つのMCPツールを提供します。結果は共通スキーマを使い、ajisai://schema/resultリソースからも取得できます。

設定

ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。

mcp.json · 共通設定
{
"mcpServers": {
"masamoto1982-ajisai": {
"command": "npx",
"args": [
"-y",
"ajisai-mcp-server"
]
}
}
}
起動コマンドnpx -y ajisai-mcp-server

ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。

パッケージ
npmajisai-mcp-server0.9.0

ツール

5

掲載時のツール一覧 · 2 週間前に更新

パラメーター型必須説明
sourcestringはいAjisai のソーステキスト(ファイルパスは受け付けません)。実効上限は 65536 UTF-8 バイトです。そのため、非 ASCII テキストは maxLength が示す文字数より少ない文字数で上限に達します。構文は後置記法です。オペランドを先に書き、その後に Word を記述します — `1 2 ADD`、`[ 1 2 3 ] LENGTH`。文字列はシングルクォートで囲みます(`'hi'`。"hi" は不可)。MAP/FILTER/FOLD/SCAN に渡すブロックは、他と同じ Vector であり、`[ ]` で記述します — ブロック専用の括弧はありません(`[ 1 2 3 4 ] [ 2 GT ] FILTER`)。Word のオペランド形式は契約の一部です。不明な場合は word_contract で確認してください — 数値 1 つが自然に見えても、ベクトルを受け取るものがあります。例:`0 4 RANGE`、`[ [ 1 2 ] [ 3 4 ] ] ZIP`。

詳細

Ajisai MCP サーバー

Ajisai の MCP インターフェースにより、この言語は AI エージェント向けの、範囲が限定され、決定的で、診断可能な計算カーネルとして役立ちます。サーバーは薄いアダプターに徹します。言語のセマンティクスは Rust CLI が担い、語彙は生成されたアーティファクトが担います。

Ajisai が保証するのは、無条件の「丸め誤差なし」ではなく、サポート対象の数値領域における厳密性です。明示的な丸めなど、その領域外の関数には、それぞれ文書化されたセマンティクスが適用されます。

この README は、サーバーの機能と検証方法を記録するものです。以前 docs/dev/ に置かれていた準備状況トラッカーと引き継ぎメモは、終了基準を満たしたため廃止されました。 ホストごとのリソース上限は docs/dev/mcp-host-profiles.md で比較しています。

インストールと接続

要件:Node 20 以降。ほかには何も必要ありません。ビルド手順も cargo もネイティブバイナリも不要です。パッケージに WASM バックエンドが含まれています。

サーバーは npm で ajisai-mcp-server として公開され、公式 MCP Registry には io.github.masamoto1982/ajisai として登録されています。ほとんどの MCP クライアントでは、サーバーエントリーに JSON を使用します。Claude Desktop(claude_desktop_config.json)、Claude Code(.mcp.json)、Cursor(.cursor/mcp.json)はいずれも次の形式です。

{
  "mcpServers": {
    "ajisai": {
      "command": "npx",
      "args": ["-y", "ajisai-mcp-server"]
    }
  }
}

npx -y ajisai-mcp-server --doctor は、インストール済みのコピーで実際に計算できる場合、終了コード 0 を返します。

チェックアウトから実行する

クローンからは npm を使わずに同じサーバーを実行できます。これは、リポジトリ独自のテストや未リリースのエンジンにアクセスする方法です。WASM バックエンドは wasm/generated/ にコミットされているため、新しいクローンでもすぐに計算できます。

git clone https://github.com/masamoto1982/Ajisai.git
cd Ajisai/tools/mcp-server
npm install
node index.js --doctor     # exits 0 when this copy can actually compute

この場合、サーバーエントリーではチェックアウト内の index.js を指定します。

{
  "mcpServers": {
    "ajisai": {
      "command": "node",
      "args": ["/path/to/Ajisai/tools/mcp-server/index.js"]
    }
  }
}

設定はこれだけです。env ブロックは不要です。また、このファイルの以前のバージョンにあった唯一の動作例のように、AJISAI_BIN でネイティブバイナリを指定するのは、前提条件ではなく任意の上書き設定です。

  • AJISAI_BIN を指定すると、パッケージに含まれる WASM バックエンドの代わりにネイティブの ajisai バイナリが選択されます。これは、ネイティブバイナリをビルドする Docker イメージの設定方法です。
  • AJISAI_REPO は、ローカルでビルドしたバイナリを名前で指定せずに見つけるための、開発専用のフォールバックです。

どちらも指定しない場合、ネイティブバイナリが検出されるのは、このパッケージを Ajisai のチェックアウト(rust/Cargo.toml と並ぶ tools/mcp-server)から実行した場合のみです。その場合は、rust/target/release と rust/target/debug のうち、より新しくビルドされたほうが使われます。node_modules 内にインストールされたコピーは、その外部を検索しません。パッケージに含まれる WASM バックエンドを実行します。

公開されるパッケージには、サーバーが実行に必要とするものだけが含まれます。アダプター、2 つのバックエンド、パッケージに含まれるアセットと WASM モジュール、README.md、CHANGELOG.md、LICENSE です。評価ハーネス、そのコーパス、テストはリポジトリに残されます(含まれている場合、npm run test:pack は失敗します)。

どちらのバックエンドも同じ結果を返します(バックエンドと来歴を参照)。上書き設定はデプロイ方法に関するものであり、結果に関するものではありません。

インストールの確認

サーバーが正常なときは何も出力しないため、応答しなくなったサーバーと区別できません。同じ実行ファイルでサーバー自身を確認できます。

node index.js --version    # adapter, engine and specification versions, registry digest
node index.js --doctor     # Node, assets, backend and two real computations
node index.js --help

すべてのチェックに合格すると --doctor は終了コード 0 を返し、1 つでも失敗すると 1 を返すため、コンテナーの起動やサポート依頼の判定に利用できます。選択されたバックエンドを通じて 2 3 DIV 1 3 DIV ADD と 2 SQRT を計算します。起動してアセットを読み込めても、誤った回答を返すサーバーは依然として壊れています。それ以外であることを証明するには、実行してみるしかありません。引数なしで実行すると、プロセスは標準入力/標準出力で MCP を通信し、それ以外の内容は出力しません。

エージェント向けインターフェース

ツール目的
compute時間、ソース、出力、ステップの制限を設けてソースを実行します
check実行せずに #:contract 宣言を解析、解決し、保守的に検証します
infer_contracts実行せずにユーザー定義の Words のコントラクトを推論します
word_contract完全な正規 spec/words.json コントラクトレジストリを照会します

実行ツールが受け付けるのはソーステキストのみです。意図的にファイルパス入力を省くことで、AI ツール呼び出しが任意のローカルファイルを読み取るのを防ぎます。

check が回答するのはプログラムの 形式 に関することであり、実行に関することではありません。実行せずにトークン化、解析、名前解決を行い、#:contract 宣言を検証します(Word ごとに 1 行の #:contract DOUBLE inputs=1 outputs=1 field=closed。キーは CONTRACT が回答する inputs、outputs、field のみで、それ以外の語があるとディレクティブは不正になります)。compute は実行前に同じ宣言チェックを行い、本文に矛盾する宣言や不正な宣言がある場合は実行を停止します。どちらのツールも通常のエラーとして回答します。エラーは error.category: contractViolation で、検出内容を引用した message が含まれ、すべての検出内容は contractDecls.findings({ severity, message })に、Word ごとの判定は contractDecls.declarations に記録されます。また、compute はこれを outcome: error:contractViolation として示します。ディレクティブのないソースには contractDecls が含まれません。そのため、check が status: ok を返しても、それが示すのはプログラムの形式が正しく、名前が解決されるということだけです。プログラムの実行が成功すること、上限内に収まること、あるいは NIL ではなく値を生成することを示すものではありません。実行しなければ判断できないことは、ここでは何も判断しません。「実行まで進める」という意味で読み、実行によって何が起きるかは compute で確認してください。

3 つのソースツールは、1 つのプログラムに対して一貫した回答を返します。また、tool-consistency.test.js(npm run selftest の一部)は、すべてのゴールデンソースとコーパスソースを対象に、一貫性を検証します。

  • エラーの outcome と error.category は、同じカテゴリを示します。
  • 解析できないソースは、3 つすべてで malformedSource になります。infer_contracts も例外ではありません。
  • check が ok なら、プログラムの形式や名前が原因で実行が失敗することはありません。
  • infer_contracts が返す suggested の各行をソースの前に貼り付けると、check で検証できます。
  • check は実行より厳格です。呼び出されない Word の中であっても、定義されていない名前を拒否しますが、実行時にはそこまで到達しないことがあります。
3 つの結果を区別する
Ajisai の結果statusoutcome(compute)isError
値okvalue—
NIL(reason)不在理由を含む oknil:<reason>—
言語の ERRORmessage と error を含む errorerror:<category>—
ホスト の障害hostError—はい

outcome は spec/outcomes.json の ID を使用するため、最上位のスタックノードを確認せずに、理由付きの不在と値を区別できます。

4 つのツールはすべて同じエンベロープ(result.schema.json。ajisai://schema/result としても提供)で回答するため、呼び出し側が受け取るすべての結果を 1 つのスキーマで記述できます。整合性を保つための 2 つ目のコントラクトは必要ありません。

結果にかかるコスト

結果は毎回、2 つの形式で返されます。呼び出し元が条件分岐に使う structuredContent と、テキストコンテンツブロックにシリアライズされた形式です。MCP では、出力スキーマを持つツールにもシリアライズ済み JSON を同じ形式で返すよう求められるためです。テキストのみのクライアントには、結果を得るほかの手段がありません。このミラーは維持します。これを文章による要約に置き換えるのは、実際に情報を失う唯一の圧縮方法です。また、セルフテストでは、テキストのみのクライアントがテキストだけから値、理由を伴う NIL、言語エラー、ホスト障害を区別できることを確認しています。

削除したのは、すべての結果で一定だった情報です。1 2 ADD の応答は 3,732 バイトで、そのうち答えである stack と stackDisplay は 85 バイトでした。残りは、毎回の結果に含まれていた 12 件の上限テーブル(mcp.limits)と、ホストが検証していない実行レシートおよび観測ダイジェストでした。1 回のターンで 5 回呼び出すと、その情報だけで 5,000 トークンを消費していました。現在は次のようになっています。

  • mcp.limitProfile がプロファイル(mcp-local-stdio)を示します。上限値は ajisai://limits リソースで確認でき、一度読み取れば十分です。上限に達した場合は、error.resource に該当する上限の名前が、message にその値が含まれます。ホスト障害が上限に関するものであれば、error.limit に上限の名前が含まれるため、結果にテーブルがなくても対応できます。
  • 実行で各上限に対して消費した量を示す resourceUsage は送信されます。エンジンは最適化カウンターを一切報告しません。
  • エンジンはレシートも観測ダイジェストも送信しません(エンベロープスキーマ 5)。
  • 値を持たないオプションフィールドは null ではなく省略されます。通常の成功時の message と error、何も宣言しないソースでの contractDecls がこれに該当します。null かどうかではなく、フィールドの有無を確認してください。

送信時の 1 2 ADD は約 1 KB で、変わらず残っているのはその出所情報です。npm run eval:performance は 7 つのベンチマークケースについて、応答全体とテキストブロック単体のサイズを測定し、コミット済みの medianResponseBytesBudget を超えると失敗するため、これらの情報が気づかれないまま戻ることはありません。応答が実際に小さくなった場合は予算を引き下げます。リグレッションを通すために引き上げることはありません。

ホスト障害は機械可読です。error.code は安定した識別子(invalidRequest、unknownTool、sourceTooLarge、backendUnavailable、capacityExhausted、timeout、responseTooLarge、malformedBackendResponse、backendFailure、registryUnavailable)です。error.retryable は再試行が有効かどうかを示し、障害が上限に関するものであれば、error.limit が該当する上限の名前を示します。error.message はモデル向けに記述されており、ホストのパス、環境変数名、プロセス起動時の診断情報は含みません。そうした詳細は、運用担当者が確認するサーバーの標準エラー出力に送られます。

concurrentExecutions の上限に達すると、capacityExhausted を返す前に、呼び出し元を最大 1 秒間キューに入れます。そのため、通常の集中アクセスは、呼び出し元がリトライループを実装しなくても、バックプレッシャーとして処理されます。

代数的な値を読む

2 SQRT は、値、その表示形式、近似値を返します。スタックノードでは、次のように読みます。

フィールド内容
stackDisplay値を 1 つのトークンで表したものです。"sqrt(2)"、"2/1*sqrt(2)"、"sqrt(2)-sqrt(3)" のように、正確な値が省略されずに表示されます。
semantics.exactTerms値そのものです。Σ (numerator/denominator)·√radicand の形式で、任意精度整数は文字列として表されます。

表示形式は、隣にある項をそのまま正確に表します。計算には exactTerms を使用してください。表示形式は解析するためではなく、人が読むためのものです。

誤解を招くのは、ノード自身の value です。これは semantics.approximate のフラグが付いた有理数による近似値であり、正確な値のように見えますが、正確ではありません。

表示形式では標準正規形を使うため、等しい値は同じ形式で表されます。8 SQRT と 2 SQRT 2 SQRT ADD はどちらも 2/1*sqrt(2) となり、EQ で同じ数であると判定されます。ここで等値性を判定するのは比較であり、文字列比較ではありません。文字列は表示用のテキストであって、値ではないためです。有理数または有理数のベクトルでは exactTerms は表示されません。その場合、stackDisplay が値全体を表します。

エラー

言語エラーは、1 行のテキストである message と、1 つのオブジェクト error: { category, resource?, word?, line?, column? } です。category は spec/outcomes.json のエラーカテゴリーで、outcome と同じ ID であり、 分岐に使う値です。word は失敗の原因とされる Word、line と column はその記述位置、resource は resourceLimitExceeded の場合に、制限に達した ajisai://limits の項目です。不明な Word は category: unknownWord となり、word には記述された名前が入ります。 word_contract は、その名前に最も近い既知の Word を suggestions で返します。

responseBytes は、構造化された結果、そのシリアライズ済みテキストのミラー、および来歴を合わせた、送信時点のレスポンスサイズに上限を設けます。成功した結果は拒否されるのではなく、エンジンによってこの上限内に収まるよう処理されます。エージェントプロファイルでは、スタックは 440 KiB まで丸ごと送信されます(小さな整数 5,000 個のベクター)。それを超える場合は、収まりきらないスロットが、失敗したスタックと同じ方法で省略されます。すなわち、value: null、elements と approxBytes を含む elided レコード、stackDisplay 内の対応する <elided …> マーカー、およびトップレベルの stackElided.reason: valueStackBudget が設定されます。その横にある値はすべて丸ごと届きます。0 7000 RANGE 1 2 ADD は、以前は responseTooLarge となり、呼び出し元には答えが大きすぎること以外は何も伝わりませんでした。現在は 3/1 と、7,001 個の要素を持つベクターがその下に残されたことを示すレコードを返し、それによって呼び出し元はそのベクターを破棄できます。responseTooLarge は、それ以上省略しても上限内に収まらない結果に対する最終的な制限として、引き続き残ります。

リソース制限による失敗では、上限に達した ajisai://limits の項目そのものが error.resource に示され、message には制限と、何がそれを超えたかが記載されます(materializedElements of 100002 exceeds the limit of 100000)。

上限に達した場合、呼び出しが失敗扱いにならずに拒否されることはありません。結果が収まらない、形式として正しい生成系の Word は、materializedElements に対する 0 100001 RANGE、上限、または nestingDepth を超える FILL や RESHAPE の形状、同じ深さのテキストに対する JSON-DECODE、numericLiteralDigits を超える字句に対する NUM、bigintBits を超える POW のいずれも、status: error と resourceLimitExceeded になります。error.resource には上限が、message にはその値と要求されたサイズが示され、いずれも何かを構築する前に測定されます。Word のオペランドはスタックに残ります。上限はプログラムのものではなくホストのものです。そのため、上限を超えたときに値が返されることはありません。NIL は他の値と同じように後続処理へ進み、異なるホスト上で同じプログラムが異なる値を使って ok を返せることになるためです(engine 1.0.0-beta.1 までは NIL(spaceExhausted) として、そのように動作していました)。ホスト間の違いは、異なる答えではなく、上限を明示する失敗として必ず示されます。

バックエンドと来歴

すべての実行ツールは、ホストに依存しない同じ Rust エージェント境界 (rust/src/agent)を、交換可能な 2 つのバックエンド (tools/mcp-server/backend/)のいずれかを通じて呼び出します。1 つは呼び出しごとにネイティブの ajisai サブプロセスを起動する方式、もう 1 つは同じエージェントコードを WASM にコンパイルし、再利用される worker_threads Worker 内で呼び出しごとに新しい WebAssembly インスタンスとして実行する方式です。どちらも同一の結果エンベロープを返すことは、backend/parity-test.js でケースごとに検証されています。そのため、Node がコマンド固有の結果を再解釈することはありません。

バックエンドは起動時に一度だけ選択され、mcp.backend.kind (nativeCli または wasmWorker)に記録されます。リクエストごとに選択する方式では、セッションの途中で cargo build が完了すると、後続の呼び出しが異なる実行経路に何も知らせず移行し、レスポンスにもその旨が示されませんでした。パリティによって 2 つの回答が等しくなり、来歴によって、等しくない回答を調査できるようになります。

すべての結果には、mcp.serverVersion、mcp.engineVersion、 mcp.assetDigest と、適用されたプロファイル名である mcp.limitProfile も含まれます。2 つのバージョンは、別々にリリースされるコンポーネントを示します。serverVersion はこの Node アダプターのバージョンで、engineVersion はアダプターが処理を委ねる Ajisai 言語のバージョンです。以前は、保存された結果に 2 つ目のバージョンしか記録されていなかったため、アーカイブされたエンベロープにフィールドがない場合、そのフィールドをアダプターのバージョンが送信していなかったのか、単に欠落したのかを区別できませんでした。

すべてのエンジン結果の最上位にある specificationVersion は、エンジンが実装する言語仕様のバージョンを示します。エンジンはベータ版です。1.0.0 までは、このバージョンが変わるとプログラムの回答も変わる可能性があり、Ajisai リポジトリの spec/CHANGELOG.md には、そのような変更がそれぞれ、プログラムと変更前後の回答とともに記載されています。保存する結果には、このフィールドも含めてください。

パッケージに含まれるレジストリは、起動時に記録済みのダイジェストと照合して検証されます。そのため、破損したアセットがある場合は、最初にそれに触れたリクエストで一般的な失敗として表面化するのではなく、サーバーの起動が停止します。

制限

プロファイルは ajisai://limits リソースで、すべての結果に mcp.limitProfile として名前が記録されます。すべてのエントリーには golden/limits.json に対応するエントリーがあり、2 つの集合が異なる場合はセルフテストが失敗します。上限を宣言するなら、それをどのように検証するかも示さなければなりません。5 つの上限は、セルフテストのたびに実際の境界テスト用ソースをライブサーバーで実行し、両方のバックエンドで結果を比較して固定されています。concurrentExecutions、wallTimeMs、responseBytes はアダプター独自の受け入れ制御と配信経路を通じて固定されます。また、numericWork、bigintBits、algebraicTerms は、宣言された値では wallTimeMs 以内に到達できないため、上限を注入して Rust 内で固定されています。golden/limits.json と docs/dev/mcp-host-profiles.md では、このことを明記しており、差異の発見を後回しにしていません。

Playground には別の、より緩いプロファイルが適用されます。0 100001 RANGE は Playground では成功しますが、ここでは拒否されます(resourceLimitExceeded。materializedElements を明示します)。また、Playground のステップ予算はここでの 120 倍なので、そこで 100,000 要素を走査するブロック反復も、ここでは拒否されます (executionSteps。代わりに何を書くべきかはクイックスタートで説明しています)。両方のホストで実行できるプログラムは、どちらでも同じ回答を返します。上限が回答を変えることはなく、回答を名前付きの失敗に変えるだけです。両方のホストは適用するプロファイルを公開します。Playground はスプラッシュ画面に両方のプロファイルを表示し、Playground バッジのツールチップには、このプロファイルの上限を自身の上限と並べて表示します。また、この違いは、それを示すゴールデンケースに明示的な hostDivergence ブロックとして記録されています。

リソース

ajisai://guide/quickstart、ajisai://vocabulary、ajisai://contracts、 ajisai://schema/result、ajisai://limits、ajisai://phrasebook。ajisai://contracts では すべての Word の完全なコントラクトを一度に読み取れます。ajisai://vocabulary は一覧のみで、 各名前とその kind、family、vocabularyTier が記載されています。 ajisai://words/{name} テンプレートでは、ツールを呼び出さずに word_contract と同じ完全な Word コントラクトを参照できます。Word 名は、 検索時もプログラム内と同様に大文字と小文字を区別しません(add は ADD として実行されます)。レジストリのダイジェストは、 縮約されたドキュメントマニフェストではなく、正規の仕様から計算されます。

ajisai://guide/quickstart は、sync-assets.js で結合された MCP の前書き(mcp-quickstart.md)と 生成されたライティングプロトコル(SKILL.md)で構成されています。

ajisai://phrasebook は、リポジトリの docs/phrasebook/phrasebook.ajisai です。 プログラムが繰り返し記述するフレーズ用の User Words で、それぞれに検証済みの #:contract、例、および内容の識別情報を示す #:digest 行があります。 compute、check、infer_contracts は、これらの名前を指定する任意の words 配列を受け取り、ソースの実行前に、呼び出し先のフレーズブック内の Word とともに定義します。結果の prelude には、 追加された各 Word とそのダイジェストが記載されるため、名前ではなく内容によって実行内容を検証できます。呼び出しごとに新しいソースが実行されることに変わりはなく、呼び出し間で状態は保持されません。AJISAI_PHRASEBOOK に、同じ形式の別ファイルのパスを設定すると、そのファイルが words と ajisai://phrasebook の代わりに使用されます。ファイルには Word ごとに DEF 行が 1 行あり、それぞれの後に #:digest 行が必要です。語彙創発実験では、この方法で各世代に継承された Word を渡します。 有効なパーセントエンコード文字列ではない名前で ajisai://words/{name} を読み取ろうとすると、無効なリクエストとして拒否されます。また、スキーマで宣言されていない引数を含むツール呼び出しは、その引数名を示す invalidRequest として拒否されます。additionalProperties: false はサーバーによって強制されており、単に仕様として示されているだけではありません。 以前のガイドは SKILL.md のみで、CLI の実行ループ(接続中のクライアントが実行できない ajisai run file --json コマンド)から始まり、どのツールを呼び出すべきかも説明していませんでした。そのため、先に読んだモデルは、インターフェースを知る前に言語を学ぶことになっていました。前書きでは、ツールの選択、結果に応じた分岐、代数的値に関する落とし穴を 1 画面で説明してから、後半へ引き継ぎます。前書き自体の例は、セルフテストで稼働中のバックエンドに対して実行されます。これは、ジェネレーターがその下のセクションに対して保証するのと同じものです。

4 つのツールすべてで、読み取り専用、非破壊、べき等の MCP アノテーションが宣言されています。

開発

cd tools/mcp-server
npm install
npm run selftest       # uses the packaged WASM backend unless AJISAI_BIN is set
npm run test:pack
npm run eval:validate
npm run eval:performance

パッケージ化された WASM バンドル(wasm/generated/)は、リポジトリのルートで npm run build:mcp-wasm を実行すると再生成されます。語彙、コントラクト、ガイド、バージョン、レジストリの出所情報は、バックエンドにかかわらず assets/ にパッケージ化されます。

リポジトリのルートで npm run test:mcp-backends を実行すると(ネイティブバイナリをビルドしてから backend/parity-test.js を実行)、すべてのゴールデンケースと宣言されているすべての制限値の境界を両方のバックエンドで実行し、結果が一致することを検証します。

サーバーの評価方法 — バイリンガルエージェントコーパス、トレースと修復のスコアラー、取得済みのモデルベースライン、パフォーマンスとレスポンスサイズの予算 — については、専用のドキュメント docs/dev/mcp-evaluation.md を参照してください。この README は、サーバーへの接続方法と、サーバーが返す内容を読むためのものです。

npm run test:pack は、許可リストに基づいた tarball を作成して空の一時プレフィックスにインストールし、インストールされたコピーを次の 4 通りでテストします。AJISAI_REPO も AJISAI_BIN も設定せずに createServer をインポートし、リポジトリもネイティブバイナリも利用できない状態で、パッケージに含まれる自己完結型の WASM バックエンドを使って計算することを確認します。すべてのドキュメントに記載されたクライアントのエントリポイントが起動する方法である、node_modules/.bin 経由で ajisai-mcp-server の bin を起動すること、インストール済みパッケージで --doctor を実行すること、最後に明示的な AJISAI_BIN を指定して同じ bin をもう一度起動し、mcp.backend.kind が nativeCli であることを検証します。

最後の 2 つは、意図的に別プロセスとして起動します。バックエンドはプロセスごとに一度だけ解決されるため、同一プロセス内で AJISAI_BIN を設定して 2 つ目のサーバーを構築しても、最初のシナリオで確定した WASM バックエンドが再利用されていました。そのため、ネイティブバイナリがないマシンでもネイティブの検証に合格していました。現在は実際にネイティブバイナリを使うため、npm run test:pack の実行にはビルド済みのバイナリが必要です。リポジトリのルートで npm run test:mcp-pack を実行すると、先にビルドされます。

ブラウザのプレイグラウンドはこのパッケージとは独立しており、引き続き利用できます。

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。