Atlas MCP Server
Connect an MCP client to Atlas over Streamable HTTP. Every call needs a delegated Atlas Bearer token and is scoped to that token's organisation. Writes always go through a proposal that a person confirms.
Release status
Ready on staging. MCP profile 1.1 serves 11 governed tools: 3 customer reads, 2 cited knowledge searches, and 6 propose, confirm, reject tools for tasks and customer profiles.
This page does not claim a production release. Configure clients against atlas.staging.forth.ai.
Endpoints
| Environment | URL |
|---|---|
| Staging | https://atlas.staging.forth.ai/assistant/v1/mcp |
| Production (not verified) | https://atlas.forth.ai/assistant/v1/mcp |
Transport: HTTP POST only, JSON responses, no sessions. Supported protocol revisions: 2025-11-25 and 2025-06-18. Any client that supports Streamable HTTP with custom headers works.
Authentication
Send Authorization: Bearer <token> on every request. Without it the server answers 401 authentication_required.
Mint a token
- Sign in to the portal at
https://atlas.staging.forth.ai. - Open the browser developer console and run:
fetch("/auth/tokens", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ name: "mcp-client", scopes: ["crm:read", "crm:write"], lifetimeDays: 7 }) }).then(r => r.json()).then(console.log)
- Copy
tokenfrom the response. It is shown once.
lifetimeDays defaults to 7 and is capped at 30. Admins can revoke a token at any time. Include only the scopes the client needs.
Scopes
| Scope | Unlocks |
|---|---|
crm:read | crm_customer_profile_read, crm_customer_profile_suggestions_list, crm_customers_search |
ekb:read | ekb_knowledge_retrieve, ekb_library_search |
tasks:write | tasks_profile_gap_task_create_propose, _confirm, _reject |
crm:write | crm_customer_profile_create_propose, _confirm, _reject |
tasks:read | Task tracking data. No MCP tool requires it today. |
Client setup
Claude Code
claude mcp add --transport http atlas https://atlas.staging.forth.ai/assistant/v1/mcp --header "Authorization: Bearer <your-token>"
Verified with Claude Code CLI 2.1.260. Run claude mcp list to confirm the server connects.
Any Streamable HTTP client
{
"mcpServers": {
"atlas": {
"url": "https://atlas.staging.forth.ai/assistant/v1/mcp",
"headers": {
"Authorization": "Bearer <your-token>"
}
}
}
}
Tool reference
Required inputs are in bold. Reads return data directly. Propose tools return a proposal_id and create nothing.
| Tool | Returns | Inputs | Scope |
|---|---|---|---|
crm_customer_profile_read | One customer's profile level, confirmed facts, cited evidence, missing requirements. | customer_id | crm:read |
crm_customer_profile_suggestions_list | Profile-gap suggestions for one customer, each with its reason. | customer_id | crm:read |
crm_customers_search | Customers whose name, contact, or email matches. | q, limit | crm:read |
ekb_knowledge_retrieve | Ranked, cited passages from active organisation knowledge. | query, limit, type, source_id | ekb:read |
ekb_library_search | Ranked, cited snippets from confirmed Knowledge Library documents. | query, limit | ekb:read |
tasks_profile_gap_task_create_propose | Proposal for a profile-gap task. | customer_id, profile_gap_code, title, idempotency_key, due_at, assignee_email, suggestion_id | tasks:write |
tasks_profile_gap_task_create_confirm | Creates the task from the proposal. | proposal_id, idempotency_key | tasks:write |
tasks_profile_gap_task_create_reject | Closes the proposal without creating a task. | proposal_id, idempotency_key | tasks:write |
crm_customer_profile_create_propose | Proposal for a new customer profile. | name, idempotency_key, contact, email, country, industry, customer_type | crm:write |
crm_customer_profile_create_confirm | Creates the customer from the proposal. | proposal_id, idempotency_key | crm:write |
crm_customer_profile_create_reject | Closes the proposal without creating a customer. | proposal_id, idempotency_key | crm:write |
Full input schemas come from tools/list. Call it once after connecting rather than hard-coding the table above.
Consequential changes stay two-step
- Call
*_create_proposewith anidempotency_keyyou choose. The result carriesproposal_id, a summary, andexpires_at. - Show the summary to the person deciding. Do not confirm on their behalf.
- Call
*_create_confirmor*_create_rejectwith thatproposal_idand a newidempotency_key. - Repeating a confirm with the same key returns the original result with
meta.repeated: trueand no second effect.
Proposals expire 15 minutes after creation. Confirming an expired or rejected proposal returns conflict; propose again.
Troubleshooting
| Symptom | Fix |
|---|---|
HTTP 401 authentication_required | Token missing, expired, or revoked. Mint a new one and update the client header. |
Status forbidden, error insufficient_scope | Mint a token that includes the scope named in the error. |
Status conflict on confirm | Proposal expired or was rejected, or the idempotency key was reused with different input. Propose again. |
HTTP 400 invalid MCP-Protocol-Version | Use a client that negotiates 2025-11-25 or 2025-06-18. |
HTTP 405 | The client sent GET or DELETE. The endpoint is POST only; disable SSE or session features. |
Tool missing from tools/list | Compare against the table above. A missing tool means the client is pointed at an older environment. |