← all systems
AGENT INFRAENRICHMENTAI AGENT

In-House Clay MCP Server

A paid hosted MCP dependency sat between our agents and client workspaces. I replaced it with one we own. Same tool names, validated live.

MCP (stdio) · TypeScript / Node · Clay · Env-only credentials

The Problem

Our agents talked to Clay through a third-party hosted MCP server. It worked, but every call routed client workspace access through someone else's proxy, and the vendor controlled uptime, pricing, and which tools existed. For a consultancy running live client workspaces, that is the wrong place for a dependency. I built a drop-in replacement: same tool names, so nothing upstream changed; our own credential handling, so no third party sits between us and a client workspace; and every tool validated against a production workspace before it replaced anything.

Stack

🔌
MCP (stdio)
Drop-in replacement — identical tool names to the hosted server
🟦
TypeScript / Node
Server, tool layer, live validation suite
🧱
Clay
Table status, credits, counts, schema, export, column operations
🔐
Env-only credentials
Loaded at startup — never accepted as a tool argument

How It Works

The execution path

01Map the Tools
→
02Rebuild In-House
→
03Validate Live
→
04Swap the Dependency
Execution flow
Inventory every tool the hosted server exposed— names, inputs, outputs
Implement each with the hosted server's exact name and shape
Credentials loaded from env at startup — never a tool arg
tools/call against production: status · credits · count · schema · export · add column · update column
All 200 → repoint agents to the in-house server
Nothing upstream changes; the third party is gone
The migration was invisible to everything upstream. Every skill and agent that used the hosted server kept working the moment we pointed it at ours, because tool-name parity was a design requirement, not a nice-to-have. Before the swap, each tool was exercised through real MCP tools/call on the live workspace — status, credits, count, schema, paginated export, add column, update column — and every one returned 200. The security rule is one line and non-negotiable: credentials load from the environment at startup and are never accepted as a tool argument.

Key Design Decisions

🔁
Drop-In, Not Rewrite
Same tool names as the vendor. Every agent and skill that used the hosted server kept working the moment we pointed it at ours.
🔐
Credentials Never Cross the Tool Boundary
Loaded from the environment at startup. They cannot be passed, logged, or leaked through a tool argument.
🧪
Validated Against Production
Every tool was exercised through real MCP tools/call on the live workspace before it replaced anything.
🏠
Own the Dependency
Uptime, cost, and the tool surface are ours to control. No third party between an agent and a client workspace.

By The Numbers

7
Tools validated live
0
Third parties in the path
1:1
Tool-name parity with hosted server
100%
Upstream agents unchanged
← back to all systemsmatthew batterson · gtm engineer