The URL
POST https://app.hiambrose.com/api/team/<slug-or-webhook_id>/mcp
Streamable HTTP MCP — the modern wire format. Works with any MCP client that supports HTTP transport.
What the client sees — the full tool surface
The endpoint does not expose just one tool. A tools/list call returns everything this team is wired to, so the connecting client (Claude, Cursor, VAPI, your SDK) can use the team's tools directly — not just delegate to the whole team. You get:
- The team meta-tool —
ask_<slug>. Hand the whole job to the team's reasoning:ask_lead_qualifier({ input: "qualify contact xyz789" }). - One tool per spoke action — every tool of every spoke attached to the team, named
<spoke>__<tool>. E.g.ghl__ghl_contact_search,agent_vault__vault_list,plan_quoter__ichra_savings. The real tool names + schemas come live from each spoke, so they always match what the spoke can actually do. - The Brain meta-tools — when the team has
brain(or a scopedbrain:<source>) enabled:brain_catalog,brain_tool_schema,brain_executefor the federated .gov/healthcare data. - Attached skills — one
skill__<slug>tool per skill the team has, which runs that SKILL.md playbook through the team. - Attached external MCPs — tools from any user-installed MCP the team has, re-exposed as
mcpext__<slug>__<tool>. - Introspection + management —
ambrose_get_info,ambrose_list_files,ambrose_read_file,ambrose_list_tools,ambrose_list_sequences,ambrose_create_sequence,ambrose_get_logs,ambrose_agency_info.
{
"name": "ask_lead_qualifier",
"description": "Run the Lead Qualifier team. Qualify a GHL contact as HOT/WARM/COLD/REJECT.",
"input_schema": {
"type": "object",
"properties": { "input": { "type": "string", "description": "Natural-language instruction for the team." } },
"required": ["input"]
}
}
webhook_id — never from the client. So agent_vault__vault_list over a team MCP reads that agency's vault and nothing else; spoke credentials, attached MCPs, and skills are all the owning agency's. A client can't read another tenant's data by passing a different agency id.Vault + spoke tools actually work over MCP
Because the endpoint publishes the live tool list, a connected client can read the agency's vault, query GHL, run quotes, hit the Brain, and so on — directly:
// list the agency's private vault (book of business) over the team MCP
callTool({ name: "agent_vault__vault_list", arguments: {} })
// search it
callTool({ name: "agent_vault__vault_search", arguments: { query: "Blue Cross enrollment" } })
// move a contact's opportunity in GHL
callTool({ name: "ghl__ghl_opportunity_move_stage", arguments: { /* … */ } })
The agency id is injected server-side for spokes that need it (the vaults), so you never pass it — and can't override it.
Manage agency skills over MCP
If the team has the admin-ops capability enabled, the endpoint also exposes ambrose_skill_create, ambrose_skill_update, ambrose_skill_list, and ambrose_skill_delete. These let a connected client (e.g. Claude) create and update your agency's skills directly — and they apply immediately (no staged-confirm step). They only ever touch your agency's own skills, never the shared system/default skills or another agency's. If admin-ops isn't enabled on the team, these tools don't appear.
callTool({ name: "ambrose_skill_create", arguments: {
slug: "objection-handling",
name: "Objection Handling",
description: "How we answer the top 5 ACA objections",
body: "When a prospect says it's too expensive, ..."
}})
Example 1 — Mount in Claude Desktop
// ~/.claude/mcp_settings.json
{
"mcpServers": {
"ambrose-leadqualifier": {
"type": "http",
"url": "https://app.hiambrose.com/api/team/leadqualifier/mcp",
"headers": { "Authorization": "Bearer <token>" }
}
}
}
Restart Claude Desktop. The team appears as a tool. You can then ask Claude "qualify contact xyz789" and it will call the team.
Example 2 — Mount in Cursor
Settings → MCP → Add → Add by URL. Paste the team URL + bearer token. Save. The team's tools appear in the cmd-shift-K composer.
Example 3 — Mount on VAPI as native MCP
VAPI's MCP tab → Add MCP server → paste the team URL + token. The team's tool is now callable mid-call by VAPI's voice agent.
Example 4 — From your own code (TypeScript)
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
const transport = new StreamableHTTPClientTransport(
new URL('https://app.hiambrose.com/api/team/leadqualifier/mcp'),
{ requestInit: { headers: { Authorization: 'Bearer ' + token } } }
);
const client = new Client({ name: 'my-client', version: '1.0.0' }, {});
await client.connect(transport);
const result = await client.callTool({
name: 'ask_lead_qualifier',
arguments: { input: 'Qualify contact xyz789 and recommend a tier.' }
});
console.log(result);
Example 5 — From Python (anthropic SDK)
from anthropic import Anthropic
client = Anthropic()
resp = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
mcp_servers=[
{
"type": "url",
"url": "https://app.hiambrose.com/api/team/leadqualifier/mcp",
"name": "ambrose-leadqualifier",
"authorization_token": TOKEN,
}
],
messages=[{"role": "user", "content": "Qualify contact xyz789"}],
)
Auth
- Open by default — pass no header and it works (rate-limited per IP).
- For production, generate a consumer token on the team detail page and require
Authorization: Bearer <token>.
Schemas you can hand-write
If the auto-generated schema is too loose, drop a tools.json next to the team prompt:
{
"input_schema": {
"type": "object",
"properties": {
"contact_id": { "type": "string" },
"instruction": { "type": "string" }
},
"required": ["contact_id"]
}
}
The MCP handshake will use yours instead. This is how you get crisp tool descriptions in the calling LLM's catalog.
HIPAA
MCP calls go through the same PHI Rail as any other team run. PHI mode is set per-call via the phi_mode tool argument when present, otherwise it defaults to Fast (scrub).
Tool-count limits
Calling LLMs cap their tool catalog (Claude: 40 tools per request). If a team has too many sub-tools, the MCP endpoint returns the top-priority 40 and logs the truncation in the team's logs.