Skip to main content
Glama
Yunwcy

Portfolio MCP Server

by Yunwcy

Portfolio MCP Server

MCP(Model Context Protocol)サーバーで、Cheng-Yun Wuのポートフォリオ(プロジェクト、スキル、履歴書)をツールとして公開します。MCP互換のAIアシスタント(Claude Desktop、Claude.ai Connectors、MCP Inspectorなど)は、ウェブサイトをスクレイピングする代わりに、これらのツールを直接呼び出すことができます。

なぜこれを作ったか

MCPが実際にどのように動作するかを、読むだけでなく理解したいと思ったからです。そこで、自分のポートフォリオサイトのコンテンツを構造化されたツールに変換する小さなサーバーを構築しました。また、これまであまり触れてこなかったDockerと基本的なCI/CDパイプラインを学ぶための、意図的なきっかけでもあります。これらは、私が応募している求人情報で頻繁に登場するスキルです。

Related MCP server: Bijon Portfolio MCP Server

MCPとは(簡単に)

MCPは(Anthropicによる)オープンプロトコルで、AIアシスタントが外部の「ツール」(名前、説明、スキーマを持つ型付き関数)を呼び出して、トレーニングデータや貼り付けられたドキュメントだけに頼るのではなく、ライブ情報を取得したりアクションを実行したりできるようにします。サーバーは自身のツールを宣言し、MCP対応クライアントはそれらを発見して呼び出すことができます。このプロジェクトはそのようなサーバーの1つで、自身のポートフォリオデータに基づく4つのツールを宣言しています。

ツール

ツール

機能

list_projects()

すべてのポートフォリオ項目(リリース済みシステム、コンテスト参加作品、研究プロジェクト、出版論文、コースレポート。主要なケーススタディだけでなく)を、id、名前、タグライン、カテゴリ、年、1行の概要、そしてリスト内にリンク(ライブシステム、GitHub、レポート、デモ動画など)とともに表示します。

get_project_details(name)

1つの項目の完全なレコード。主要プロジェクトの場合:役割、技術スタック、問題、課題と解決策、成果、リンク。軽量な項目の場合:ファイルにある情報(最低でも説明とリンク)。マッチングは寛容でエイリアスに対応しています("lab handover" → ifit-lab-handover、"NTPU OPE Assistant" → 実際の論文システム)。

search_skills(keyword)

スキル分類全体のキーワード検索。関連性でランク付けされ、各結果はそのスキルを示すプロジェクトを表示します。

get_resume_summary(length)

"short" / "medium" / "long" の自己紹介と連絡先情報。

各ツールのdocstringは、AIアシスタントがいつ呼び出すかを判断するために実際に読み取るものです。詳細は src/portfolio_mcp/server.py を参照してください。

カバレッジ: data/projects.json には全31件のポートフォリオ項目が含まれています。7件の詳細なケーススタディ(リリース済みシステム、論文、NSTC研究プロジェクト、受賞論文)と、24件の軽量な項目(その他のコンテスト参加作品、コースレポート、会議論文)です。すべての項目に少なくとも1つのリンクが含まれています。コース段階のレポートや関連論文には、所属する詳細なケーススタディを指す related_project idが含まれており、アシスタントがレポートから完全なストーリーにドリルダウンできます。

アーキテクチャ

Claude Desktop / Claude.ai / MCP Inspector
              │  (stdio locally, or Streamable HTTP remotely)
              ▼
      MCPServer instance (server.py)
              │  registers 4 tools
              ▼
       tools.py  (pure, unit-tested logic)
              │
              ▼
   data_loader.py  →  data/*.json  (projects, skills, resume)
  • トランスポート: Streamable HTTP(stdioではありません)。ポイントは、リモートクライアント(例:Claude.aiのConnectors)がローカルで起動されたプロセスだけでなく、公開URL経由でこのサーバーにアクセスできることです。ローカルのClaude Desktop / MCP Inspectorテスト用にstdioもサポートしています。

  • データ層: data/ の下にある3つのフラットなJSONファイル。一度ロードされ、キャッシュされます(functools.lru_cache)。データベースはありません。データは小さく、公開されており、変更は稀です。

  • ツールロジックとMCP配線: 意図的に分離されています(tools.py vs. server.py)。これにより、MCPサーバーやトランスポートを実行せずにロジックを単体テストできます。

  • SDKに関する注意: 公式の mcp Python SDKは、v2.0.0で高レベルサーバーAPIを FastMCP から mcp.server.mcpserver.MCPServer に変更しました。このプロジェクトは mcp>=2.0.0 とその現在のAPIをターゲットにしています。from mcp.server.fastmcp import FastMCP を使用する古いMCPチュートリアルを見たことがある場合、それはv2.0.0以前のAPIであり、pip install mcp で現在入手できるものに対してインポートできません。

プロジェクト構造

portfolio-mcp-server/
├── data/                      # projects.json, skills.json, resume.json
├── src/portfolio_mcp/
│   ├── server.py              # MCPServer app: registers tools, stdio/HTTP entrypoints, /chat route
│   ├── tools.py                # MCP tool logic (testable, no MCP dependency)
│   ├── chat.py                  # /chat: Claude + Tool Runner over the same data, for the site's Q&A widget
│   └── data_loader.py          # cached JSON loading
├── tests/                      # pytest suite run in CI (tools, server security, chat, chat route)
├── Dockerfile                  # python:3.12-slim + uvicorn, Streamable HTTP
├── .github/workflows/ci.yml    # lint (ruff) + test (pytest) on every push
└── claude_desktop_config.json  # example config for local stdio testing

ローカルでの実行

# from the repo root
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"

オプションA — stdio、MCP Inspector使用

npx @modelcontextprotocol/inspector python -m portfolio_mcp.server

各ツールを直接呼び出し、リクエスト/レスポンスを検査できるローカルWeb UIが開きます。

オプションB — stdio、Claude Desktop使用

claude_desktop_config.json の mcpServers エントリを自身のClaude Desktop設定(設定 → 開発者 → 設定の編集)にマージし、パスを自分のマシン用に修正してからClaude Desktopを再起動し、「この人が手がけたプロジェクトは?」などと質問してください。

オプションC — Streamable HTTP、ローカル

TRANSPORT=http python -m portfolio_mcp.server
# equivalent — both serve the exact same ASGI app, /chat included:
uvicorn portfolio_mcp.server:app --host 0.0.0.0 --port 8000

テスト

pytest -v
ruff check .

Dockerでの実行

docker build -t portfolio-mcp-server .
docker run -p 8000:8000 portfolio-mcp-server

コンテナは常にStreamable HTTPを提供します(コンテナ化のポイントはこれです — ポータブルで公開可能なユニットであり、1台のマシンに縛られたstdioプロセスではありません)。

デプロイ(Render)

選択したデプロイ先: Render、無料枠。長時間実行されるコンテナ(実行時間制限のあるサーバーレス関数ではない)を実行します。これはStreamable HTTPの永続的な接続に必要であり、開始にクレジットカードは不要です。

  1. このリポジトリをGitHubにプッシュします。

  2. render.com で: New → Web Service → このリポジトリに接続。

  3. Renderが Dockerfile を自動検出し、コンテナとしてビルド/実行します。

  4. Free インスタンスタイプを選択 → https://<something>.onrender.com のURLが取得できます。

  5. 動作確認:

    npx @modelcontextprotocol/inspector https://<something>.onrender.com/mcp
  6. (オプション)RenderのGitHub自動デプロイを有効にすると、git push を main に実行するたびに自動的に再デプロイされます。以下のCIワークフローと組み合わせることで、完全なCI/CDストーリーが完成します。

無料枠の注意: Renderの無料Webサービスは、約15分間アイドル状態が続くとスリープし、次のリクエストで起動するのに30〜60秒かかります。ポートフォリオのデモには問題ありませんが、尋ねられた場合に意図的なコスト/レイテンシのトレードオフとして言及する価値があります。

ライブデプロイ: https://yun-portfolio-mcp.onrender.com/mcp — MCPクライアントをこのURLに接続してください(/mcp パスに注意。ベアドメインは404になります。これは想定内です — Streamable HTTPはその1つのパスのみを提供します)。npx @modelcontextprotocol/inspector https://yun-portfolio-mcp.onrender.com/mcp で自分で確認できます。

これをフォークする場合: server.py のHostヘッダー許可リストはデフォルトで yun-portfolio-mcp.onrender.com にハードコードされています(DNSリバインディング保護により、他のHostヘッダーは421で拒否されます)。MCP_ALLOWED_HOSTS 環境変数を自身のデプロイのホスト名に設定するか、ALLOWED_HOSTS を直接編集してください。

チャットエンドポイント(/chat)— ポートフォリオサイトのQ&Aウィジェット

同じRenderサービス上の2つ目の独立したドアで、yunwcy.github.io に埋め込まれたプレーンなチャットウィジェット用です。上記のMCPプロトコルサーフェスの一部ではありません。 ブラウザが {"message": "..."} を /chat に POST すると、サーバーはAnthropic Tool Runnerを使用して、Claudeに同じ4つのツールのどれを呼び出すかを決定させ(MCPハンドシェイクなしで tools.py を直接呼び出す)、{"reply": "..."} を返します。完全な実装については src/portfolio_mcp/chat.py を参照してください。

なぜこれに実際のバックエンドが必要で、GitHub Pagesだけではできないのか: 自然言語で応答するには、LLMが質問を見てどのツールを呼び出すかを決定する必要があり、それにはAnthropic APIキーが必要です。そして、キーは静的サイトのクライアントサイドJSに決して置くことができません。誰でもソースを表示してアカウントを使い潰せるからです。/chat はキーをサーバーサイド(Renderの環境変数。ブラウザには決して送信されません)に保持し、ブラウザが必要とするウィジェットのみをGitHub Pagesに配信します。

セットアップ(このエンドポイントが機能する前に必要):

  1. Anthropic Console からAPIキーを取得し、Renderの ANTHROPIC_API_KEY 環境変数として追加します(Renderダッシュボード → このサービス → Environment)。これがない場合、/chat はサーバーをクラッシュさせる代わりに 503 {"error": "not_configured"} を返します。

  2. CHAT_ALLOWED_ORIGINS(カンマ区切り)がCORSを制御します。デフォルトは https://yunwcy.github.io です。ウィジェットが別の場所にある場合は設定してください。

  3. ANTHROPIC_CHAT_MODEL(デフォルト claude-opus-5)— 最も強力な汎用選択肢ですが、これはシンプルで、潜在的に高トラフィックで、コストに敏感な公開ウィジェットであるため、claude-haiku-4-5 はここで特に検討に値します。これはハードコードされず、サーバーを実行する人に委ねられた意図的な選択です。

  4. CHAT_RATE_LIMIT_PER_HOUR(デフォルト 30)— シンプルなインメモリのIPごとの制限で、1人の訪問者が単独で請求額を増やせないようにします。再起動/再デプロイのたびにリセットされ、インスタンス間で共有されません。低トラフィックの個人サイトには十分ですが、一般的な悪用防止策ではありません。

CI/CD

.github/workflows/ci.yml は、main ブランチへのプッシュ/PRごとに実行されます。パッケージのインストール、ruff によるリント、pytest スイートの実行を行います。RenderのGitHub自動デプロイ(上記参照)がCD部分を担当します。

セキュリティ / コストに関する注意

  • MCPツールサーフェス(/mcp)はそれ自体ではLLMを呼び出しません — ローカルのJSONを読み取って返すだけです。接続する側(そのClaude、そのトークン)がそのコストを負担し、このサーバーは負担しません。

  • /chat エンドポイントはLLMを呼び出します。このサーバー自身のAnthropic APIキーを使用します。それがそもそもの目的です(ブラウザはキーを安全に保持できません)。コストはIPごとのレート制限、effort: "low"、および小さな max_tokens によって制限されています。詳細は上記のチャットエンドポイントのセクションを参照してください。

  • すべてのデータはすでに私のポートフォリオサイトで公開されています。どちらのエンドポイントにも認証は実装されていません。保護するべきプライベートなものは何もないからです。/chat のCORS許可リストは、誰がAPI予算を使うことができるかを制御するために存在し、データを保護するためではありません。

データの更新

data/ の下のJSONファイルを直接編集してください。id は get_project_details が照合する安定した識別子です。他のフィールドは自由形式です。コンテンツの更新にコードの変更は必要ありません。

Available Tools

4 tools
get_project_detailsA

Get the full record for one portfolio item. For a flagship project this includes role, tech stack, the problem it solved, challenges and how they were solved, outcomes, and links; for a lighter item (a course report, a smaller competition entry) it returns whatever is on file — at minimum a description and its links.

Args: name: A project name, id, or known alias/alternate name — e.g. "IM Your Buddy", "knovyra", "lab handover", "NTPU OPE Assistant", or a competition name like "North Taiwan University Alliance AI Agent Competition". Matching is forgiving (case-insensitive, partial, alias-aware), so you don't need the exact id from list_projects — but calling list_projects first helps pick the right one when unsure.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYes

TDQS

A4.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description fully bears the burden of behavioral disclosure. It clearly conveys the tool's non-destructive, read-only nature by stating it retrieves records. However, it does not disclose potential side effects like logging, or rate limits, which slightly limits transparency. The indication that matching is forgiving and alias-aware adds valuable behavioral context, justifying a 4.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is efficiently structured, front-loading the tool's purpose in the first sentence, then elaborating on behavioral nuance (flagship vs lighter items) in a natural flow. Every sentence adds value, and the Args section is clearly separated and self-contained. There is no wasted text.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool has only one parameter, no annotations, and no output schema, the description provides sufficient context for an AI agent to select and invoke the tool correctly. It covers input semantics, matching behavior, variation in returned data, and even suggests a complementary sibling tool (list_projects). The description is complete for this single-param retrieval tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has 0% description coverage and only one parameter ('name'), so the description must fully compensate. It excels by describing acceptable inputs (project name, id, alias, or competition name), provides concrete examples, and explains matching behavior (case-insensitive, partial, alias-aware). This adds rich semantics far beyond the schema's bare type declaration.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description explicitly states the tool retrieves the full record for one portfolio item, differentiating between flagship projects (returns detailed fields like role, tech stack, outcomes) and lighter items (returns description and links). This clear verb+resource+variation makes the purpose highly specific and distinct from siblings like list_projects.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit guidance on when to use this tool (to get full details of a single portfolio item) and includes a clear when-not alternative: it advises calling list_projects first to select the right item when unsure about the name. This pre-emptive guidance prevents misuse and clarifies the tool's role in a workflow.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_resume_summaryA

Get a self-introduction / resume summary, plus name, title, and contact info. Use this to answer "tell me about yourself" or "give me a summary of this person's background" style questions.

Args: length: "short" for 1-2 sentences, "medium" for a paragraph, or "long" for a full narrative summary covering research, shipped projects, publications, and certifications. Defaults to "short".

ParametersJSON Schema
NameRequiredDescriptionDefault
lengthNoshort

TDQS

A4.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description must fully disclose behavioral traits. It explains what the tool returns (self-introduction, name, title, contact info) and the length parameter's effect. However, it does not mention whether the operation is read-only, any authentication requirements, or rate limits. For a simple get operation, this is adequate but not exceptional.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise and front-loaded: two sentences of purpose followed by a clear parameter definition. Every sentence adds value, and there is no redundancy or filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity (one parameter, no output schema), the description is largely complete. It covers what the tool returns and how to use the length parameter. It could be slightly more explicit about the return format or structure, but it is sufficient for an agent to invoke correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate for the lack of parameter info. It does so excellently by explaining the 'length' parameter with three concrete options ('short', 'medium', 'long') and their meanings. This adds significant value beyond the schema's bare type and default.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'Get a self-introduction / resume summary, plus name, title, and contact info.' It also provides concrete use cases ('tell me about yourself' or 'give me a summary of this person's background'). This distinguishes it from sibling tools like list_projects and search_skills.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly tells when to use the tool: 'Use this to answer... style questions.' This gives clear context. However, it does not explicitly state when not to use it or point to alternative tools, which would be a minor improvement.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_projectsA

List every item in the portfolio — shipped systems, competition entries, research projects, published papers, and course reports, not just the flagship case studies — with id, name, tagline, category, year, a one-sentence summary, and its links (live system, GitHub, report, demo video, etc., whichever apply). Links are included right here, so a system or report can be pointed to without a second call. An entry's related_project (when present) is the id of a fuller case study it's a stage or companion piece of — pass that id to get_project_details for the deep-dive version. Call this first for any broad question like "what has this person worked on?" or "does a system exist for X?".

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full transparency burden. It explains that links are included to avoid a second call, and describes the related_project field and its purpose. It does not mention any side effects (none expected), but could be more explicit about the read-only nature. Still, it provides useful behavioral context beyond a simple list.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with a clear topic sentence, then enumeration of fields, an explanation of related_project, and usage guidance. Every sentence adds value. It is slightly long but not verbose; it could be tightened slightly (e.g., remove 'whichever apply' as it's implied).

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given that the tool has no parameters and an output schema exists, the description is quite complete. It explains the output fields, the role of related_project, and when to use it. However, it does not mention ordering or limiting of results, and the portfolio size is assumed small. For most use cases, this is sufficient.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so schema coverage is 100% trivially. The baseline for no parameters is 4, as the description does not need to add parameter semantics. However, it does describe the output fields, which is beneficial for understanding the tool's result but not directly about input parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states it lists every item in the portfolio with specific fields, and distinguishes itself from the sibling 'get_project_details' by emphasizing that links and related_project are included for a comprehensive overview. The verb 'List' and resource 'projects' are specific, and the mention of 'not just the flagship case studies' clarifies scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit usage guidance is provided: 'Call this first for any broad question like "what has this person worked on?" or "does a system exist for X?".' This tells the agent when to use this tool and implicitly when not to (e.g., deep-dive should use get_project_details). No exclusions or alternatives needed beyond the sibling context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_skillsA

Search the skills/technology taxonomy by keyword and return matches ranked by relevance, each with the projects that demonstrate it. Use this to answer questions like "does this person know RAG / Docker / vector databases / iOS development?".

Args: keyword: A skill, technology, or category to search for, e.g. "RAG", "Docker", "vector database", "iOS", "Next.js".

ParametersJSON Schema
NameRequiredDescriptionDefault
keywordYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It discloses that results are ranked by relevance and include projects, but does not explicitly state that the tool is read-only, mention any authentication needs, rate limits, or edge cases like no matches. It is adequate but lacks depth.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise with two paragraphs: the main purpose and the args section. Every sentence adds value, and the examples are front-loaded. There is no waste, and the structure is efficient.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity (single parameter, output schema exists), the description is complete. It explains the search behavior, relevance ranking, and inclusion of projects. Since an output schema is present, there is no need to detail return values.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has a single parameter 'keyword' with 0% description coverage. The description compensates fully by providing clear examples ('e.g., "RAG", "Docker", "vector database", "iOS", "Next.js"') and explaining the expected format, which adds significant meaning beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('search') and resource ('skills/technology taxonomy'), states it returns matches ranked by relevance with projects, and provides example questions like 'does this person know RAG / Docker / vector databases / iOS development?' This clearly distinguishes it from sibling tools (list_projects, get_project_details, get_resume_summary).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says 'Use this to answer questions like...' which gives clear context for when to use the tool. While it does not mention when not to use it or name alternatives, the sibling tools are not related to skills search, so the context is sufficient.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 4 tool updatesv0.1.0
    • First observedget_project_details
    • First observedget_resume_summary
    • First observedlist_projects
    • First observedsearch_skills

TDQS

A4.6/5.0

Scored across 4 tools

Disambiguation5/5

Each tool has a distinct, well-defined purpose. list_projects provides an overview, get_project_details provides deep dives on individual entries, search_skills queries the technology taxonomy, and get_resume_summary returns background info. There is no overlap or ambiguity between any of these tools.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern (list_projects, get_project_details, search_skills, get_resume_summary). The naming clearly indicates what action is being taken and on what resource, making the API predictable and easy to navigate.

Tool Count5/5

With exactly 4 tools covering portfolio browsing, detail retrieval, skill search, and resume summary, the number is well-scoped for a personal portfolio MCP server. No tools are missing, and every tool serves a distinct, necessary function without redundancy.

Completeness5/5

The tool set provides a complete coverage of the portfolio domain: listing all entries, retrieving full details for any entry, searching across skills/tags, and providing a professional summary. There are no obvious gaps—a user can explore projects, drill into details, assess expertise, and get background information.

Maintenance

ActivitySlowing
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Exposes personal portfolio data as tools for Claude to answer questions about the developer, including profile, skills, experience, projects, and contact information.
    -
  • A
    license
    Not graded
    quality
    D
    maintenance
    Exposes a structured professional resume as a set of AI-queryable tools, enabling AI clients like Claude Desktop to query summary, experience, skills, projects, and tailor resumes to job descriptions.
    1
    MIT
  • F
    license
    A
    quality
    B
    maintenance
    MCP server that exposes a resume as callable tools and resources, enabling AI agents to query experience, skills, projects, and contact information via natural language.
    3
    -