feat: add mcp-dev plugin for MCP server development guide#32
Conversation
Vendor the mcp-builder skill from anthropics/skills repository as a local plugin. This provides comprehensive MCP server development guidance with best practices, TypeScript/Python patterns, and evaluation tools. The plugin includes: - MCP development best practices and guidelines - Node.js/TypeScript server implementation patterns - Python server implementation patterns - Evaluation tools and scripts for testing MCP servers - Example evaluation configurations Source: anthropics/skills mcp-builder skill
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Summary of ChangesHello @amondnet, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly enhances the development ecosystem by introducing a dedicated plugin for Model Context Protocol (MCP) server creation. It aims to standardize and simplify the process of building high-quality MCP servers by providing a centralized resource for best practices, language-specific implementation guides, and robust evaluation mechanisms. This addition will empower developers to create more effective and reliable integrations with external services. Highlights
Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request introduces the mcp-dev plugin, which provides a comprehensive guide for MCP server development. The changes are well-organized, including detailed documentation for best practices, language-specific patterns for TypeScript and Python, and a suite of evaluation scripts. The code is generally of high quality. I've identified one potential runtime error in the evaluation script that should be addressed.
There was a problem hiding this comment.
9 issues found across 12 files
Prompt for AI agents (all issues)
Check if these issues are valid — if so, understand the root cause of each and fix them.
<file name="plugins/mcp-dev/scripts/connections.py">
<violation number="1" location="plugins/mcp-dev/scripts/connections.py:51">
P2: The return value of `self._stack.__aexit__()` is discarded. Per the Python async context manager protocol, `__aexit__` should return the inner stack's result to correctly propagate exception suppression.</violation>
</file>
<file name="plugins/mcp-dev/scripts/requirements.txt">
<violation number="1" location="plugins/mcp-dev/scripts/requirements.txt:2">
P1: Minimum `mcp` version is too low — `mcp.client.streamable_http.streamablehttp_client` was introduced in v1.8.0 of the MCP Python SDK. Installing any version between 1.1.0 and 1.7.x will cause an `ImportError` when `connections.py` is imported. Bump the minimum to `>=1.8.0`.</violation>
</file>
<file name="plugins/mcp-dev/scripts/evaluation.py">
<violation number="1" location="plugins/mcp-dev/scripts/evaluation.py:110">
P1: Bug: Only the first `tool_use` block is processed per response turn. The Anthropic API can return multiple parallel tool calls in a single response, and requires a `tool_result` for each `tool_use`. This will cause an API error when the model issues parallel tool calls. Iterate over all `tool_use` blocks and return all results.</violation>
<violation number="2" location="plugins/mcp-dev/scripts/evaluation.py:168">
P1: Bug: `response` from `agent_loop` can be `None` (when no text block exists in the final response), which will cause a `TypeError` in `re.findall` inside `extract_xml_content`. Add a `None` guard before passing to regex.</violation>
</file>
<file name="plugins/mcp-dev/skills/mcp-builder/reference/node_mcp_server.md">
<violation number="1" location="plugins/mcp-dev/skills/mcp-builder/reference/node_mcp_server.md:547">
P1: SDK version mismatch: `package.json` specifies `@modelcontextprotocol/sdk: ^1.6.1` (v1.x), but all code examples use `server.registerTool()` which is a v2 API. The v1.x SDK uses `server.tool()` instead. Developers following this guide will encounter runtime errors. Either update the dependency to the v2 SDK package (`@modelcontextprotocol/server`) or change the code examples to use the v1.x `server.tool()` API.</violation>
<violation number="2" location="plugins/mcp-dev/skills/mcp-builder/reference/node_mcp_server.md:767">
P2: Unused import: `ResourceTemplate` is imported but never used in the resource registration examples below. This is confusing for developers following the guide. Either remove the import or show an example that actually uses `ResourceTemplate`.</violation>
</file>
<file name="plugins/mcp-dev/skills/mcp-builder/reference/mcp_best_practices.md">
<violation number="1" location="plugins/mcp-dev/skills/mcp-builder/reference/mcp_best_practices.md:223">
P2: Error handling example contradicts the document's own security guidance. The code directly exposes `error.message` to the client, but the Security and Error Handling sections both advise against exposing internal errors/implementation details. Consider sanitizing the error or mapping internal errors to user-safe messages in the example.</violation>
</file>
<file name="plugins/mcp-dev/skills/mcp-builder/reference/python_mcp_server.md">
<violation number="1" location="plugins/mcp-dev/skills/mcp-builder/reference/python_mcp_server.md:90">
P1: Pydantic v2 migration issue: `max_items` is deprecated. Use `max_length=10` instead, consistent with the document's own Pydantic v2 guidance (which correctly recommends `field_validator` over `validator`, `model_dump()` over `dict()`, etc.).</violation>
<violation number="2" location="plugins/mcp-dev/skills/mcp-builder/reference/python_mcp_server.md:522">
P1: Incorrect Context API method names. The FastMCP Context object exposes `ctx.info()`, `ctx.debug()`, `ctx.error()`, and `ctx.log()` — not `ctx.log_info()`. Users following this guide will get an `AttributeError`.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
| @@ -0,0 +1,2 @@ | |||
| anthropic>=0.39.0 | |||
| mcp>=1.1.0 | |||
There was a problem hiding this comment.
P1: Minimum mcp version is too low — mcp.client.streamable_http.streamablehttp_client was introduced in v1.8.0 of the MCP Python SDK. Installing any version between 1.1.0 and 1.7.x will cause an ImportError when connections.py is imported. Bump the minimum to >=1.8.0.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At plugins/mcp-dev/scripts/requirements.txt, line 2:
<comment>Minimum `mcp` version is too low — `mcp.client.streamable_http.streamablehttp_client` was introduced in v1.8.0 of the MCP Python SDK. Installing any version between 1.1.0 and 1.7.x will cause an `ImportError` when `connections.py` is imported. Bump the minimum to `>=1.8.0`.</comment>
<file context>
@@ -0,0 +1,2 @@
+anthropic>=0.39.0
+mcp>=1.1.0
</file context>
| mcp>=1.1.0 | |
| mcp>=1.8.0 |
| tool_metrics = {} | ||
|
|
||
| while response.stop_reason == "tool_use": | ||
| tool_use = next(block for block in response.content if block.type == "tool_use") |
There was a problem hiding this comment.
P1: Bug: Only the first tool_use block is processed per response turn. The Anthropic API can return multiple parallel tool calls in a single response, and requires a tool_result for each tool_use. This will cause an API error when the model issues parallel tool calls. Iterate over all tool_use blocks and return all results.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At plugins/mcp-dev/scripts/evaluation.py, line 110:
<comment>Bug: Only the first `tool_use` block is processed per response turn. The Anthropic API can return multiple parallel tool calls in a single response, and requires a `tool_result` for each `tool_use`. This will cause an API error when the model issues parallel tool calls. Iterate over all `tool_use` blocks and return all results.</comment>
<file context>
@@ -0,0 +1,373 @@
+ tool_metrics = {}
+
+ while response.stop_reason == "tool_use":
+ tool_use = next(block for block in response.content if block.type == "tool_use")
+ tool_name = tool_use.name
+ tool_input = tool_use.input
</file context>
| print(f"Task {task_index + 1}: Running task with question: {qa_pair['question']}") | ||
| response, tool_metrics = await agent_loop(client, model, qa_pair["question"], tools, connection) | ||
|
|
||
| response_value = extract_xml_content(response, "response") |
There was a problem hiding this comment.
P1: Bug: response from agent_loop can be None (when no text block exists in the final response), which will cause a TypeError in re.findall inside extract_xml_content. Add a None guard before passing to regex.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At plugins/mcp-dev/scripts/evaluation.py, line 168:
<comment>Bug: `response` from `agent_loop` can be `None` (when no text block exists in the final response), which will cause a `TypeError` in `re.findall` inside `extract_xml_content`. Add a `None` guard before passing to regex.</comment>
<file context>
@@ -0,0 +1,373 @@
+ print(f"Task {task_index + 1}: Running task with question: {qa_pair['question']}")
+ response, tool_metrics = await agent_loop(client, model, qa_pair["question"], tools, connection)
+
+ response_value = extract_xml_content(response, "response")
+ summary = extract_xml_content(response, "summary")
+ feedback = extract_xml_content(response, "feedback")
</file context>
| "node": ">=18" | ||
| }, | ||
| "dependencies": { | ||
| "@modelcontextprotocol/sdk": "^1.6.1", |
There was a problem hiding this comment.
P1: SDK version mismatch: package.json specifies @modelcontextprotocol/sdk: ^1.6.1 (v1.x), but all code examples use server.registerTool() which is a v2 API. The v1.x SDK uses server.tool() instead. Developers following this guide will encounter runtime errors. Either update the dependency to the v2 SDK package (@modelcontextprotocol/server) or change the code examples to use the v1.x server.tool() API.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At plugins/mcp-dev/skills/mcp-builder/reference/node_mcp_server.md, line 547:
<comment>SDK version mismatch: `package.json` specifies `@modelcontextprotocol/sdk: ^1.6.1` (v1.x), but all code examples use `server.registerTool()` which is a v2 API. The v1.x SDK uses `server.tool()` instead. Developers following this guide will encounter runtime errors. Either update the dependency to the v2 SDK package (`@modelcontextprotocol/server`) or change the code examples to use the v1.x `server.tool()` API.</comment>
<file context>
@@ -0,0 +1,970 @@
+ "node": ">=18"
+ },
+ "dependencies": {
+ "@modelcontextprotocol/sdk": "^1.6.1",
+ "axios": "^1.7.9",
+ "zod": "^3.23.8"
</file context>
|
|
||
| **Context capabilities:** | ||
| - `ctx.report_progress(progress, message)` - Report progress for long operations | ||
| - `ctx.log_info(message, data)` / `ctx.log_error()` / `ctx.log_debug()` - Logging |
There was a problem hiding this comment.
P1: Incorrect Context API method names. The FastMCP Context object exposes ctx.info(), ctx.debug(), ctx.error(), and ctx.log() — not ctx.log_info(). Users following this guide will get an AttributeError.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At plugins/mcp-dev/skills/mcp-builder/reference/python_mcp_server.md, line 522:
<comment>Incorrect Context API method names. The FastMCP Context object exposes `ctx.info()`, `ctx.debug()`, `ctx.error()`, and `ctx.log()` — not `ctx.log_info()`. Users following this guide will get an `AttributeError`.</comment>
<file context>
@@ -0,0 +1,719 @@
+
+**Context capabilities:**
+- `ctx.report_progress(progress, message)` - Report progress for long operations
+- `ctx.log_info(message, data)` / `ctx.log_error()` / `ctx.log_debug()` - Logging
+- `ctx.elicit(prompt, input_type)` - Request input from users
+- `ctx.fastmcp.name` - Access server configuration
</file context>
|
|
||
| param1: str = Field(..., description="First parameter description (e.g., 'user123', 'project-abc')", min_length=1, max_length=100) | ||
| param2: Optional[int] = Field(default=None, description="Optional integer parameter with constraints", ge=0, le=1000) | ||
| tags: Optional[List[str]] = Field(default_factory=list, description="List of tags to apply", max_items=10) |
There was a problem hiding this comment.
P1: Pydantic v2 migration issue: max_items is deprecated. Use max_length=10 instead, consistent with the document's own Pydantic v2 guidance (which correctly recommends field_validator over validator, model_dump() over dict(), etc.).
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At plugins/mcp-dev/skills/mcp-builder/reference/python_mcp_server.md, line 90:
<comment>Pydantic v2 migration issue: `max_items` is deprecated. Use `max_length=10` instead, consistent with the document's own Pydantic v2 guidance (which correctly recommends `field_validator` over `validator`, `model_dump()` over `dict()`, etc.).</comment>
<file context>
@@ -0,0 +1,719 @@
+
+ param1: str = Field(..., description="First parameter description (e.g., 'user123', 'project-abc')", min_length=1, max_length=100)
+ param2: Optional[int] = Field(default=None, description="Optional integer parameter with constraints", ge=0, le=1000)
+ tags: Optional[List[str]] = Field(default_factory=list, description="List of tags to apply", max_items=10)
+
+@mcp.tool(
</file context>
| async def __aexit__(self, exc_type, exc_val, exc_tb): | ||
| """Clean up MCP server connection resources.""" | ||
| if self._stack: | ||
| await self._stack.__aexit__(exc_type, exc_val, exc_tb) |
There was a problem hiding this comment.
P2: The return value of self._stack.__aexit__() is discarded. Per the Python async context manager protocol, __aexit__ should return the inner stack's result to correctly propagate exception suppression.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At plugins/mcp-dev/scripts/connections.py, line 51:
<comment>The return value of `self._stack.__aexit__()` is discarded. Per the Python async context manager protocol, `__aexit__` should return the inner stack's result to correctly propagate exception suppression.</comment>
<file context>
@@ -0,0 +1,151 @@
+ async def __aexit__(self, exc_type, exc_val, exc_tb):
+ """Clean up MCP server connection resources."""
+ if self._stack:
+ await self._stack.__aexit__(exc_type, exc_val, exc_tb)
+ self.session = None
+ self._stack = None
</file context>
| Expose data as resources for efficient, URI-based access: | ||
|
|
||
| ```typescript | ||
| import { ResourceTemplate } from "@modelcontextprotocol/sdk/types.js"; |
There was a problem hiding this comment.
P2: Unused import: ResourceTemplate is imported but never used in the resource registration examples below. This is confusing for developers following the guide. Either remove the import or show an example that actually uses ResourceTemplate.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At plugins/mcp-dev/skills/mcp-builder/reference/node_mcp_server.md, line 767:
<comment>Unused import: `ResourceTemplate` is imported but never used in the resource registration examples below. This is confusing for developers following the guide. Either remove the import or show an example that actually uses `ResourceTemplate`.</comment>
<file context>
@@ -0,0 +1,970 @@
+Expose data as resources for efficient, URI-based access:
+
+```typescript
+import { ResourceTemplate } from "@modelcontextprotocol/sdk/types.js";
+
+// Register a resource with URI template
</file context>
| isError: true, | ||
| content: [{ | ||
| type: "text", | ||
| text: `Error: ${error.message}. Try using filter='active_only' to reduce results.` |
There was a problem hiding this comment.
P2: Error handling example contradicts the document's own security guidance. The code directly exposes error.message to the client, but the Security and Error Handling sections both advise against exposing internal errors/implementation details. Consider sanitizing the error or mapping internal errors to user-safe messages in the example.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At plugins/mcp-dev/skills/mcp-builder/reference/mcp_best_practices.md, line 223:
<comment>Error handling example contradicts the document's own security guidance. The code directly exposes `error.message` to the client, but the Security and Error Handling sections both advise against exposing internal errors/implementation details. Consider sanitizing the error or mapping internal errors to user-safe messages in the example.</comment>
<file context>
@@ -0,0 +1,249 @@
+ isError: true,
+ content: [{
+ type: "text",
+ text: `Error: ${error.message}. Try using filter='active_only' to reduce results.`
+ }]
+ };
</file context>
Summary
Vendor the
mcp-builderskill fromanthropics/skillsrepository as a local plugin namedmcp-dev. This provides comprehensive MCP server development guidance with best practices, implementation patterns, and evaluation tools.Changes
plugins/mcp-dev/mcp-deventry to.claude-plugin/marketplace.jsonPlugin Structure
Source
mcp-builderskillLICENSE.txt)Test Plan
plugin.json) is valid.claude-plugin/marketplace.jsonRelated Issues
This vendors the mcp-builder skill as discussed in the plugin marketplace expansion.
Summary by cubic
Adds the mcp-dev plugin to provide a practical MCP server development guide with TypeScript/Python patterns and an evaluation harness. Updates the marketplace to include the plugin.
New Features
Dependencies
Written for commit 749cbb5. Summary will update on new commits.