2026-06-19 · Architecture
Our MCP server is 160 lines
We put our whole CRM behind MCP last month — every table, document, dashboard, the chat, the calendar, the agents' own memory. 73 tools. I'd blocked out a week for it. It took an afternoon, and the server came out to 160 lines.
I keep going back to that number, so I want to write it down before it stops looking strange to me.
Here is an excerpt from the June 2026 adapter. The line and tool counts describe that snapshot, not the complete backend or today's catalogue. This excerpt omits authentication and deployment context; the literal internal user ID is not an authorization pattern for an exposed service:
const mcpTools = AGENT_TOOLS
.map(openaiToMcpTool)
.filter(t => t && !SKIP_TOOLS.has(t.name));
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
const result = await executeTool(name, args || {}, 1, context);
return { content: [{ type: 'text', text: stringify(result) }] };
});
List the tools, run the tool. The schema converter is nine lines — it copies a name, a description and a JSON schema from one envelope into another:
function openaiToMcpTool(toolDef) {
const fn = toolDef.function;
if (!fn?.name) return null;
return {
name: fn.name,
description: fn.description || '',
inputSchema: fn.parameters || { type: 'object', properties: {} },
};
}
The bridge adapts the existing tool schemas and executor to MCP. The tools were already defined as function schemas, because that's how our own agents have always called them. People and agents work with the same business records. UI requests and agent tools can use different entry points; shared storage does not imply that every button invokes executeTool. So when MCP came along there was nothing to build. We wrote a nine-line adapter and pointed it at the executor we had already built.
A detail, for honesty in both directions. We skip about fifteen tools on purpose — the agents' private scaffolding (planning, orchestration) and the file tools, since a client like Claude Code has its own. And this isn't npx-and-go: the bridge boots the real backend and wants a Postgres behind it. It's a server to a running CRM, not a toy. The trade is that you get all 73 tools over real, typed, related state.
I don't think 160 lines is impressive by itself. It's small because the expensive decision was made earlier, somewhere that has nothing to do with MCP. That's the part I find interesting — and it's easier to see in the repo than to explain in a post.
It's open source, MIT. The bridge and all 73 tool definitions are there.
godcrm.ai/git/holetron-lab/godcrm
Correction · 29 September 2026: Dated the adapter snapshot, removed the unsupported multi-year timeline and exact UI/MCP call-path equivalence. The displayed adapter is not a complete authenticated service.