Hook up a custom MCP server
Aroovo bootstraps every Tenant with Zapier MCP for breadth, but the runtime is provider-agnostic — any URL implementing the Model Context Protocol can be registered alongside. This is the path for connecting Composio, Cloudflare Workers MCP, an internal Python MCP service, or your own stack.
localhost, 127.0.0.1), and non-HTTPS URLs in production all reject. If you need to point at a non-public endpoint, expose it via a public hostname (Cloudflare Tunnel, ngrok with a paid domain) before registering.1. Confirm the MCP server is reachable
From any internet-facing host, hit the MCP server's SSE endpoint and confirm it responds to the standard handshake:
curl -N -H 'Accept: text/event-stream' \ https://mcp.example.com/sse
2. Register with Aroovo
As Owner or Admin of the target Tenant:
POST /api/mcp-servers
{
"name": "Composio HubSpot",
"url": "https://mcp.composio.dev/v1/<account>/sse"
}
200 OK
{
"id": "mcp_07",
"name": "Composio HubSpot",
"url": "https://mcp.composio.dev/v1/<account>/sse",
"active": true,
"toolCount": 24
}On success, the platform:
- Opened the MCP connection and introspected the tool list.
- Compiled Ajv validators for every tool input schema (per the security hardening pass in ADR-001).
- Wrote an
McpServerrow scoped to the Tenant. - Wrote a
secret.createdaudit row if the server URL carried an API token in its path.
3. Grant agent access
Newly-registered MCP servers are not automatically allowlisted for any agent. Flip them on per agent:
PUT /api/agents/sales/mcp-servers/mcp_07
{ "allowed": true }
200 OK
{ "serverId": "mcp_07", "allowed": true }4. Inspect the resolved tool catalogue
GET /api/agents/sales/mcp-tools
200 OK
{
"items": [
{
"name": "composio:hubspot_create_contact",
"description": "Create a HubSpot contact",
"approvalPolicy": "single_approval"
},
...
]
}Tool names are namespaced by the server slug (the lowercased, slugified name from registration). The default approval policy for any new MCP server is single_approval for tools with side effects and no_gate for read-only lookups; the heuristic is driven by HTTP verb + tool name match. Override per tool:
PATCH /api/mcp-servers/mcp_07/tools/hubspot_create_contact
{ "approvalPolicy": "dual_approval" }5. Test the call path end-to-end
From the agent's chat: “Create a HubSpot contact for Jane Doe at jane@example.com.” The agent loop will:
- Emit a
tool_useforcomposio:hubspot_create_contact. - Validate the args against the compiled Ajv schema. Invalid args become a synthetic
is_errortool result and never hit the upstream server. - Pause and write an
Approvalrow because the policy issingle_approval. Approve from/approvals. - Dispatch the call. The MCP server's response is written into the conversation as a
tool_result; the model continues with the new context. - A row lands in the audit chain at each step (
agent.tool_use,approval.opened,approval.resolved,agent.tool_result).
6. Disable or remove
PATCH /api/mcp-servers/mcp_07
{ "active": false }
DELETE /api/mcp-servers/mcp_07Disabled servers stop accepting new calls but keep their audit history; deleted servers are removed but the audit rows referencing them remain (and are still HMAC-verifiable).
Full conceptual background: Concepts — MCP tools & approvals, ADR-001 — Self-hosted runtime + MCP.