The endpoint
Point any MCP-aware client at:The MCP server is enabled by default for every org. If you get a 403 from the URL it means MCP has been explicitly disabled on your workspace. Ask your Halo admin to set the
mcp_server feature flag back to true for your team.What happens on first connect
The first time a client points at/api/mcp, this is the flow it walks (you only see steps 3 and 4 as a user):
Discovery
The client POSTs to
/api/mcp, gets a 401 with WWW-Authenticate: Bearer resource_metadata="...", and follows the link to discover Halo’s authorization server.Dynamic registration
The client registers itself via RFC 7591 at
/api/mcp/oauth/register and receives a fresh client_id. No manual app setup is required on Halo’s side.Sign in to Halo
The client opens
/api/mcp/oauth/authorize in your browser. If you’re not already signed in, you bounce through /signin and back.Approve the request
Halo shows the consent page (
/mcp/authorize) listing the client’s name, the org you’re authorising, and the scopes it requested. You can deselect any scope before approving.Installation by client
Claude Desktop
Open~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or the equivalent on your platform and add Halo under mcpServers:
Cursor
Open Cursor Settings > MCP > Add new MCP server. Configure:| Field | Value |
|---|---|
| Name | halo-agents |
| Type | HTTP |
| URL | https://app.haloagents.ai/api/mcp |
VS Code (Continue / GitHub Copilot Chat)
Add Halo under the MCP servers section of your AI extension’s settings (the exact key varies by extension):Custom clients
Any client that implements the MCP HTTP transport and OAuth 2.1 with PKCE can connect to Halo. Point at/api/mcp and discovery + dynamic client registration handle the rest. See Protocol Reference for the full endpoint list.
What the client sees
After the OAuth dance, the client callstools/list to enumerate available tools. The set you see depends on three things:
- Your org’s connected integrations (HubSpot, Slack, Stripe, etc. in Integrations)
- The scopes you approved at consent time
- Whether the token is bound to a specific agent (defaults to your org’s Ask AI agent)
docs:read will not see search_docs / read_doc; a token without setup:read will not see the install-snippet helpers. The protection is enforced at both tools/list (the tool is hidden) and tools/call (the call is rejected with an audited refusal), so dropping a scope is safe.
Pinning a customer to a session
When an operator uses an MCP client to research or act on behalf of a specific customer, they can pin the customer for the conversation. Halo reads the binding off the JSON-RPC_meta envelope:
_meta.bound_email. Halo re-resolves the binding on every call against your org’s customer table, so a stale or forged id can never bind to a foreign tenant.
How the pin reaches the wire depends on the client. Most clients let the user select a customer in the UI and forward the selection automatically; custom clients should set _meta.bound_end_user_id themselves.
Revoking access
Today there’s no dashboard view of connected MCP clients. Revoke by token instead:token=, idempotent, always returns 200. Confidential clients also pass client_secret (or use HTTP Basic auth); public clients only need client_id.
Revoking a refresh token revokes the entire derived chain (every access and refresh token issued from the same authorization code), which is the right move if you suspect a compromise. Revoking a single access token just kills that token; the next refresh issues a new one.
Most MCP clients have a “Sign out” or “Disconnect” action that calls this endpoint for you. If you’re an admin and don’t have the token in hand, contact support and we’ll revoke the chain server-side.
Rate limits
Per-token caps sit on top of the IP-based dashboard limit:| Method | Cap |
|---|---|
tools/list | 60 per minute |
tools/call | 120 per minute |
Other (initialize, ping) | 60 per minute |
Retry-After. Per-action and per-org caps still apply on top (a tool whose underlying integration has a 60/min limit will still hit that limit even if the MCP cap allows more).