Notes MCP
MCP Eval デモ
評価を使って、LLM エージェントが MCP サーバーを実際に効果的に使えるかどうかを検証する方法の実例です。サーバーのコードが正しいかどうかだけを確認するのではありません。
ユニットテストは「delete_note はノートを削除するか?」に答えます。しかし、MCP サーバーが実践で役立つかどうかを左右する以下の問いには答えられません。
ユーザーが ID ではなく言葉でノートを説明したとき、エージェントは正しいノートを見つけられるか?
一覧のプレビューが途中で切れていることに気づくか、それともノートの半分だけをもとに回答するか?
update_noteが上書きすると理解しているか、それとも「買い物リストに行を追加して」と頼まれてユーザーの内容を黙って破壊してしまうか?エラーメッセージから回復できるか、それとも諦めてしまうか?
これらはツールサーフェス——名前、説明、スキーマ、結果の形、エラーテキスト——の性質であり、確認する唯一の方法は、実際のエージェントをサーバーに対して実行し、その行動を採点することです。それがこのリポジトリの目的です。
ステータス
MCP サーバー、そのインフラストラクチャ、そして eval ハーネスはすべて配置済みです。
Related MCP server: MCP Notepad Server
テスト対象のサーバー: Notes MCP
インメモリのノートブックです。状態はサーバープロセス内に保持され、終了時に破棄されるため、各 eval 実行は同じ既知のコーパスから開始されます(seed.py を参照)。
ツール | 動作のヒント | 機能 |
| 書き込み | ノートを作成します。タイトルは大文字小文字を区別せず一意である必要があります。 |
| 読み取り専用 | id 指定で 1 つのノートの完全な内容を返します。 |
| 読み取り専用 | ノートを更新が新しい順に、省略されたプレビューとして一覧表示します。任意の部分文字列 |
| 破壊的 | ノートのタイトルや内容を上書きします。 |
| 破壊的操作 | ノートを完全に削除します。 |
eval が検出できるようにするために意図された設計上の決定がいくつかあります。
ID であり、タイトルではない。 すべての変更系ツールは
note_idを受け取るため、「私の買い物リスト」を変更するように依頼されたエージェントは、まず ID を調べる必要があります。ここでエージェントは推測をすることがよくあります。切り詰められたプレビュー。
list_notesは各ノートの最初の 120 文字のみを返し、content_truncatedとcontent_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バージョンについて: サーバーは、mcpSDK に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 は、このエージェントを Case の Dataset で実行します。各 Case は、このファイルの先頭にある 4 つの動作のうちの 1 つをターゲットにしています。
Case | チェック内容 |
| 「私の買い物リストのノートを削除して」という要求されたとき、エージェントは |
| 答えが |
| 「私の買い物リストにクラッカーを追加して」は、最初に完全なノートを読む必要があります。 |
| 既に存在するタイトルのノートを作成する場合、新しい内容を黙って失ったり、重複が作成されたと主張してはなりません。 |
| 存在しないノートの削除要求は、推測した ID での |
| 正気を確認するためのハッピーパス。 |
ケースは 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 の組み込み保存される (ToolCorrectness、 Contains、 MaxToolCalls、 LLMJudge は複数の有効な回復がある 2 つのケース用) と evaluators.py の 2 つの小さなカスタム評価器を組み合わせます: ToolNotCalled
(ツールが一度も呼び出されていないことを低信憑 — 組み込みの否定チェックはありません)と ArgumentContains(ツールの引数に対する部分文字列チェックで、「古いコンテンツが残っている必要があります」ケース用。LLM の正確な表現は等価性やサブセット辞書のマッチングでは固定できないたため)。両方とも組み込みと同様に、Agent.instrument_all() とローカルの (send_to_logfire=False) 構成し、logfire.configure() がキャプセスするツールコールスパンを読み取ります。agent.py の configure_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が必要です。OpenAI —
NOTES_MCP_EVAL_MODEL=openai:gpt-5およびOPENAI_API_KEYが必要です。Amazon Bedrock —
NOTES_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 は、指定されたプロバイダープレフィックスの適切なクライアントと認証情報を決済します。
Maintenance
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
- -licenseNot gradedqualityNot gradedmaintenanceA 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.
- FlicenseBqualityDmaintenanceA 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
- FlicenseNot gradedqualityDmaintenanceProvides MCP tools to create and retrieve notes stored in memory.
- FlicenseAqualityDmaintenanceA 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.31
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.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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