Skip to main content
Glama

MCP Eval デモ

評価を使って、LLM エージェントが MCP サーバーを実際に効果的に使えるかどうかを検証する方法の実例です。サーバーのコードが正しいかどうかだけを確認するのではありません。

ユニットテストは「delete_note はノートを削除するか?」に答えます。しかし、MCP サーバーが実践で役立つかどうかを左右する以下の問いには答えられません。

  • ユーザーが ID ではなく言葉でノートを説明したとき、エージェントは正しいノートを見つけられるか?

  • 一覧のプレビューが途中で切れていることに気づくか、それともノートの半分だけをもとに回答するか?

  • update_note が上書きすると理解しているか、それとも「買い物リストに行を追加して」と頼まれてユーザーの内容を黙って破壊してしまうか?

  • エラーメッセージから回復できるか、それとも諦めてしまうか?

これらはツールサーフェス——名前、説明、スキーマ、結果の形、エラーテキスト——の性質であり、確認する唯一の方法は、実際のエージェントをサーバーに対して実行し、その行動を採点することです。それがこのリポジトリの目的です。

ステータス

MCP サーバー、そのインフラストラクチャ、そして eval ハーネスはすべて配置済みです。

Related MCP server: MCP Notepad Server

テスト対象のサーバー: Notes MCP

インメモリのノートブックです。状態はサーバープロセス内に保持され、終了時に破棄されるため、各 eval 実行は同じ既知のコーパスから開始されます(seed.py を参照)。

ツール

動作のヒント

機能

create_note

書き込み

ノートを作成します。タイトルは大文字小文字を区別せず一意である必要があります。

get_note

読み取り専用

id 指定で 1 つのノートの完全な内容を返します。

list_notes

読み取り専用

ノートを更新が新しい順に、省略されたプレビューとして一覧表示します。任意の部分文字列 query に対応します。

update_note

破壊的

ノートのタイトルや内容を上書きします。

delete_note

破壊的操作

ノートを完全に削除します。

eval が検出できるようにするために意図された設計上の決定がいくつかあります。

  • ID であり、タイトルではない。 すべての変更系ツールは note_id を受け取るため、「私の買い物リスト」を変更するように依頼されたエージェントは、まず ID を調べる必要があります。ここでエージェントは推測をすることがよくあります。

  • 切り詰められたプレビュー。 list_notes は各ノートの最初の 120 文字のみを返し、content_truncatedcontent_length でフラグを立てます。一覧からそのまま内容の質問に答えるエージェントは間違えます。優れたエージェントは get_note を呼び出します。

  • 追加ではなく置き換え。 update_note は上書きします。したがって、「私の買い物リストに卵を追加して」は読み取り、変更、書き込みの操作であり、読み取りをスキップするエージェントはデータを破壊します。

  • 教えるエラー値。 すべての失敗は、問題の値を示し、それを解決するツールを指し示すため、エージェントは行き詰まるのではなく、前に進む道筋を得られます。

構成

src/notes_mcp/
  models.py    Pydantic models — also the tool input/output schemas the agent sees
  store.py     In-memory storage and its error types
  seed.py      Fixed corpus: stable ids and timestamps, so evals are reproducible
  server.py    MCP tool definitions, descriptions, and annotations
  cli.py       `notes-mcp` entry point
evals/
  agent.py       Builds the pydantic-ai agent under test + local trace capture
  task.py        One agent turn against a freshly seeded server — the thing evaluated
  evaluators.py  Custom pydantic-evals evaluators (tool-not-called, argument-contains)
  cases.yaml     The dataset itself: cases that probe specific MCP misuse patterns
  cases.py       Loads cases.yaml — registers the custom evaluators, picks the judge model
  __main__.py    `python -m evals` — runs the dataset against a live model
tests/
  test_store.py    Unit tests for the storage layer
  test_server.py   Protocol-level tests through a real MCP client session
scripts/
  lint.sh    Ruff + pyright + format check
  test.sh    Unit + protocol tests (fast, free)
  evals.sh   Agent-behaviour evals against a live model (slow, costs money)

ツールの説明は、インラインの docstring ではなく server.py 内のモジュールレベルの定数です。説明の文言は、失敗した eval に対応して調整する主な要素であり、これを 1 か所にまとめることで diff が読みやすくなります。

はじめに

uv と Python 3.12 が必要です(.python-version で固定)。

uv sync                       # create .venv and install everything
uv run scripts/test.sh        # unit + protocol tests
uv run scripts/lint.sh        # ruff check, pyright (strict), format check
uv run pre-commit install     # optional: run the same checks on commit

サーバーの実行

uv run notes-mcp                        # stdio, seeded with the sample notes
uv run notes-mcp --empty                # stdio, no notes
uv run notes-mcp --transport streamable-http

.mcp.json は、このプロジェクトの stdio サーバーを登録します。このディレクトリから起動された MCP ホストグレード——たとえば Claude Code——は、notes サーバーを自動的に認識し、手動で操作できます。

エージェントが表示するツールサーフェス(これらの eval が実際に検証しているもの)をエージェントを起動せずに確認するには、次のようにします。

uv run fastmcp list .mcp.json                   # names, signatures, descriptions
uv run fastmcp list .mcp.json --input-schema    # ...with the full JSON schemas
npx @modelcontextprotocol/inspector uv run notes-mcp   # MCP Inspector, for clicking around

mcp バージョンについて: サーバーは、mcp SDK に mcp.server.fastmcp として含まれていたコピーではなく、独立した FastMCP ライブラリ上に構築されています。mcp 2.0 でそのモジュールは削除されました。FastMCP が依存する mcp のバージョンを決定するため(3.x は mcp 1.x を解決します)、pyproject.toml には手書きの mcp バージョン指定はありません。eval ハーネスは反対側から同じライブラリに到達します:pydantic-ai の MCP クライアントは FastMCP の Client 上に構築されています。したがって、このリポジトリの両方の半分は、誰かがメンテナンスしなければならない固定ではなく、構造的にバージョンが一致します。FastMCP 4 は、両方を mcp 2.x に移行するステップであり、これが依存関係がその下に制限されている理由です。

テストアプローチ

scripts/test.sh によって実行される 2 つの pytest レイヤー:

  • test_store.py は、ストレージのセマンティクス(一意性、並べ替え順、制限、タイムスタンプ)をカバーします。高速で網羅的、プロトコルの関与はありません。

  • test_server.py は、インプロセスの MCP クライアントセッション(fastmcp.Client 経由、FastMCP のインメモリトランスポート上)でサーバーを駆動するため、エージェントが実際に受信する内容、つまりツールリスト、 JSON スキーマ、動作アノテーション、構造化結果、エラーテキストを検証します。プロトコルは実物です。サブプロセスとソケットだけが仮想的です。

非同期テストは、pytest-asyncio ではなく anyio の pytest プラグインを使用します。これは、MCP クライアントがセッションの存続期間中キャンセルスコープを開いたままにし、anyio がフィクスチャのセットアップとティアダウンを同じタスクで実行するためです。

2 番目のタイプのチェック、つまりエージェント動作 eval は、実在のモデルを呼び出し、コストがかかるため、pytest スイートには含まれません。専用のランナーとスクリプトがあります。以下で説明します。

eval ハーネス

evals/ は、最小限の pydantic-ai エージェント(汎用的な 1 行のシステムプロンプト、 数ショットの例なし、特殊化された指示なし)を構築し、その唯一のツールを pydantic_ai.mcp.MCPToolset 経由でインプロセスの Notes MCP サーバーに接続します(agent.py)。システムプロンプトは意図的に最小限です。これらの eval は、サーバー自身のツール名、説明、スキーマが正しい動作を導くのに十分かを確認するためのものであり、プロンプトエンジニアリングが弱いものを隠せるかどうかを確認するためではありません。

evals/src/ の下ではなく最上位レベルにあります。これは、このリポジトリの開発ツールであり、誰もインストールしない notes-mcp パッケージの一部ではありません。

pydantic_evals は、このエージェントを CaseDataset で実行します。各 Case は、このファイルの先頭にある 4 つの動作のうちの 1 つをターゲットにしています。

Case

チェック内容

delete_by_description_looks_up_the_id_first

「私の買い物リストのノートを削除して」という要求されたとき、エージェントは delete_note の前に list_notes を呼び出し、正しい ID を削除します。

answers_past_the_list_notes_preview_cutoff

答えが list_notes プレビューから切り詰められる質問は、エージェントが get_note を呼び出した場合のみ正しく回答されます。

appending_to_a_note_preserves_its_truncated_tail

「私の買い物リストにクラッカーを追加して」は、最初に完全なノートを読む必要があります。update_note 呼び出しは、プレビュー上限を超えてのみ存在するテキストを呼び許されるかをチェックされます。

title_conflict_on_create_is_not_silently_lost

既に存在するタイトルのノートを作成する場合、新しい内容を黙って失ったり、重複が作成されたと主張してはなりません。

deleting_a_nonexistent_note_does_not_fabricate_success

存在しないノートの削除要求は、推測した ID での delete_note 呼び出しや、成功を主張する応答をしてはなりません。

simple_lookup_answers_from_the_right_note

正気を確認するためのハッピーパス。

ケースは Python ではなく cases.yaml に存在します。ケースはデータであるため、ケースを追加したりルーブリックを言い換えたりしてもコードは変更されません。cases.py はローダーにすぎません。カスタム評価を Dataset.from_file に渡します(YAML ファイルはローダーが登録した評価器のみを指定できます)。また、判定モデルを設定します。YAML の yaml-language-server ヘッダーは cases_schema.json をファイルを指しているため、エディタは評価器名とその引数を補完して検証できます。カスタム評価器を追加または変更した後に再生成します:

uv run python -c "from evals.cases import write_json_schema; print(write_json_schema())"

評価器は、pydantic-evals の組み込み保存される (ToolCorrectnessContainsMaxToolCallsLLMJudge は複数の有効な回復がある 2 つのケース用) と evaluators.py の 2 つの小さなカスタム評価器を組み合わせます: ToolNotCalled (ツールが一度も呼び出されていないことを低信憑 — 組み込みの否定チェックはありません)と ArgumentContains(ツールの引数に対する部分文字列チェックで、「古いコンテンツが残っている必要があります」ケース用。LLM の正確な表現は等価性やサブセット辞書のマッチングでは固定できないたため)。両方とも組み込みと同様に、Agent.instrument_all() とローカルの (send_to_logfire=False) 構成し、logfire.configure() がキャプセスするツールコールスパンを読み取ります。agent.pyconfigure_instrumentation() を参照。

__main__.py はデータセットを実行し、完全なレポートを出力します。タスクエラー、クラッシュした評価器、または失敗したアサーションがあれば、非ゼロで終了します。次のコマンドで実行します:

uv run scripts/evals.sh

プロバイダーの設定

NOTES_MCP_EVAL_MODEL は、プロバイダーとモデルの両方を、pydantic-ai の provider:model 文字列として選択し、デフォルトは anthropic:claude-haiku-4-5-2025100 です。.env.example.env にコピーし、この 3 つのうちいずれかを使用しているセクションに入力してください。scripts/evals.sh.env を自動的に読み込みます(python-dotenv 経由なので、シェルで既に設定されている変数はオーバーライドされません)。また、.env は gitignore されます。

  • Anthropic API(デフォルト)— ANTHROPIC_API_KEY が必要です。

  • OpenAINOTES_MCP_EVAL_MODEL=openai:gpt-5 および OPENAI_API_KEY が必要です。

  • Amazon BedrockNOTES_MCP_EVAL_MODEL=bedrock:<bedrock-model-id>。boto3 の通常の認証情報チェーンを通じて認証されるため、標準の AWS SDK 変数以外に eval 固有の設定はありません。名前付きプロファイルを使用するには AWS_PROFILE を設定します(AWS_DEFAULT_REGION も同様、そのプロファイルがまだリージョンを設定していない場合。boto3 のリージョン解決がチェックしない AWS_REGION ではなく、AWS_DEFAULT_REGION である必要があります)。または、両方を未設定のままにして、デフォルトのプロファイル/リージョンを使用します。

プロバイダに応じてコードは分岐しません。eval_model() の文字列はエージェントと LLMJudge の両方に直接渡され、pydantic-ai の infer_model は、指定されたプロバイダープレフィックスの適切なクライアントと認証情報を決済します。

Install Server
F
license - not found
A
quality
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • -
    license
    Not graded
    quality
    Not graded
    maintenance
    A simple notes system that allows creating, storing, and accessing text notes through MCP resources and tools, with built-in prompt support for generating summaries of stored notes.
  • F
    license
    B
    quality
    D
    maintenance
    A learning-focused MCP server that demonstrates core MCP concepts through a simple notepad application, enabling users to create, update, delete, and search notes while exploring tools, resources, and prompts functionality.
    4
  • F
    license
    A
    quality
    D
    maintenance
    A minimal MCP server demonstrating tools, resources, and prompts for managing notes, with a simple notes app that supports adding, listing, deleting notes and summarizing them.
    3
    1

View all related MCP servers

Related MCP Connectors

  • Cross-session, cross-device memory for your agent: remember and recall notes. No key to start.

  • Shared, governed long-term memory for AI agents across tools and sessions via MCP and REST.

  • AI access to your aNotepad online notes: read, search, write, and organize via 22 tools.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/jasongilman/mcp-eval-demo'

If you have feedback or need assistance with the MCP directory API, please join our Discord server