About
An MCP daemon for automated tool registration.
README
A daemon that aggregates multiple MCP (Model Context Protocol) servers into one. Implements the MCP spec (2025-11-25).
Register any MCP server once with mcpd, then point your MCP client at mcpd. Add or remove servers at any time — agents discover new tools, resources, and prompts in realtime.
Installation
cargo install mcpd
or for local:
cargo install --path .
Usage
Register a server
mcpd register <name> <command> [args...]
Examples:
# Register a Node.js MCP server
mcpd register filesystem npx -y @anthropic/mcp-filesystem /home/user/documents
# Register a Python server
mcpd register mytools python -m my_mcp_server
# Register with environment variables
mcpd register api-tools node server.js -e API_KEY=sk-xxx -e DEBUG=1
List registered servers
mcpd list
Remove a server
mcpd unregister <name>
Run the daemon
mcpd serve
This starts mcpd in stdio mode, ready to accept MCP connections.
Client Configuration
Point your MCP client at mcpd instead of individual servers.
Claude Code (~/.claude/settings.json):
{
"mcpServers": {
"mcpd": {
"command": "mcpd",
"args": ["serve"]
}
}
}
Claude Desktop (claude_desktop_config.json):
{
"mcpServers": {
"mcpd": {
"command": "mcpd",
"args": ["serve"]
}
}
}
VSCode (Ctrl+Shift+P, search 'MCP', click 'MCP: Add Server', select 'stdio', type mcpd serve)
How It Works
mcpd aggregates all three MCP primitives — tools, resources, and prompts — from every registered backend into a single server.
Tools (dual-layer)
mcpd exposes exactly two meta-tools to the MCP client, regardless of how many backend servers are registered:
list_tools— Queries all registered backends and returns their tools (names, descriptions, input schemas).use_tool— Invokes a backend tool by its fully-qualified name (server__tool) with the given arguments.
The agent naturally calls list_tools first (it's the only way to know what's available), then calls use_tool to invoke what it needs. You can register or unregister backends at any time — the agent just calls list_tools again to see the latest.
Resources
mcpd natively proxies resources/list and resources/read. Resources from all backends are aggregated and namespaced:
- URIs are prefixed:
mcpd://servername/original-uri - Names are prefixed:
servername__resourcename
Backends that don't support resources are silently skipped.
Prompts
mcpd natively proxies prompts/list and prompts/get. Prompts from all backends are aggregated and namespaced:
- Names are prefixed:
servername__promptname
Backends that don't support prompts are silently skipped.
┌─────────────────┐
│ MCP Client │
│ (Claude, etc.) │
└────────┬────────┘
│ tools, resources, prompts
▼
┌─────────────────┐
│ mcpd │
└──┬─────┬─────┬──┘
│ │ │ stdio (spawned on-demand)
▼ ▼ ▼
┌─────┐┌─────┐┌─────┐
│ srv1││ srv2││ srv3│
└─────┘└─────┘└─────┘
Workflow
- You register MCP servers with mcpd (stored in
~/.config/mcpd/registry.json) - Your MCP client connects to mcpd and sees two meta-tools (
list_tools,use_tool) plus aggregated resources and prompts - Agent calls
list_toolsto discover available backend tools - Agent calls
use_tool(tool_name="server__tool", arguments={...})to invoke them - Client can also call
resources/list,resources/read,prompts/list,prompts/getdirectly - mcpd spawns backend servers on-demand and proxies the call
Example
After registering a filesystem server:
Agent calls: list_tools()
Returns:
[{"name": "filesystem__read_file", "description": "Read a file", "input_schema": {...}},
{"name": "filesystem__write_file", "description": "Write a file", "input_schema": {...}}]
Agent calls: use_tool(tool_name="filesystem__read_file", arguments={"path": "/tmp/hello.txt"})
Returns: contents of the file
Resources and prompts work via standard MCP methods:
Client calls: resources/list
Returns:
[{"uri": "mcpd://myserver/file:///docs/readme.md", "name": "myserver__readme", ...}]
Client calls: resources/read(uri="mcpd://myserver/file:///docs/readme.md")
Returns: resource contents
Client calls: prompts/list
Returns:
[{"name": "myserver__summarize", "description": "Summarize a document", ...}]
Client calls: prompts/get(name="myserver__summarize", arguments={"text": "..."})
Returns: prompt messages
Why mcpd?
- Register once: Add servers to mcpd, not to every client
- Full MCP proxy: Aggregates tools, resources, and prompts from all backends
- Hot reload: Register/unregister servers while mcpd is running — the registry is re-read on every request, and clients are notified via
list_changednotifications - Stable interface: Clients always see exactly two meta-tools, no matter how many backends exist
- Namespace isolation: Tools, resources, and prompts from different servers can't collide (
server__nameformat) - On-demand: Backend servers only spawn when actually needed
- Graceful degradation: Backends that don't support resources or prompts are silently skipped
License
MIT
Installing Mcpd
This server has no published package — it is built from source. Open the repository and follow its README.
▸ github.com/xandwr/mcpdFAQ
Is Mcpd MCP free?
Yes, Mcpd MCP is free — one-click install via Unyly at no cost.
Does Mcpd need an API key?
No, Mcpd runs without API keys or environment variables.
Is Mcpd hosted or self-hosted?
Self-hosted: the server runs locally on your machine via the install command above.
How do I install Mcpd in Claude Desktop, Claude Code or Cursor?
Open Mcpd on unyly.org, pick your client tab (Claude Desktop, Claude Code, Cursor) and press Install — the config is generated automatically, no JSON editing.
Related MCPs
GitHub
PRs, issues, code search, CI status
by GitHubFilesystem
Secure file operations with configurable access controls.
Memory
Knowledge graph-based persistent memory system.
Template MCP Server
A CLI tool to create a new Model Context Protocol server project with TypeScript support, dual transport options, and an extensible structure
by mcpdotdirectCompare Mcpd with
Not sure what to pick?
Find your stack in 60 seconds
Author?
Embed badge for your README
Browse similar
All development MCPs
