plugins/mcp-tooling/skills/mcp-proxy-daemoning/SKILL.md
Use this skill when working with mcp-proxy daemoning patterns — running a shared MCP proxy daemon that multiple Claude Code sessions can connect to simultaneously. Use when the user asks about sharing MCP servers across sessions, reducing MCP server overhead, running a single MCP proxy instance for multiple clients, configuring smart-mcp-proxy, or understanding the daemon lifecycle pattern from nsheaps/aitkit. Also use for the Serena de-duplication pattern — running project-level MCP servers at the user level to avoid duplicate instances across projects.
npx skillsauth add nsheaps/ai-mktpl mcp-proxy-daemoningInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Pattern for running a shared MCP proxy daemon that multiple Claude Code sessions connect to simultaneously, reducing resource overhead and enabling cross-session tool sharing.
When multiple Claude Code sessions each spawn their own MCP server processes:
A single daemon process runs the MCP proxy, and multiple sessions connect to it via HTTP:
Session A ──stdio──→ run-mcp-proxy.sh ──HTTP──→ mcp-proxy daemon (port 12476)
Session B ──stdio──→ run-mcp-proxy.sh ──HTTP──→ (same daemon)
Session C ──stdio──→ run-mcp-proxy.sh ──HTTP──→ (same daemon)
The run-mcp-proxy.sh script in nsheaps/aitkit implements a full daemon lifecycle:
MCPPROXY_TOP_K="10" # Tools to register per session
MCPPROXY_TOOLS_LIMIT="50" # Max tools in active pool
MCPPROXY_DATA_DIR="$AITKIT_ROOT/lib/mcpproxy" # Database/index location
MCPPROXY_CONFIG_PATH="$MCPPROXY_DATA_DIR/mcp_proxy_config.json"
MCPPROXY_PORT="12476" # Listen port
MCPPROXY_TRANSPORT="streamable-http" # Transport type
~/.aitkit/
├── run/ # PID files for daemon management
│ ├── mcp-proxy-<name>.pid # Daemon PID
│ └── mcp-servers/ # Per-session registration
│ ├── 12345 # Session A's PID
│ └── 12346 # Session B's PID
└── lib/mcpproxy/
├── mcp_proxy_config.json # MCP server definitions
├── mcp-proxy.log # Daemon log
└── (database/index files) # Smart proxy state
# Simplified lifecycle logic
start_or_reuse_daemon() {
if daemon_is_running; then
echo "Reusing existing daemon at PID $(daemon_pid)"
else
daemon --name "$DAEMON_NAME" --pidfile "$PID_FILE" \
--command "uvx smart-mcp-proxy \
--port $MCPPROXY_PORT \
--transport $MCPPROXY_TRANSPORT \
--config $MCPPROXY_CONFIG_PATH"
fi
# Register this session
echo $$ > "$MCP_PID_DIR/$$"
}
on_exit() {
rm -f "$MCP_PID_DIR/$$"
if [ "$(ls "$MCP_PID_DIR" | wc -l)" -eq 0 ]; then
kill_daemon
fi
}
trap on_exit EXIT
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "."]
},
"serena": {
"command": "uvx",
"args": ["serena", "--workspace", "/path/to/project"]
}
}
}
The smart-mcp-proxy (via uvx) provides:
Serena is a code-aware AI agent tool that stores project knowledge in .serena/memories/. When configured at the project level:
/Users/nheaps/.aitkit/upstreams/gathertown/.ai/bin/mcp/serena.sh) in per-project configs is fragile and non-portable.mcp.json.mcp.json declares Serena AND the user-level daemon already runs it, the daemon version takes precedence# Instead of this (per-project, fragile):
# project/.mcp.json → serena.sh → standalone serena process
# Do this (user-level, shared):
# ~/.aitkit/lib/mcpproxy/mcp_proxy_config.json includes serena
# All sessions connect to the shared daemon
# Serena runs once, with access to all registered projects
~/.aitkit/lib/mcpproxy/mcp_proxy_config.json.mcp.json filesIn your project's .mcp.json or user-level settings, point to the daemon wrapper:
{
"mcpServers": {
"shared-proxy": {
"type": "stdio",
"command": "/path/to/aitkit/bin/run-mcp-proxy.sh",
"args": ["mcp-user"]
}
}
}
The wrapper script:
| Issue | Resolution |
| ------------------------------- | ------------------------------------------------------------------------ |
| Daemon not starting | Check ~/.aitkit/lib/mcpproxy/mcp-proxy.log |
| Stale PID files | Remove ~/.aitkit/run/mcp-servers/* and ~/.aitkit/run/mcp-proxy-*.pid |
| Port conflict | Change MCPPROXY_PORT in the config |
| Tool not found | Verify mcp_proxy_config.json includes the server |
| Daemon crashes between sessions | Background health loop auto-recovers; check logs |
tools
Reference material for Claude Code internals — the on-disk layout under ~/.claude and project-scope .claude, the plugin cache, session-env propagation, and the full hook lifecycle. Auto-recall when working on Claude-Code-related tasks: writing or debugging hooks, authoring plugins, inspecting session state, troubleshooting why an env var is or isn't visible to a Bash tool call, or when paths under ~/.claude or ~/.claude/plugins/ come up.
development
Manage GitHub App installation tokens in Claude Code sessions. Use when tokens expire, auth errors occur in long-running sessions, or when setting up GitHub App credentials for agent teams. <example>my github token expired</example> <example>refresh the github app token</example> <example>check token status</example> <example>set up github app authentication for this session</example>
tools
Auto-detect project formatting tools and configure edit-utils settings
tools
Use this skill when the user asks about 1Password, secrets management, retrieving credentials, using op CLI, service accounts, secret references, vault operations, or any task involving the 1Password CLI (op). Also use when needing to inject secrets into environment variables, read passwords or API keys from 1Password, or manage 1Password items from the command line.