https://github.com/pitimon/mcp-plugin-patterns
Production patterns for building MCP plugins for Claude Code — from c-memforge (27 tools)
https://github.com/pitimon/mcp-plugin-patterns
Last synced: about 2 months ago
JSON representation
Production patterns for building MCP plugins for Claude Code — from c-memforge (27 tools)
- Host: GitHub
- URL: https://github.com/pitimon/mcp-plugin-patterns
- Owner: pitimon
- Created: 2026-03-21T22:21:30.000Z (3 months ago)
- Default Branch: main
- Last Pushed: 2026-03-21T22:48:21.000Z (3 months ago)
- Last Synced: 2026-03-22T11:14:18.874Z (3 months ago)
- Size: 27.3 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Building Production MCP Plugins for Claude Code
**Practical patterns for building MCP plugins that LLMs actually use correctly.**
This guide shares design patterns, security practices, and lessons learned from building a production MCP plugin (27 tools, workflow hints, SSRF protection, background sync) for Claude Code. These patterns apply to any MCP plugin that talks to a remote API.
**Not** a getting-started tutorial. This is a **builder's guide** — for engineers who have a working MCP server and want to make it production-grade.
## Who This Is For
- Engineers building Claude Code plugins with MCP tools
- Teams shipping MCP servers that call remote APIs
- Developers struggling with LLM tool selection across 10+ tools
- Anyone who has shipped an MCP plugin and watched the LLM pick the wrong tool
## Plugin Architecture
```
┌─────────────────────────────────────────────────────────┐
│ Claude Code Host │
│ │
│ User Prompt ──► LLM reads tool descriptions │
│ ──► selects tool by routing hints │
│ ──► calls MCP tool │
└──────────────────────────┬───────────────────────────────┘
│ MCP Protocol (stdio)
▼
┌─────────────────────────────────────────────────────────┐
│ MCP Plugin Server │
│ │
│ ┌─ Validation ──┐ ┌─ Handlers ──┐ ┌─ Formatters ──┐ │
│ │ Zod schemas │ │ 27 tools │ │ Markdown │ │
│ │ Defense-in- │ │ by domain: │ │ + suggested │ │
│ │ depth (not │ │ search (5) │ │ _next hints │ │
│ │ just hints) │ │ obs (4) │ │ │ │
│ └───────┬───────┘ │ entity (2) │ │ "Use X AFTER" │ │
│ │ │ skill (5) │ │ "Use Y FIRST" │ │
│ ▼ │ meta (6) │ │ "Use Z INSTEAD│ │
│ ┌─ SSRF Guard ──┐ │ context(2) │ └───────────────┘ │
│ │ Hostname list │ │ other (3) │ │
│ │ Endpoint list │ └──────┬──────┘ │
│ │ HTTPS enforce │ │ │
│ │ Metadata block│ │ │
│ └───────────────┘ │ │
│ ▼ │
│ ┌─ API Client ───────────────────────────────────────┐ │
│ │ callRemoteAPI() ── GET + retry (2x backoff) │ │
│ │ postRemoteAPI() ── POST (no retry, mutations) │ │
│ │ patchRemoteAPI() ── PATCH (pin, importance, date) │ │
│ │ Timeout: 30s general, 60s search │ │
│ └────────────────────────┬───────────────────────────┘ │
│ │ │
│ ┌─ Sync Poller ─────────────────────────────────────┐ │
│ │ In-process (not daemon) │ Adaptive: 1-10s │ │
│ │ Circuit breaker (30s) │ Pending queue + retry │ │
│ └─────────────────────────────────────────────────────┘ │
└──────────────────────────┬──────────────────────────────┘
│ HTTPS (X-API-Key)
▼
┌──────────────┐
│ Remote API │
│ Server │
└──────────────┘
```
## Chapters
| # | Chapter | Key Insight |
| --- | ------------------------------------------------------ | ---------------------------------------------------------------------------------- |
| 1 | [Tool Design](chapters/01-tool-design.md) | Fewer tools with modes beat many specialized tools. Group by domain. |
| 2 | [Descriptions as Routing](chapters/02-descriptions.md) | Descriptions are routing hints, not documentation. "Use X FIRST" changes behavior. |
| 3 | [Workflow Hints](chapters/03-workflow-hints.md) | Append "suggested next" actions to results. Rule-based, no LLM needed. |
| 4 | [Input Validation](chapters/04-validation.md) | `inputSchema` is an LLM hint only. Zod enforces at runtime. |
| 5 | [SSRF Protection](chapters/05-ssrf-protection.md) | Hostname allowlist + endpoint allowlist + HTTPS enforcement. |
| 6 | [Sync Architecture](chapters/06-sync-architecture.md) | In-process polling with adaptive intervals and circuit breaker. |
| 7 | [API Client Patterns](chapters/07-api-client.md) | Retry transient errors only. Longer timeouts for search. Format as markdown. |
| 8 | [Publishing](chapters/08-publishing.md) | 3 version files. Plugin directory structure. Marketplace schema. |
## Anti-Patterns
| Anti-Pattern | Why It Fails | Better Alternative |
| ---------------------------------- | -------------------------------------------------- | ------------------------------------------------------------ |
| One tool per API endpoint | LLM can't choose between 30 tools | Unified tool with `mode` parameter (Ch. 1) |
| Description says what, not when | LLM picks wrong tool for the task | "Use X FIRST", "Use Y instead" routing (Ch. 2) |
| No workflow hints | User must manually figure out next step | Append `suggested_next` to results (Ch. 3) |
| Trust `inputSchema` for validation | LLM sends malformed data; no runtime check | Zod schemas as defense-in-depth (Ch. 4) |
| No URL validation on config | SSRF via config file pointing to metadata endpoint | Hostname allowlist + metadata IP block (Ch. 5) |
| Detached sync daemon | Orphaned processes, crash recovery complexity | In-process poller with circuit breaker (Ch. 6) |
| Retry all HTTP errors | 400/401/404 retried forever | Only retry network/TLS errors, not HTTP 4xx (Ch. 7) |
| Single version file | Plugin metadata out of sync with package | 3 files: package.json, plugin.json, marketplace.json (Ch. 8) |
## Technology Stack (Reference Implementation)
```
Runtime: Bun (TypeScript)
Protocol: MCP SDK (@modelcontextprotocol/sdk)
Validation: Zod 4
Transport: stdio (JSON-RPC over stdin/stdout)
API Auth: X-API-Key header
Sync: In-process polling (SQLite -> remote API)
```
## Decision Matrix: Tool Count
| Tool Count | Pros | Cons | When to Use |
| ----------- | ----------------------------- | --------------------------------------------------- | ------------------------------- |
| 1-5 tools | Easy selection, low confusion | Limited capability | Simple plugins (status, config) |
| 6-15 tools | Good balance | Needs routing hints | Most production plugins |
| 16-30 tools | Full feature coverage | Must group by domain, needs descriptions as routing | Complex plugins (memory, data) |
| 30+ tools | Maximum flexibility | LLM confusion, slow tool listing | Split into multiple plugins |
## Contributing
Found a pattern that worked (or broke) in your MCP plugin? PRs welcome.
## License
MIT
---
_Last verified: 2026-03-22 | Version: 1.0_