ClydeNexus — the command center for this homelab — has always had a chat interface. You open a browser, ask it something, and it queries the fleet, pulls logs, checks spend, runs tasks. That works fine from a browser. But I wanted to flip it: instead of going to ClydeNexus, I wanted to bring the fleet tools into wherever I'm already working.
That turned out to be MCP.
What MCP Is
The Model Context Protocol is an open standard for connecting AI assistants to external tools over HTTP. Claude, Claude.ai, and a growing number of clients support it. You register a server URL, and the assistant gets a list of tools it can call — the same way you'd define tools in the API directly, except they live on your server instead of in the prompt.
The protocol is JSON-RPC 2.0 over HTTP, with an optional SSE stream for server-initiated events. From the server's perspective, you implement three methods: initialize (handshake), tools/list (return your tool schemas), and tools/call (execute a tool and return the result).
The Setup
ClydeNexus already had 36 tools defined in tools.py — everything from get_fleet_status and search_fleet_logs to submit_task and save_memory. These were wired into the WebSocket chat handler. The MCP server is a separate FastAPI app (mcp_server.py) that imports those same tool implementations directly and wraps them in the MCP protocol. No duplicated logic — same code, different transport.
The server runs on port 7856 as clydenexus-mcp.service, exposed publicly at https://mcp.burntai.com via the DMZ nginx proxy.
Tool subset is 24 of 36. The excluded ones are destructive or internal: deploy_cc_agent, provision_and_onboard, and a few others that shouldn't be reachable from a public endpoint even with auth.
The Auth Problem
Bearer token auth was the obvious starting point. Generate a token, check it on every request, done. Except claude.ai's connector doesn't send a Bearer token — it uses OAuth Dynamic Client Registration (RFC 7591) to get one first.
The flow looks like this:
- Claude.ai fetches
/.well-known/oauth-authorization-serverto discover endpoints - It POSTs to
/registerto register itself as a client - It GETs
/authorizeto get an authorization code - It POSTs to
/tokento exchange the code for an access token - It uses that token on subsequent requests
So I implemented all five endpoints. They auto-approve everything — this is a homelab, the authorization model is "is this the claude.ai connector I registered." Tokens are in-memory and lost on restart; claude.ai just re-registers on reconnect.
One additional quirk: if no Authorization header is present at all, the server allows the request. This handles clients that call tools/list before completing the OAuth flow.
What It Can Do
Once registered, claude.ai gets 24 tools covering:
- Fleet status — host health, stack services, metrics per host
- Memory — read, write, search the ClydeNexus memory layer
- Tasks — submit tasks to cc_agent on any fleet host, check session output
- Logs — search fleet logs across all 19 hosts, filter by host/program/level
- Spend — daily API spend by key, cap status, usage breakdown
- Hosts — list hosts from ProjectLens, sync fleet state
In practice this means I can open a new Claude conversation, ask "which hosts had errors in the last hour," and get a real answer pulled from /var/log/clydestack/ across the fleet — without opening ClydeNexus or SSHing into anything.
What's Interesting About This Pattern
The MCP server itself is about 300 lines. Most of it is OAuth boilerplate. The actual tool dispatch is a dict lookup and a function call. The hard part was already done: the tool implementations, the fleet clients, the memory layer. MCP just adds an HTTP adapter on top.
It also makes the tooling available from any MCP-compatible client, not just claude.ai. The same server works with any client that speaks the protocol.
The server is live at https://mcp.burntai.com/mcp — not useful to anyone outside this homelab, but the pattern (wrap existing internal tools in MCP, expose via reverse proxy, handle OAuth for claude.ai) is straightforward enough to be worth documenting.