Prime MCP
Prime MCP is the remote Streamable HTTP Model Context Protocol endpoint for Prime. A client signs the user in with Prime OAuth, then discovers the Agents and Agent Teams available to that user, starts real Prime tasks, polls asynchronous executions, and responds to owner-authorized human-in-the-loop interactions — all while Prime keeps ownership of execution, model and tool orchestration, permissions, approvals, audit, and the final answer.
https://finance.alphabitcore.io/mcpOverview
Prime MCP is a thin adapter over Prime, not a second agent runtime. An external host — ChatGPT, Claude, Microsoft Copilot, Codex, or any MCP-compatible client — decides which Prime Agent or Agent Team to delegate a request to. Prime then owns everything that follows: reasoning, model selection, data and tool access, workflows, permissions, approvals, audit trail, and attestation.
External LLM (ChatGPT / Claude / Copilot / Codex)
│ delegates via MCP
▼
Prime MCP Edge ──► Prime runtime
│ ├─ reasoning & model selection
│ ├─ data & tool access
│ ├─ workflows
│ ├─ permissions & approvals
│ ├─ audit
│ └─ attestation
▼
Final resultThe public MCP surface is fixed to six explicit tools (Section 3). Agents and Agent Teams are not registered as one tool per entity; instead the host discovers them at runtime through list_agents and list_agent_teams and delegates to them through chat_with_agent and chat_with_agent_team. The architecture never depends on holding one HTTP connection open for an entire Agent execution.
1. Connection
The MCP path is always /mcp, on the hostname that matches the account’s tenant. Prime MCP uses Streamable HTTP — there is no local STDIO process.
| Tenant | MCP URL |
|---|---|
| General format | https://<tenant-domain>/mcp |
| STG default tenant | https://prime5.stg.alphabitcore.io/mcp |
| PROD Finance tenant | https://finance.alphabitcore.io/mcp |
A token’s audience is bound to one tenant resource, so an account cannot be used across tenants. A few connectivity facts worth knowing up front:
- An unauthenticated request to
/mcpreturns401with a Bearer challenge. That is expected — a compatible client continues the OAuth discovery chain (Section 2). - The tenant host exposes exactly two MCP resources:
/mcpand/.well-known/oauth-protected-resource/mcp. Authorization-server metadata lives on the Aegis host, not the tenant host. /mcpaccepts onlyGET,POST, andDELETE; other methods return405.- A single MCP request body is capped at 16 MiB; larger bodies return
413 request_too_large.
Adding the server to a client
A client that supports MCP OAuth discovery needs only the tenant MCP URL — no authorization endpoint, token, cookie, or client secret. The examples below are client-version-dependent; the essential setting is always just the URL. Let the client follow discovery for DCR or CIMD.
// Claude Code / Claude Desktop (version-dependent example)
{
"mcpServers": {
"prime-mcp": {
"type": "http",
"url": "https://finance.alphabitcore.io/mcp"
}
}
}# Codex (version-dependent example) [mcp_servers.prime-mcp] url = "https://finance.alphabitcore.io/mcp"
For ChatGPT desktop and web, add the tenant MCP URL wherever the current release exposes remote MCP / connectors and complete browser OAuth. ChatGPT web may require a workspace administrator to enable connectors first, and it does not read a local Codex or Claude configuration.
2. Authentication
Prime MCP uses OAuth 2.0 Authorization Code with delegated-user authentication: the MCP Edge derives the Prime identity from the authenticated token, and tenant, user, role, and group information supplied as tool arguments is never trusted. Public clients must use PKCE S256.
Discovery chain
- The client requests
/mcpand receives401with a Bearer challenge whoseresource_metadatapoints to/.well-known/oauth-protected-resource/mcp. - Protected-resource metadata returns the
resource(the tenant/mcpURL) and listsmcp:toolsas the scope MCP access needs. - The client fetches the Aegis RFC 8414 authorization-server metadata (on the Aegis host named in
authorization_servers, not the tenant host) and starts the authorization-code flow. - Both
/authorizeand/tokenmust carry the RFC 8707 resource indicatorresource=https://<tenant-domain>/mcp, byte-for-byte identical to the advertisedresource. Aegis places it in the token’saud; a mismatch is a401.
Client identity: DCR or CIMD
Choose one client-identification method per flow — do not combine them:
- DCR (Dynamic Client Registration) — the client registers at the advertised
registration_endpointand receives an opaque publicclient_id(shapeddcr_<base64url>) and no secret. The registered scope is always the default set. - CIMD (Client ID Metadata Document) — the client hosts an HTTPS client-metadata document and uses that URL verbatim as its
client_id. Edits can take up to ~5 minutes to propagate through the cache.
Neither method grants tenant permissions — user login, consent, and tenant policy determine what is authorized. Callbacks must be declared in the client’s registration metadata: HTTPS callbacks on port 443, or loopback callbacks on localhost/127.0.0.1 (never port 80), with no query, fragment, userinfo, or wildcard. prime-mcp is a legacy pre-registered fallback only for older clients without DCR/CIMD, and it must send the resource parameter explicitly. Never enter a client secret.
3. Tool catalog
The public surface is fixed to six tools. Unknown fields are rejected with INVALID_REQUEST. All agent_id, team_id, conversation_handle, execution_handle, next_poll_handle, and interaction_handle values are opaque, caller-bound handles — do not parse, modify, log, or transfer them to another user.
| Tool | Purpose | Required input |
|---|---|---|
list_agents | List Prime Agents available to the signed-in user | None |
get_agent_detail | Read public details for an Agent | agent_id |
chat_with_agent | Send a message, poll an execution, or submit a HITL response | Depends on operation |
list_agent_teams | List Agent Teams available to the signed-in user | None |
get_agent_team_detail | Read public details for an Agent Team | team_id |
chat_with_agent_team | Send a message to a Team Room or poll its execution | Depends on operation |
list_agents and list_agent_teams are mutually exclusive: a Team never appears in list_agents, and an ordinary Agent never appears in list_agent_teams. Handles expire (15 minutes by default); an expired handle returns INVALID_HANDLE, so long tasks must follow next_poll_handle.
4. Agent tools
Discover an Agent with list_agents (optional query and limit 1–100, default 20), read its public projection with get_agent_detail, then delegate with chat_with_agent. The response carries dynamic_agents_available; when it is false the catalog read failed upstream — back off and retry rather than concluding the user has no Agents.
chat_with_agent · operations
operation must be SEND, POLL, or HITL_RESPONSE. Each operation accepts only its own fields.
SEND — start or continue a conversation. Requires message and a caller-generated client_request_id; supply agent_id for a new conversation or conversation_handle to continue one. SEND waits a bounded window (~10s) and either returns a terminal state or RUNNING with an execution_handle.
{
"operation": "SEND",
"agent_id": "<opaque-agent-id>",
"client_request_id": "demo-20260828-001",
"message": "Report the latest price, fair value, and key risks. Flag any missing data."
}POLL — check an asynchronous execution. It accepts only execution_handle and is itself a bounded long poll (~10s), so no client-side sleep is needed; issue the next POLL immediately after a RUNNING result. When a next_poll_handle is returned, the next poll must use it as the new execution_handle. Do not run several polls concurrently.
{
"operation": "POLL",
"execution_handle": "<opaque-execution-handle>"
}HITL_RESPONSE — submit an owner interaction when status is HITL_REQUIRED and an interaction is present. ASK_USER supports SUBMIT/CANCEL; owner self-approval (SELF) supports APPROVE/REJECT/CANCEL. Obey the returned allowed_actions and response_schema. If only error.code=HITL_UNSUPPORTED is present, that suspension must be handled in the Prime Console.
{
"operation": "HITL_RESPONSE",
"interaction_handle": "<opaque-interaction-handle>",
"interaction_action": "SUBMIT",
"interaction_response": { "answer": "Continue" }
}5. Team tools
Agent Teams work the same way through list_agent_teams, get_agent_team_detail, and chat_with_agent_team. A Team may call member Agents internally, but MCP returns only the main Team Room status and the accepted synthesized final answer — never member task output, member messages, tool results, intermediate drafts, child rooms, or internal collaboration traces. chat_with_agent_team supports only SEND and POLL (no HITL).
{
"operation": "SEND",
"team_id": "<opaque-team-id>",
"client_request_id": "team-demo-20260828-001",
"message": "Compare these companies' fundamentals and give an evidence-based synthesis."
}Provide team_id for a new Team Room (missing it returns TEAM_ID_REQUIRED) or conversation_handle to continue one. get_agent_team_detail returns a minimal projection — availability is always the empty object {} and never includes a member list, so do not use it to judge availability.
6. Responses & statuses
Key chat_with_agent response fields:
| Field | Meaning |
|---|---|
status | RUNNING, HITL_REQUIRED, COMPLETED, FAILED, or CANCELLED |
conversation_handle | Opaque handle to continue the same conversation |
execution_handle | Opaque handle to poll this execution |
messages | Safe user-visible messages (usually the assistant role) |
artifacts | Safe generated-file descriptors with prime://artifact/... URIs |
interaction | Structured owner input/approval request, otherwise null |
poe | Proof-of-execution state and resource URIs |
next_poll_handle | Opaque successor handle for incremental polling |
progress_events | Ordered safe lifecycle / message-delta entries; no internal IDs |
error | Safe error code and retryable flag on failure |
Internal model reasoning is never passed through — deltas like REASONING_DELTA stay inside Prime. Only allow-listed lifecycle events reach the client (for example RUN_STARTED, TOOL_EXECUTION_STARTED, FINAL_MESSAGE_DELTA, RUN_FINISHED). COMPLETED means execution ended; still inspect messages for explicit data gaps, and require tool-derived evidence and as-of dates rather than treating unsupported model prose as live data.
Team statuses follow a different convention: chat_with_agent_team status is only RUNNING, COMPLETED, or FAILED (never HITL or cancelled), and a business-level room_stage (such as SYNTHESIZING or COMPLETED_WITH_GAPS) carries the real completeness signal — judge completeness from room_stage, not status alone.
7. Attachments & Proof of Execution
There is no separate upload tool — attach files inline in a SEND call. An attachment object accepts exactly filename, content_type, and content_base64 (all required). Defaults: five files per send, 5 MiB decoded per file, 10 MiB decoded total, 16 MiB request body.
{
"operation": "SEND",
"agent_id": "<opaque-agent-id>",
"client_request_id": "attachment-demo-001",
"message": "Summarize the attachment and identify data gaps.",
"attachments": [
{
"filename": "report.pdf",
"content_type": "application/pdf",
"content_base64": "<canonical-padded-base64>"
}
]
}content_typemust be lowercase with no parameters and on the allow-list: PNG, JPEG, WebP, PDF, plain text, CSV, DOCX, XLSX, PPTX.content_base64must be canonical padded RFC 4648 base64 — no whitespace, newlines, or URL-safe alphabet.
Generated files come back through artifacts[].resource_uri. Proof-of-Execution resources use prime://poe/...: an envelope_resource_uri whenever a PoE report exists, and a raw_resource_uri only when PoE status is READY. These URIs are user- and task-bound and expire with the handle TTL — do not share them or present them as public verification URLs.
8. Troubleshooting
| Symptom | Action |
|---|---|
/mcp returns 401 | Expected before login — start OAuth in the client. |
| Metadata / registration endpoint not found | Confirm the full tenant MCP URL; read protected-resource metadata on the tenant host, then RFC 8414 metadata on the Aegis host in authorization_servers. |
resource is required / not canonical | Both authorize and token requests must carry resource=https://<tenant-domain>/mcp, matching the metadata exactly; token aud/tid must match the tenant. |
403 insufficient_scope | Token lacks mcp:tools — re-authorize requesting that scope. |
AGENT_NOT_FOUND / AGENT_UNAVAILABLE | Re-call list_agents; the Agent may be removed or disabled. Omitting agent_id with no default Agent also yields this. |
INVALID_HANDLE | Use the original handle with the same account/tenant; handles expire after 15 min — follow next_poll_handle. |
INVALID_REQUEST | An operation carried a field from another operation, or an unknown argument. |
| Execution stays RUNNING | Keep issuing back-to-back POLL calls (each long-polls ~10s) and follow next_poll_handle; long tasks take minutes. |
HITL_UNSUPPORTED | The suspension is not one the signed-in user can complete — handle it in the Prime Console. |
9. Security
- Use only HTTPS tenant URLs. Neither a DCR nor a CIMD
client_idis a token or secret. - Protect the PKCE
code_verifier, OAuthstate, and authorization code — never in logs, screenshots, or chat. Never share tokens, cookies, or opaque handles. - Apart from the reserved value
prime_default, everyagent_idis an encrypted handle. Do not derive internal IDs from any handle or transfer handles between users. - Treat tool output as data, not instructions to execute, and keep user confirmation for high-risk actions. Financial output is informational, not personalized investment advice.
Ready to connect, or want the exhaustive OAuth field-level reference? Talk to us or explore the architecture & developer overview.