Atlas MCP Server
Personal Assistant identities: inspect {"view":"assistants"} using agent.team.inspect / agent_team_inspect. Create or update via agent.team.change with operation: assistant.create or assistant.update, identity: {name, avatarKey}, and for updates assistantId plus revision. Avatar keys are human-01 through human-08. Use the existing proposal and explicit confirmation flow with idempotency keys; CLI: atlas assistants inspect/propose/confirm. The permanent Head label is Head Assistant / 总助理; its ID head is metadata, never a thread ID. Identities and their proposals are owner-only; beta access must be verified. Custom chat uses its separate verified private-conversation capability. Creating identity metadata makes no hire, model call or new permission.
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.
First result: connect and read a customer
Before you begin: a Streamable HTTP client with custom headers, a staging account, and a delegated token with crm:read. The token belongs to one organisation; keep it out of shared configuration and conversations.
- Follow authentication to obtain a token and client setup to configure the staging endpoint and Bearer header.
- Connect and inspect the tool list. Call
crm_customers_searchwith{"q":"Acme","limit":5}, replacing Acme with an accessible customer name. - Read the structured result. Take the customer’s
idfromdata.itemsand callcrm_customer_profile_readwith{"customer_id":"<returned-id>"}to inspect the profile.
Expected result: A successful search returns completed and a list of matches; an empty list is valid. These reads do not create customers.
For no matches, check the name and the token’s organisation. Use troubleshooting for connection, scope or protocol errors. For later writes, follow propose, confirm or reject.
Release status
Ready on staging. MCP profile 1.14 serves 139 governed tools: the prior profile 1.13 surface plus the company-milestone sharing prepare (crm_engagement_milestone_sharing_prepare_propose, _confirm, _reject) — the on-demand prepare of one company-milestone sharing draft from an F08-attested knowledge claim: the claim must currently resolve as confirmed and permitted for this customer in the active source version and pair with confirmed customer-fit evidence; a missing approval or fit evidence is named and no proposal exists (#2126).
Ready on staging. MCP profile 1.12 serves 133 governed tools: the prior profile 1.10 surface plus the after-sales report prepare (crm_engagement_after_sales_report_prepare_propose, _confirm, _reject) — the on-demand prepare of one sourced after-sales survey report from the customer's recorded survey/feedback evidence, where every knowledge claim's exact locator must currently resolve as confirmed and customer-shareable through the source-use gate; response counts ride per source only where the source supplies one, and missing months are stated as partial coverage (#2115).
Ready on staging. MCP profile 1.12 serves 133 governed tools: the prior surface plus the confirmed order-delivery follow-up (#2110 — the reads crm_engagement_order_delivery_list and crm_engagement_order_delivery_read and the confirmed-observation effect crm_engagement_order_delivery_confirm_propose, _confirm, _reject; evidence only, never fulfilment) and the customer inventory and sales check-in (#2113 — the read crm_engagement_inventory_sales_checkin_read, one customer's recorded observations newest-first with three distinct measures where missing stays null and zero is a value; the on-demand request prepare crm_engagement_inventory_sales_checkin_prepare_propose, _confirm, _reject, one product-specific update request per customer per month keyed checkin:<customer_id>:<YYYY-MM>; and the confirmed-figures record crm_engagement_inventory_sales_checkin_record_propose, _confirm, _reject, a versioned append-only observation where the product must resolve inside this customer's records and no forecast, purchase order or external stock record is ever written). and the per-sample test follow-up (#2108 — the read crm_engagement_sample_test_read, listing one customer's sample-test cases with their latest confirmed result or reading one case with its full observation history, and the confirmed-result effect crm_engagement_sample_test_confirm_propose, _confirm, _reject — a final pass/fail stops only that sample's follow-up) and the confirmed tender brief (crm_engagement_tender_brief_read and the crm_engagement_tender_brief_create/update/delete propose-confirm-reject effects) — one rep-confirmed brief per customer tender: reference, title, deadline (epoch ms plus its IANA zone) and 1-12 confirmed requirements, every requirement citing 1-5 current, resolvable confirmed EvidenceRefs (owner:kind/id@version); an update appends a revision the prior basis pins, and nothing here creates a quotation, sample, price, bid document or submission (#2123) Plus the next-year cooperation-plan prepare (#2116 — crm_engagement_cooperation_plan_prepare_propose, _confirm, _reject): the on-demand prepare of one next-calendar-year cooperation plan draft from the year's verified annual cooperation evidence plus explicitly confirmed customer goal facts — a labelled suggestion (建议稿) that never reads as a quotation, order or budget commitment, with an empty evidence year or an unresolvable goal named. Plus the quotation result follow-up and confirmation (#2107 — the read crm_engagement_quotation_result_read, listing one customer's unresolved quotations with their latest confirmed result note or reading one quotation with its full note history, and the confirmed recording effect crm_engagement_quotation_result_confirm_propose, _confirm, _reject — the customer's confirmed answer accepted/rejected/changes_requested/undecided for one exact revision; accepted/rejected invoke the existing guarded lifecycle and return its canonical state and require at least one sourced evidence reference, changes_requested links the existing revision action without creating anything, feedback is stored as versioned CRM notes never a parallel status table, and nothing here alters terms, submits a quote or creates an order). Plus the sample selection follow-up and results (#2109 — the read crm_engagement_sample_selection_read, listing one customer's sample-selection cases with their latest confirmed selection result or reading one case with its full observation history, and the confirmed-result triple crm_engagement_sample_selection_confirm_propose, _confirm, _reject — selected, not_selected or pending for one sample on the same sample identity, stored and followed up separately from the test result, with the selected and rejected product refs and reasons or the explicit not-provided marker; product refs must resolve inside this customer's records, and a final result stops only that sample's selection follow-up). Plus the shipment progress follow-up (#2112 — the read crm_engagement_order_shipment_read, listing one customer's shipment cases under their A09 order identities with the latest confirmed progress and its as-of time, or reading one case with its full observation history, and the confirmed-observation triple crm_engagement_order_shipment_confirm_propose, _confirm, _reject — in_transit, exception or delivered for one shipment, with the carrier and tracking reference or an explicit unknown and the observed time; missing details stay unknown, a delivered status stops only that shipment's follow-up, the order-delivery commitment is never resolved, and no carrier is ever queried). Plus the customer platform sales review (#2114 — the read crm_engagement_platform_sales_read, listing one customer's recorded platform-sales observations newest-first with each measure's reported/estimated/missing classification and its evidence, the reused A11 check-in evidence resolved once each and the like-for-like comparison groups; the on-demand review prepare crm_engagement_platform_sales_prepare_propose, _confirm, _reject, one cited review/update-request draft per customer per month keyed psales:<customer_id>:<YYYY-MM>; and the classified record crm_engagement_platform_sales_record_propose, _confirm, _reject, a versioned append-only observation where a reported value cites its source, an estimate names its method and evidence, a missing states its reason — labels never merge, a withdrawn source refuses, and no external platform is ever scraped, queried or published to) The tender-specific product promotion (#2124 — crm_engagement_tender_product_promotion_prepare_propose, _confirm, _reject) prepares, from one current confirmed tender brief, a customer product-promotion draft whose claims map confirmed requirements to the approved tailored product evidence — supported claims only, unsupported requirements named; communication only, never a bid submission...
This page does not claim a production release. Configure clients against atlas.staging.forth.ai.
Ready on staging. MCP profile 1.13 serves 136 governed tools: the profile 1.12 surface plus the Pre-sale Assistant's quotation draft (#2742 — crm_engagement_quotation_draft_prepare_propose, crm_engagement_quotation_draft_prepare_confirm, crm_engagement_quotation_draft_prepare_reject). Confirming creates exactly one quotation in status draft on an open deal of the named customer, with one unpriced line per approved product-evidence entry: the agent never sets a price, never marks a quotation sent, and there is no send tool for it on any surface. A person prices the draft and decides.
Ready on staging. Beyond this pinned governed-tools count, tools/list now also returns the calling organisation's own classified external tools (#2747, #2774) — never another organisation's, and never counted in the sentence above, which names only the tools every organisation gets. See "Organisation-scoped external tools" below.
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, crm_engagement_context_read, crm_engagement_receivable_list, crm_engagement_receivable_read, crm_engagement_order_delivery_list, crm_engagement_order_delivery_read, crm_engagement_annual_evidence_read, crm_engagement_drafts_read, crm_engagement_dispatches_read, crm_engagement_exhibition_context_read, crm_engagement_tender_brief_read, crm_engagement_schedules_read, crm_engagement_preparation_read, crm_engagement_inventory_sales_checkin_read, crm_engagement_sample_test_read, crm_engagement_quotation_result_read, crm_engagement_sample_selection_read |
ekb:read | ekb_knowledge_retrieve, ekb_library_search, ekb_library_passages_read, ekb_source_use_read, ekb_releases_list, ekb_releases_read, ekb_product_evidence_selection_read |
ekb:write | ekb_source_use_change_propose, _confirm, _reject; ekb_product_evidence_selection_create/update/delete_propose each with _confirm, _reject |
tasks:write | tasks_profile_gap_task_create_propose, _confirm, _reject; tasks_engagement_followup_create_propose, _confirm, _reject |
crm:write | crm_customer_profile_create_propose, _confirm, _reject; crm_engagement_receivable_confirm_propose, _confirm, _reject; crm_engagement_order_delivery_confirm_propose, _confirm, _reject; crm_engagement_drafts_change_propose, _confirm, _reject; crm_engagement_drafts_send_propose, _confirm, _reject; crm_engagement_exhibition_context_create/update/delete_propose, _confirm, _reject; crm_engagement_schedules_change_propose, _confirm, _reject; crm_engagement_preparation_retry_propose, _confirm, _reject; crm_engagement_tailored_solution_prepare_propose, _confirm, _reject; crm_engagement_exhibition_invitation_prepare_propose, _confirm, _reject; crm_engagement_new_product_promotion_prepare_propose, _confirm, _reject; crm_engagement_after_sales_report_prepare_propose, _confirm, _reject; crm_engagement_milestone_sharing_prepare_propose, _confirm, _reject |
crm:write | crm_customer_profile_create_propose, _confirm, _reject; crm_engagement_receivable_confirm_propose, _confirm, _reject; crm_engagement_order_delivery_confirm_propose, _confirm, _reject; crm_engagement_drafts_change_propose, _confirm, _reject; crm_engagement_drafts_send_propose, _confirm, _reject; crm_engagement_exhibition_context_create/update/delete_propose, _confirm, _reject; crm_engagement_schedules_change_propose, _confirm, _reject; crm_engagement_preparation_retry_propose, _confirm, _reject; crm_engagement_tailored_solution_prepare_propose, _confirm, _reject; crm_engagement_exhibition_invitation_prepare_propose, _confirm, _reject; crm_engagement_new_product_promotion_prepare_propose, _confirm, _reject; crm_engagement_inventory_sales_checkin_prepare_propose, _confirm, _reject; crm_engagement_inventory_sales_checkin_record_propose, _confirm, _reject; crm_engagement_sample_test_confirm_propose, _confirm, _reject; crm_engagement_cooperation_plan_prepare_propose, _confirm, _reject; crm_engagement_quotation_result_confirm_propose, _confirm, _reject; crm_engagement_sample_selection_confirm_propose, _confirm, _reject |
tasks:read | Task tracking data. No MCP tool requires it today. |
Client setup
Claude Code plugin (recommended)
The atlas-crm plugin wraps sign-in, token minting, and MCP registration into one command — no dev console, no copying a token by hand.
/plugin marketplace add Forth-AI/atlas-crm-plugin
/plugin install atlas-crm@atlas-crm-plugin
/atlas-crm:login
/atlas-crm:login asks for your Atlas email, sends a one-time code, mints a 30-day delegated token, and registers it as the atlas-crm MCP server at user scope — available in every Claude Code project on the machine, not just one repo. /atlas-crm:status shows the token's name and expiry; /atlas-crm:logout removes the local registration. Source: Forth-AI/atlas-crm-plugin on GitHub.
Staging only for now — the plugin points at atlas.staging.forth.ai and doesn't yet support production or invite-code sign-in.
Claude Code (manual)
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 matching every term across profile, linked-contact, country/industry, classification, or visible-label fields. | q, limit | crm:read |
ekb_knowledge_retrieve | Ranked, cited passages from active organisation knowledge. | query, limit, type, source_id | ekb:read |
ekb_library_search | Cited snippets from confirmed Knowledge Library documents, ranked by hybrid recall (keyword and meaning combined; part numbers such as MC-3200-T match whole). Each item carries a fused score and a locator — page, sheet and range, part or line, plus kind — to cite where the passage sits. | query, limit | ekb:read |
ekb_library_passages_read | Reads what a library search found in full. With passage_index: that passage plus at most one neighbour on each side (at most 6,000 characters). Without it: every passage of the file in order when the file has at most 12,000 extracted characters, otherwise status: "too_large" with passage_count and no text. Each passage carries the same locator as the search. Same visibility as ekb_library_search; another organisation’s file, another member’s personal file, a file that is not ready and an out-of-range index are one not_found. | file_id, passage_index | ekb:read |
ekb_releases_list | List or lexically search current published policy and workflow releases. Results keep the owner's content, citation locators and opaque pagination cursor. | kind, q, limit, cursor | ekb:read |
ekb_releases_read | Read one current release by its EKB release id. Unknown, foreign, withdrawn and superseded ids all return not_found. | release_id | 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 |
agent_team_inspect | Account Manager team, one hire's detail (a hire detail also lists optimizationDrafts: at most one scheduled method-optimization draft per hire per day, content-free run statistics only, pending first), decisions, learning options, or pilot metrics, by view. A detail selected by runId includes usage.byPurpose: ledger-derived attempts, coverage, token totals, provider cost in nanos with its currency, and separate customer credits. Cached and reasoning tokens are subsets. usage.pendingAttempts counts unsettled attempts; usage.incomplete is true for pending, missing or incompatible measurements, including an empty projection with no usage evidence. Unavailable totals stay null. team and detail carry each hire's configuration.permissionLevel. View roles returns the organisation's switch for every catalog role (roleId, enabled, revision, updatedBy, updatedAt); administrators only, refused admin_required otherwise. A hire whose role is switched off carries roleDisabled: true in the team and detail views. View customer takes a customerId and answers the same hire shape narrowed to that one account, for the customer profile's AI team panel; an unreadable, foreign-organisation or hire-free customer all answer {"items":[]}, and an empty customerId is refused invalid_input. View decisions also answers doneByAiTeam: the work an auto-pilot hire confirmed itself (decidedBy starting agent:), newest first. View team also answers runHealth: the caller's visible hires' last seven days as since, runs (started in the window), terminalRuns (the ones that finished), degraded (completed runs carrying reason: "output_degraded"), failed, degradedRate, failedRate, hiresCounted, hiresTruncated and byHire (only the hires that degraded or failed). degradedRate and failedRate are shares of terminalRuns, the runs that finished, not of runs. Trial and evaluation runs are not counted, and neither are runs governance has purged. hiresCounted says how many hires were counted and hiresTruncated is true when the organisation may hold more. The same block, counted over the metrics period, also rides view metrics as runHealth. A rollup only — nothing is paged from it. A run executed on the Account Manager specialist loop (feature team-specialist-loop, STORY-DRAFT-AT-02) also carries identity.tools, the steps it took in order as [{"name","at"}], and its model use under purpose specialist_turn; both are absent on single-call runs. | view, hireId, runId, customerId | crm:read |
agent_team_change_propose | Proposal for a hire, role, configuration, work, or teaching change; creates nothing. | operation, idempotency_key, plus fields the operation needs (candidateId, hireId, configuration, work, teaching, revision, scope, roleSettings). role.enable takes roleSettings only and creates one Sales Assistant per eligible rep. work.undo takes back one action an auto-pilot hire executed by itself, naming the work and its revision: the task it created is cancelled, a draft it saved is discarded, once only (already_undone), never for a human decision (not_auto_executed) and never over a task the world has already moved on from (world_changed). It needs the authority deciding the action would have needed — tasks:write for a task — and is recorded against the person, never the hire. hire.create and hire.configure accept configuration.role for a customer-scoped hire (presale_assistant, customer_success_manager, or omitted for the Account Manager; sales_assistant is refused — it is the portfolio scope's own role), and configuration.permissionLevel (plan_only, co_pilot default, auto_pilot); auto_pilot needs an organisation administrator's session and the proposal evidence lists the role's allowedActionClasses and excludedActionClasses to read before confirming. hire.create and hire.configure also accept configuration.eventTriggers (at most 4 catalog ids; today email.inbound only), and configuration.schedule becomes optional when at least one event is selected: a hire configured with the inbound-email trigger runs once for each inbound email that becomes linked to a customer in its scope (its own account, its assigned rep's portfolio, or the whole organisation for the Business Analyst), and a configuration carrying neither a schedule nor events is refused. An event-started run is labelled event in run history, and the same email never starts a second run. role.configure takes roleAvailability only (roleId, enabled, revision) and switches one catalog role on or off for the whole organisation — roleId is one of account_manager, sales_assistant, presale_assistant, customer_success_manager, business_analyst; administrators only, and a revision other than the stored one is refused stale_revision. hire.create, hire.configure and role.enable for a switched-off role are refused 409 role_disabled at propose and at confirm, writing nothing. One account carries a whole AI team but at most one non-retired hire of each role: hire.create for a role a non-retired hire already holds on that customer is refused 409 role_already_assigned, with existing_hire_id and existing_role on the envelope error naming that hire and nothing written; a different role on the same account is an independent hire. hire.create and hire.configure also hire the Business Analyst for the whole organisation: the configuration then carries assignmentScope {"kind":"organisation","roleId":"business_analyst"} with the reserved customerId organisation:business_analyst, an empty knowledge list, and permissionLevel plan_only or co_pilot — auto_pilot is refused for this role in v1, an attached document is refused, and the scope key must match the role. Administrators only (admin_required); a second analyst while one is not retired is refused role_already_hired at propose and again at confirm, writing nothing. role.configure's roleAvailability.roleId accepts business_analyst alongside account_manager and sales_assistant. skill.withdraw (administrators; scope, fromVersionId, headRevision, no target) moves the active learned-guidance head back to the base version and marks that version withdrawn; a changed head is refused 409 skill_head_changed, and recovery is a replacement through teaching. | crm:write |
agent_team_change_confirm | Applies one previously proposed Account Manager change. | proposal_id, idempotency_key | crm:write |
agent_team_change_reject | Closes the proposal without applying the change. | proposal_id, idempotency_key | crm:write |
ekb_source_use_read | Whether one exact current knowledge claim is confirmed and permitted for one customer, with the approval reference and basis digest. Indexing alone never permits. | source_id, page_no, ordinal, customer_id | ekb:read |
ekb_product_evidence_selection_read | List the organisation's product-evidence selections, or read one with per-entry source, version, excerpt, eligibility and outward basis, resolved live. | selection_id (optional), customer_id (optional) | ekb:read |
ekb_product_evidence_selection_create_propose | Proposal to save one named selection of 1-12 pinned claims. Managers and administrators only; creates nothing until confirmed. | name, entries, idempotency_key | ekb:write |
ekb_product_evidence_selection_create_confirm | Saves the selection from the proposal. | proposal_id, idempotency_key | ekb:write |
ekb_product_evidence_selection_create_reject | Closes the proposal without saving anything. | proposal_id, idempotency_key | ekb:write |
ekb_product_evidence_selection_update_propose | Proposal to replace a selection's name and entries; a version change makes it stale. | selection_id, name, entries, idempotency_key | ekb:write |
ekb_product_evidence_selection_update_confirm | Applies the replacement from the proposal. | proposal_id, idempotency_key | ekb:write |
ekb_product_evidence_selection_update_reject | Closes the proposal without replacing anything. | proposal_id, idempotency_key | ekb:write |
ekb_product_evidence_selection_delete_propose | Proposal to delete one selection and its entries. | selection_id, idempotency_key | ekb:write |
ekb_product_evidence_selection_delete_confirm | Deletes the selection from the proposal. | proposal_id, idempotency_key | ekb:write |
ekb_product_evidence_selection_delete_reject | Closes the proposal without deleting anything. | proposal_id, idempotency_key | ekb:write |
ekb_source_use_change_propose | Proposal to approve or withdraw one bounded customer-use approval, pinned to the current source version. Managers and administrators only; creates nothing. | operation, source_id, idempotency_key, page_no, ordinal, audience, customer_id, valid_until, attestation_id | ekb:write |
ekb_source_use_change_confirm | Applies the approval or withdrawal from the proposal. | proposal_id, idempotency_key | ekb:write |
ekb_source_use_change_reject | Closes the proposal without changing any approval. | proposal_id, idempotency_key | ekb:write |
crm_engagement_context_read | One customer's cited engagement context: profile and confirmed facts, contacts, deals, transactions and timeline, each item with owner, content-digest version, observation date, confirmation and shareability; ineligible evidence surfaces only as generic gaps. Read-only; no model calls. | customer_id, purpose, sections, limit, cursor | crm:read |
crm_engagement_receivable_list | One customer's confirmed receivable cases with the latest balance, due date and state. | customer_id | crm:read |
crm_engagement_receivable_read | One receivable case and its full observation history. | customer_id, case_id | crm:read |
crm_engagement_order_delivery_list | One customer’s confirmed order-delivery cases with the latest observation and observation count. | customer_id | crm:read |
crm_engagement_order_delivery_read | One order-delivery case and its full observation history. | customer_id, case_id | crm:read |
crm_engagement_annual_evidence_read | One customer's reproducible annual cooperation evidence: status-and-currency transaction groups, activity, and the separately dated receivable balance. | customer_id, year | crm:read |
crm_engagement_receivable_confirm_propose | Proposal for one dated receivable observation — follow-up evidence, never a payment. | customer_id, remaining_balance, currency, state, idempotency_key, case_id, source_kind, source_id, expected_revision, due_on, observed_at, note | crm:write |
crm_engagement_receivable_confirm_confirm | Records the observation from the proposal. | proposal_id, idempotency_key | crm:write |
crm_engagement_order_delivery_confirm_propose | Proposal for one dated order-delivery observation — follow-up evidence, never an order action or an ERP write. | customer_id, timing_result, idempotency_key, case_id, order_reference, source_document_id, expected_revision, expected_on, observed_at, source_refs, note | crm:write |
crm_engagement_order_delivery_confirm_confirm | Records the observation from the proposal. | proposal_id, idempotency_key | crm:write |
crm_engagement_drafts_read | One customer's versioned engagement drafts with purpose, business reference, occurrence, recipient and source digest, or one draft with its full decision history. | customer_id, draft_id, purpose | crm:read |
crm_engagement_drafts_change_propose | Proposal for one engagement-draft operation — submit, edit, approve, dismiss or refresh. Approving binds the exact content, recipient and source digest; nothing is ever sent. | customer_id, operation, idempotency_key, draft_id, expected_version, purpose, business_ref_kind, business_ref_id, occurrence_key, intent, recipient_contact_id, recipient_email, subject, body | crm:write |
crm_engagement_drafts_change_confirm | Applies the engagement-draft operation from the proposal. | proposal_id, idempotency_key | crm:write |
crm_engagement_drafts_change_reject | Closes the proposal without applying anything. | proposal_id, idempotency_key | crm:write |
crm_engagement_dispatches_read | One customer's engagement dispatch reservations and their attempt outcomes — provider acceptance, definite failure or unknown; a receipt is never shown as recipient delivery. | customer_id, dispatch_id, draft_id | crm:read |
crm_engagement_drafts_send_propose | Proposal for dispatching one approved engagement message — CRM reserves the message version first, the existing email adapter is invoked once, and unknown outcomes are never retried. | customer_id, draft_id, expected_version, idempotency_key | crm:write |
crm_engagement_drafts_send_confirm | Confirms the send — the explicit human decision behind one reserved provider attempt. | proposal_id, idempotency_key | crm:write |
crm_engagement_drafts_send_reject | Closes the proposal without sending anything. | proposal_id, idempotency_key | crm:write |
tasks_engagement_followup_create_propose | Proposal to create exactly one Task from an accepted engagement follow-up proposal, with optional title, due date and owner edits. | customer_id, draft_id, proposal_id, idempotency_key, title, due_on, assignee_email | tasks:write |
tasks_engagement_followup_create_confirm | Creates the one Task behind the Tasks service and records the acceptance; a repeat or a recovered failure returns the same Task. | proposal_id, idempotency_key | tasks:write |
tasks_engagement_followup_create_reject | Closes the proposal without creating a task. | proposal_id, idempotency_key | tasks:write |
crm_engagement_schedules_read | One customer's accepted engagement schedules with purpose, business reference, recurrence, explicit first due date, time zone, next due occurrence and due basis, or one schedule with its occurrence history. | customer_id, schedule_id, status | crm:read |
crm_engagement_preparation_read | One customer's engagement preparation run states — which due occurrence was prepared into a draft, skipped, failed or stopped, per schedule occurrence and on-demand request. | customer_id, preparation_id, schedule_id, status | crm:read |
crm_engagement_inventory_sales_checkin_read | One customer's recorded inventory and sales check-in observations newest-first — product, period and the three distinct measures (inventory quantity with its as-of date, sales quantity with its period, sales amount with its currency), where a missing measure stays null and zero is a value. | customer_id, limit, cursor | crm:read |
crm_engagement_inventory_sales_checkin_prepare_propose | Proposal to prepare one inventory and sales check-in request draft — one product-specific ask per customer per month (inventory quantity with its as-of date, sales quantity with its period, sales amount with its currency); CRM renders the ask from the customer's known products. Preparing never sends. | customer_id, recipient_contact_id, idempotency_key | crm:write |
crm_engagement_inventory_sales_checkin_prepare_confirm | Confirms the prepare — the request draft waits in the decision queue; a month yields at most one request (checkin:<customer_id>:<YYYY-MM>). | proposal_id, idempotency_key | crm:write |
crm_engagement_inventory_sales_checkin_prepare_reject | Closes the prepare proposal without preparing any draft. | proposal_id, idempotency_key | crm:write |
crm_engagement_inventory_sales_checkin_record_propose | Proposal to record one confirmed inventory/sales check-in as a versioned observation — at least one of the three measures, each complete with its explicit unit, currency and period; zero is a value and a missing measure stays missing, and the product must resolve inside this customer's records or nothing is written. | customer_id, product_ref, inventory, sales_quantity, sales_amount, observed_at, source_refs, idempotency_key, occurrence_key | crm:write |
crm_engagement_inventory_sales_checkin_record_confirm | Confirms the record — a NEW versioned observation is appended; recording one occurrence never touches later recurring periods, and no forecast, purchase order or external stock record is ever written. | proposal_id, idempotency_key | crm:write |
crm_engagement_inventory_sales_checkin_record_reject | Closes the record proposal without recording anything. | proposal_id, idempotency_key | crm:write |
crm_engagement_schedules_change_propose | Proposal for one versioned engagement-schedule operation — accept, pause, cancel or update. Monthly recurrence clamps to shorter months; event_relative counts an entered lead back from a confirmed date — a pre-exhibition promotion anchors on the verified exhibition event and runs on the event's own time zone; saving prepares and sends nothing. | customer_id, operation, idempotency_key, schedule_id, expected_revision, purpose, business_ref_kind, business_ref_id, recurrence, first_due_on, timezone, lead_days, date_ref_kind, date_ref_id, date_ref_field | crm:write |
crm_engagement_schedules_change_confirm | Applies the engagement-schedule operation from the proposal. | proposal_id, idempotency_key | crm:write |
crm_engagement_schedules_change_reject | Closes the proposal without applying anything. | proposal_id, idempotency_key | crm:write |
crm_engagement_preparation_retry_propose | Proposal for re-driving one proven failed engagement preparation through the same registry. Nothing is applied until confirmed, and retry never sends. | customer_id, preparation_id, idempotency_key | crm:write |
crm_engagement_preparation_retry_confirm | Re-drives the failed preparation from the proposal. Retry never sends. | proposal_id, idempotency_key | crm:write |
crm_engagement_preparation_retry_reject | Closes the proposal without applying anything. | proposal_id, idempotency_key | crm:write |
crm_engagement_tailored_solution_prepare_propose | Proposal to prepare one tailored product-solution draft from a product-evidence selection — at most three recommendations, each with a product source and a confirmed customer-fit reason; missing evidence is named and nothing is created. | customer_id, selection_id, recipient_contact_id, idempotency_key | crm:write |
crm_engagement_tailored_solution_prepare_confirm | Confirms the prepare — the revalidated basis is pinned into a versioned draft that waits in the decision queue. Preparing never sends. | proposal_id, idempotency_key | crm:write |
crm_engagement_tailored_solution_prepare_reject | Closes the prepare proposal without preparing any draft. | proposal_id, idempotency_key | crm:write |
crm_engagement_exhibition_invitation_prepare_propose | Proposal to prepare one exhibition-invitation draft from the customer's verified exhibition record — event, timezone-aware timing, venue, and the company booth label only when confirmed; unconfirmed participation or an invisible recipient is named and nothing is created. | customer_id, event_id, recipient_contact_id, idempotency_key | crm:write |
crm_engagement_new_product_promotion_prepare_propose | Proposal to prepare one new-product promotion draft from the customer's latest approved tailored basis — every promoted product's pinned claim must currently resolve through the source-use resolver as confirmed and customer-shareable launch evidence; an upload, replacement or indexing date never qualifies, and a missing or lapsed attestation is named with no proposal created. | customer_id, recipient_contact_id, idempotency_key | crm:write |
crm_engagement_after_sales_report_prepare_propose | Proposal to prepare one after-sales survey report draft from the customer’s recorded survey/feedback evidence — every knowledge claim’s exact locator must currently resolve through the source-use resolver as confirmed and customer-shareable; response counts ride per source only where the source supplies one, and missing months are stated as partial coverage. Preparing never sends. | customer_id, recipient_contact_id, period_start, period_end, selected_source_refs, idempotency_key, unresolved_questions, permission_limited | crm:write |
crm_engagement_after_sales_report_prepare_confirm | Confirms the prepare — the revalidated sources are pinned into a versioned draft that waits in the decision queue. Preparing never sends. | proposal_id, idempotency_key | crm:write |
crm_engagement_after_sales_report_prepare_reject | Closes the prepare proposal without preparing any draft. | proposal_id, idempotency_key | crm:write |
crm_engagement_milestone_sharing_prepare_propose | Proposal to prepare one company-milestone sharing draft from an F08-attested knowledge claim ({customer_id, source_id, page_no, ordinal, recipient_contact_id}) — the exact claim must currently resolve through the source-use resolver as confirmed and permitted for this customer in the source's active version, paired with confirmed customer-fit evidence; a missing, expired, withdrawn or internal-only approval, or absent fit evidence, is named with no proposal created. | customer_id, source_id, page_no, ordinal, recipient_contact_id, idempotency_key | crm:write |
crm_engagement_milestone_sharing_prepare_confirm | Confirms the prepare — the attested claim, its version and the confirmed fit reason are pinned into a versioned draft that waits in the decision queue; the same request replays the same occurrence. Preparing never sends, and approval/send revalidate the attestation live. | proposal_id, idempotency_key | crm:write |
crm_engagement_milestone_sharing_prepare_reject | Closes the prepare proposal without preparing any draft. | proposal_id, idempotency_key | crm:write |
crm_engagement_new_product_promotion_prepare_propose | Proposal to prepare one new-product promotion draft from the customer's latest approved tailored basis — every promoted product's pinned claim must currently resolve through the source-use resolver as confirmed and customer-shareable launch evidence; an upload, replacement or indexing date never qualifies, and a missing or lapsed attestation is named with no proposal created. | customer_id, recipient_contact_id, idempotency_key | crm:write |
crm_engagement_sample_test_confirm_propose | Proposal for one confirmed sample-test result — pass, fail, inconclusive or retest required; the result closes only this sample's own follow-up. | customer_id, result, idempotency_key, case_id, document_id, sample_label, expected_revision, observed_at, feedback, source_refs | crm:write |
crm_engagement_sample_test_confirm_confirm | Explicitly confirm one pending sample-test result proposal; a final pass/fail stops only that sample's own test follow-up. | proposal_id, idempotency_key | crm:write |
crm_engagement_sample_test_confirm_reject | Explicitly reject one sample-test result proposal — nothing is recorded and no follow-up is closed. | proposal_id, idempotency_key | crm:write |
crm_engagement_promotion_meeting_summary_prepare_propose | Proposal to prepare one summary draft from an existing visible promotion meeting — confirmed facts, decisions, unanswered questions and next points exactly as the rep confirmed them, discussed products resolved live against one pinned selection with a display title, and at most three proposed follow-up tasks; proposing creates no task. | customer_id, meeting_id, recipient_contact_id, request_id, promotion_confirmed, idempotency_key | crm:write |
crm_engagement_promotion_meeting_summary_prepare_confirm | Confirms the prepare — the re-resolved meeting and evidence-checked discussed products are pinned into a versioned draft that waits in the decision queue; each proposed follow-up needs its own explicit Accept and exactly one Task is created per slot. Preparing never sends. | proposal_id, idempotency_key | crm:write |
crm_engagement_promotion_meeting_summary_prepare_reject | Closes the prepare proposal without preparing any draft. | proposal_id, idempotency_key | crm:write |
crm_engagement_cooperation_plan_prepare_propose | Proposal to prepare one next-calendar-year cooperation plan draft from the year's verified annual cooperation evidence plus explicitly confirmed customer goal facts — the target year is evidence_year + 1, every goal ref must resolve as a currently confirmed AND goal-eligible fact under this customer — internal manual notes, personal contact details and internal amounts are refused as goal_ref_not_eligible — and an empty evidence year or an unresolvable goal is named with no proposal created. | customer_id, evidence_year, confirmed_goal_refs, request_id, recipient_contact_id, idempotency_key | crm:write |
crm_engagement_cooperation_plan_prepare_confirm | Confirms the prepare — the evidence digest and every confirmed goal's revision are pinned into a versioned draft that waits in the decision queue; the caller's request id is the whole identity, so a repeat answers with the same result and a new request waits while one is pending. Preparing never sends. | proposal_id, idempotency_key | crm:write |
crm_engagement_cooperation_plan_prepare_reject | Closes the prepare proposal without preparing any draft. | proposal_id, idempotency_key | crm:write |
crm_engagement_new_product_promotion_prepare_confirm | Confirms the prepare — the launch-evidence-checked basis and its claim locators are pinned into a versioned draft that waits in the decision queue, one per customer per month. Preparing never sends. | proposal_id, idempotency_key | crm:write |
crm_engagement_new_product_promotion_prepare_reject | Closes the prepare proposal without preparing any draft. | proposal_id, idempotency_key | crm:write |
crm_engagement_exhibition_invitation_prepare_confirm | Confirms the prepare — the revalidated event evidence is pinned into a versioned draft that waits in the decision queue. Preparing never sends. | proposal_id, idempotency_key | crm:write |
crm_engagement_exhibition_invitation_prepare_reject | Closes the prepare proposal without preparing any draft. | proposal_id, idempotency_key | crm:write |
crm_engagement_receivable_confirm_reject | Closes the proposal without recording anything. | proposal_id, idempotency_key | crm:write |
crm_engagement_order_delivery_confirm_reject | Closes the proposal without recording anything. | proposal_id, idempotency_key | crm:write |
crm_engagement_exhibition_context_read | One customer's verified exhibition contexts — event, timing, venue, verified participation and booth — with the confirmation sources, confirmer and time. | customer_id, event_id | crm:read |
crm_engagement_exhibition_context_create_propose | Proposal for one verified exhibition context; unknown participation or booth stays explicitly unconfirmed. | customer_id, event_id, event_name, starts_at, ends_at, timezone, venue, participation_customer, participation_company, booth_party, sources, idempotency_key, booth_label | crm:write |
crm_engagement_exhibition_context_create_confirm | Records the verified exhibition context from the proposal. | proposal_id, idempotency_key | crm:write |
crm_engagement_exhibition_context_create_reject | Closes the proposal without recording anything. | proposal_id, idempotency_key | crm:write |
crm_engagement_exhibition_context_update_propose | Proposal to re-confirm one existing exhibition record; same inputs as create. | customer_id, event_id, event_name, starts_at, ends_at, timezone, venue, participation_customer, participation_company, booth_party, sources, idempotency_key, booth_label | crm:write |
crm_engagement_exhibition_context_update_confirm | Applies the re-confirmation from the proposal. | proposal_id, idempotency_key | crm:write |
crm_engagement_exhibition_context_update_reject | Closes the proposal without changing the record. | proposal_id, idempotency_key | crm:write |
crm_engagement_exhibition_context_delete_propose | Proposal to withdraw one verified exhibition record. | customer_id, event_id, idempotency_key | crm:write |
crm_engagement_exhibition_context_delete_confirm | Withdraws the record from the proposal. | proposal_id, idempotency_key | crm:write |
crm_engagement_exhibition_context_delete_reject | Closes the proposal without withdrawing anything. | proposal_id, idempotency_key | crm:write |
crm_engagement_tender_brief_read | One customer's confirmed tender briefs — or one brief with its cited evidence, confirmer, revision and live new-draft eligibility. | customer_id, tender_reference | crm:read |
crm_engagement_tender_brief_create_propose | Proposal for one confirmed tender brief; every requirement cites 1-5 confirmed evidence references (owner:kind/id@version). | customer_id, tender_reference, title, deadline_at, timezone, requirements, idempotency_key | crm:write |
crm_engagement_tender_brief_create_confirm | Records the confirmed tender brief from the proposal; CRM re-resolves every cite at execution. | proposal_id, idempotency_key | crm:write |
crm_engagement_tender_brief_create_reject | Closes the proposal without recording anything. | proposal_id, idempotency_key | crm:write |
crm_engagement_tender_brief_update_propose | Proposal to re-confirm one existing brief (same inputs as create; the reference cannot change). | customer_id, tender_reference, title, deadline_at, timezone, requirements, idempotency_key | crm:write |
crm_engagement_tender_brief_update_confirm | Appends the re-confirmation as a new revision; the prior revision is preserved and becomes non-current. | proposal_id, idempotency_key | crm:write |
crm_engagement_tender_brief_update_reject | Closes the proposal without changing the brief. | proposal_id, idempotency_key | crm:write |
crm_engagement_tender_brief_delete_propose | Proposal to withdraw one confirmed tender brief and its preserved revisions. | customer_id, tender_reference, idempotency_key | crm:write |
crm_engagement_tender_brief_delete_confirm | Withdraws the brief from the proposal. | proposal_id, idempotency_key | crm:write |
crm_engagement_tender_brief_delete_reject | Closes the proposal without withdrawing anything. | proposal_id, idempotency_key | crm:write |
RFQ handoff
Call agent_team_change_propose with {"operation":"run.handoff","hireId":"<pre-sale hire id>","revision":<hire revision>}, then agent_team_change_confirm. It hands the active Pre-sale Assistant's requirements matrix to the active Account Manager on the same customer: two runs with trigger handoff and one Workflow. The Account Manager run records the Pre-sale run as handoff evidence before its one governed model call (purpose rfq_handoff) and publishes one Clarify: <requirement> task for each of the first three gaps plus one follow-up draft, all pending approval; nothing is sent. Refused with 409 handoff_unavailable when there is no active Account Manager on the customer, the caller cannot run both hires, or a handoff is still in flight; a Pre-sale run with no requirements ends the Account Manager run failed with handoff_source_failed. The same idempotency key never creates a second run pair.
A Pre-sale hire's detail view (agent_team_inspect view:"detail") carries handoffAvailable and, when it is false, handoffUnavailableReason: one of no_account_manager, plan_only_account_manager, handoff_in_flight, no_access, unavailable. A handoff counts as in flight while either run of its pair is queued or running and its Workflow has not finished; when the Workflow ends after a step exhausted its retries, the unfinished runs end failed (handoff_abandoned, or handoff_source_failed for an Account Manager run whose Pre-sale run did not complete) and a new handoff can start. Two confirmations racing under different keys create one run pair; the other is refused 409 handoff_unavailable. When the Workflow cannot be started the confirmation answers 503 handoff_unavailable, ends the pair handoff_abandoned and can simply be retried; a detail read that cannot decide reads unavailable. The Account Manager run's output and work derived from a handoff are shown, and may be approved, only to a member who can also see the Pre-sale hire now and only while the Pre-sale run is still the retained, completed run it recorded; anyone else reads them as evidence_unavailable, the same as withdrawn evidence. Gaps beyond the three asked are each named in the limitations; when they do not all fit, the rest are named together in one final Not asked: <id>, <id> entry.
Unsaved teaching suggestion
Call agent_team_change_propose with the arguments below, then agent_team_change_confirm with the returned proposal_id and a confirmation idempotency_key.
{"operation":"teaching.suggest","hireId":"amhire_example","revision":1,"teachingSuggestion":{"runId":"amrun_example","excerpt":"No clear question.","expected":"Ask for a decision date."},"idempotency_key":"suggest-example-1"}
Scope defaults to account; authorised organisation proposals retain existing administrator-only evaluation/publication gates. Confirmation creates one charged attempt and returns an unsaved suggestion containing proposedInstructions, rationale, inputDigest and source references, with top-level runId/hireId. Review before a separate teaching.create. teaching.create accepts an optional feedback anchor ({"source":"knowledge_sandbox"|"agent_run","id"}) verified against the named Sandbox or agent-run rating before anything is saved. Current source/method access and credit reservation are mandatory. Replay recovers retained output or refuses; result_unavailable never triggers another invocation. A fresh explicit proposal is separately charged. See REST input limits, failures and retention.
For the teaching comparison, propose and confirm {"operation":"teaching.compare","hireId":"amhire_example","candidateId":"amlearn_example"}. It is current-human-admin only. In staging/development the server owns reviewed pack/case resolution, the 2 × 3 frozen expansion, reservation and credit checks, and honestly refuses before worlds or model calls while the registry has no compatible method pack. On production the comparison is an effect-free replay of the recorded anchor run — recorded inputs re-read with drift refusal, regeneration with and without the lesson, a frozen judge against the recorded output and the human correction — metered against the organisation's credits, audited, and publication-gating: only a passing comparison makes the lesson publishable.
Current release calls and results
Use the same tool for an unfiltered page, a lexical search, and the next opaque cursor page. Read one returned id with ekb_releases_read:
{"jsonrpc":"2.0","id":21,"method":"tools/call","params":{"name":"ekb_releases_list","arguments":{"kind":"policy","limit":1}}}
{"jsonrpc":"2.0","id":22,"method":"tools/call","params":{"name":"ekb_releases_list","arguments":{"q":"quotation approval","limit":1}}}
{"jsonrpc":"2.0","id":23,"method":"tools/call","params":{"name":"ekb_releases_list","arguments":{"q":"quotation approval","limit":1,"cursor":"eyJxIjoicXVvdGF0aW9uIGFwcHJvdmFsIiwia2luZCI6bnVsbCwidGllciI6MSwicHVibGlzaGVkX2F0IjoiMjAyNi0wOS0wOFQwMDowMDowMC4wMDBaIiwiaWQiOiJtcmVsXzAxIn0"}}}
{"jsonrpc":"2.0","id":24,"method":"tools/call","params":{"name":"ekb_releases_read","arguments":{"release_id":"mrel_01"}}}
A matched search returns the owner payload unchanged inside structuredContent. This abridged response shows the typed stable locator and quote; pass next_cursor back unchanged:
{"jsonrpc":"2.0","id":22,"result":{"structuredContent":{
"schema_version":"atlas.action.v1","action":"ekb.releases.list","status":"completed",
"data":{"items":[{
"citation":{"schemaVersion":1,"reference":{"schemaVersion":1,"kind":"policy","owner":"ekb","id":"mrel_01","version":"3"},"asset":{"id":"mpol_01","title":"Quotation policy"},"locator":{"type":"section","stable_id":"psec_0123456789abcdef0123456789abcdef","label":"Approval"},"quote":"quotation approval is required"},
"release":{"id":"mrel_01","release_no":3,"published_at":"2026-09-08T00:00:00.000Z","author_email":"[email protected]","status":"released","content_digest":"…","answerable":false,"executable":false,"withdrawn_at":null,"withdrawn_by":null,"withdraw_reason":null,"asset_kind":"policy","asset_id":"mpol_01","asset_title":"Quotation policy","content":{"title":"Quotation policy","category":"sales","sections":[{"heading":"Approval","body":"quotation approval is required"}]}}
}],"next_cursor":"eyJxIjoicXVvdGF0aW9uIGFwcHJvdmFsIiwia2luZCI6bnVsbCwidGllciI6MSwicHVibGlzaGVkX2F0IjoiMjAyNi0wOS0wOFQwMDowMDowMC4wMDBaIiwiaWQiOiJtcmVsXzAxIn0"},"meta":{"principal_kind":"delegated_token"}
}}}
An empty page is still completed: data: {"items":[],"next_cursor":null}. A successful ekb_releases_read response uses action ekb.releases.read and returns the same complete item as data.item. Unknown, foreign, withdrawn, and superseded ids return terminal_failure/not_found.
Admission failures happen before JSON-RPC dispatch: suspension is HTTP 403 {"error":"organisation_suspended","retryable":false}; an Auth outage is HTTP 503 {"error":"credential_store_unavailable","retryable":true}. Tool-level failures use isError:true and contain no release data:
{"jsonrpc":"2.0","id":22,"result":{"isError":true,"structuredContent":{"status":"forbidden","error":{"code":"insufficient_scope","retryable":false}}}}
{"jsonrpc":"2.0","id":22,"result":{"isError":true,"structuredContent":{"status":"retryable_failure","error":{"code":"credential_store_unavailable","retryable":true}}}}
{"jsonrpc":"2.0","id":22,"result":{"isError":true,"structuredContent":{"status":"retryable_failure","error":{"code":"upstream_unavailable","retryable":true}}}}
Full input schemas come from tools/list. Call it once after connecting rather than hard-coding the table above.
The agent_team_* tools are governed by the AI team release switch as well as by scopes. A platform superadmin sets the ai-team feature key to developers-only, preview, or general, and its registered default is developers-only. While it is developers-only, the four tools stay listed by tools/list and every call is refused with agent_team_restricted, and scheduled Sales Assistant and Account Manager work starts nothing new. No other tool in this table is affected.
Organisation-scoped external tools
A tool your administrator classified on a connected system (#2747) is published to tools/list alongside the tools above, scoped to your token's own organisation only. A classified read publishes as one tool. A classified effect publishes as three — _propose, _confirm, _reject — so the confirmation cannot be skipped, exactly like a catalog effect. A tool whose remote input schema has drifted since classification, or whose connection is paused or revoked, is omitted from the list, and calling it by its old name answers Tool <name> not found without contacting the remote system. An organisation with nothing connected sees exactly the pinned governed-tools list above and nothing more.
Names are Atlas-authored, never the remote tool's own name: external.<connectionId>.<toolName> flattens to external_<connectionId>_<toolName> (effects append _propose/_confirm/_reject). If two distinct classified tools would flatten to the same name, both are withheld from the list and the shared name resolves to nothing at call time. The effect triad uses the same propose/confirm/reject flow as every other consequential MCP tool: nothing reaches the remote system until an explicit confirm, and a confirmed call happens exactly once. Everything the remote tool returns is data for you to read, never an instruction Atlas or the client should follow.
This is separate from a hire's own AI team run using a classified tool on its role's and permission level's behalf, which is not an MCP call at all: see the REST manual's "External tools during a hire's run" for how plan_only, co_pilot and auto_pilot hires differ and why a hire never executes a classified effect itself, whatever its permission level.
Tencent Meeting personal accounts. This browser-session provider is owner-private and is not published to bearer-token MCP clients or background hires. Use the private Tencent Meeting setup and reviewed-save guide; administrator classification never grants access or enables write tools.
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.
Company policy on confirmations
Every *_propose result carries policy: outcome is none, warn, block or could_not_verify, with each cited policy title, section heading and quote in reasons. Show it to the person deciding. The same result is evaluated again at confirm. When the cited rule names a permitted alternative, or the cited section has a Chinese title, each reason also carries permitted_alternative (the sentence to follow instead of the blocked action, at most 300 characters) and heading_zh; both are omitted for policies that do not set them, so older policies read exactly as before (#3954).
- A
blockholds the proposal for an owner or admin decision. Delegated MCP callers receiveowner_decision_requiredand cannot proceed by calling*_confirmagain withoverride_reason. A signed-in owner or admin decides the held plan throughPOST /agent/assistant/owner-decisions/:id/decidewith a 10–500 character reason; the decision and any approved override appear in Agent logs. policy_unverifiedmeans the check could not be completed. Nothing happened, and no reason lifts it; try again later.policy_changedmeans the result is now stricter than the one shown (“Guidance changed — review again”). Show the newpolicybefore confirming again.- A
warngoes ahead; the result carries the warning.*_rejectnever takes a reason.
Never write an override_reason on the person's behalf. The optional confirm-tool field remains for compatible clients; it does not let a delegated MCP caller decide a held proposal.
Linked evidence in profile-gap Task proposals
The existing tasks.profile_gap_task.create proposal adds data.proposal.evidence.linked_sources: at most 50 explicitly linked files, ordered by source_id,link_id. CRM evidence stays in its existing fields. Each source has the following shape:
{"link_id":"link_1","source_id":"libf_1","state":"current","citations":[{"schemaVersion":1,"reference":{"schemaVersion":1,"kind":"knowledge_source","owner":"ekb","id":"libf_1"},"asset":{"id":"libf_1","title":"Customer notes"},"locator":{"type":"passage","index":0},"quote":"Contact channel reported by the source."}]}
A readable source is current; each citation contains its real source ID/title, a zero-based passage index, and a verbatim prefix capped at 200 Unicode code points. At most three passages per file are returned in index order. [] means CRM has no associations. Other source states have empty citations: source_unavailable (missing or foreign source, indistinguishable 404), inaccessible (no existing Knowledge read authority or 401/403), no_passage (valid file without passages), and owner_unavailable (missing binding, timeout, 503, malformed or unexpected response). CRM enrichment unknown retains the association; an independently authorised EKB read may still provide citations.
The proposal still requires tasks:write; delegated citations additionally require that same token's existing ekb:read. Missing Knowledge access does not change Task eligibility. Source text never changes CRM facts or Task metadata. Review both evidence fields before explicitly confirming. Changed linked IDs, states or citation content return 409 proposal_stale and create no Task: propose again and review the new evidence. An unchanged confirm retains its existing idempotency; reject creates no Task.
Use tasks_profile_gap_task_create_propose and review result.structuredContent.data.proposal.evidence.linked_sources. Then call tasks_profile_gap_task_create_confirm or tasks_profile_gap_task_create_reject with the existing proposal_id,idempotency_key. MCP continues to require a delegated Bearer token.
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 forbidden, error agent_team_restricted | The AI team is not released in this environment, or this role is not open to you. A platform superadmin releases the ai-team feature key; the tools stay listed either way. |
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. |
Customer profiles, imports and sampling stages
Customer profile reads include website, background and optional main_markets, brands and products. Organisation and customer-owner authorization still applies. Maintain these facts through REST import or the customer editor.
Task privacy
Self-created, self-assigned tasks default to private, including tasks linked to a customer. Only their assignee can access them; managers and admins have no override. A team task is visible to its assignee, creator and organisation management, never unrelated representatives. These boundaries also apply to filters, source retries, reminders and agent calls. Scheduled shared context excludes private tasks.
XLSX reading and customer preparation
GET /knowledge/files/:id/xlsx reads the retained original workbook through the authenticated Knowledge owner. Existing organisation and Library permissions apply. The response is {"extraction": ...}; reading does not replace the stored source or confirm a CRM import.
| Query | Meaning |
|---|---|
sheetIndex | Zero-based sheet index; default 0. |
startRow, startColumn | One-based coordinates; default 1. |
maxRows, maxColumns | At most 200 rows and 40 columns per read; these are also the defaults. |
The result includes the pinned skill id/version/digest, document metadata, ordered sheet names, original cell coordinates, typed and display values, hyperlink labels and targets, merged ranges, and formulas separately from cached values. Missing cached values are explicit; formulas and external links never execute. coverage.covered, coverage.remaining and continuation identify exact ranges. Repeat the read with the returned continuation; headers retain their original coordinates. Charts expose cached series first. Raster descriptions use governed AI; unavailable visual content produces warnings and partial coverage. A valid empty workbook succeeds. Missing metadata is not provided.
Named parser failures include xlsx_corrupt, xlsx_encrypted, xlsx_legacy_binary and xlsx_unsafe_archive. Resource limits include 400 ZIP entries, 32 MiB expanded total, 8 MiB per entry, plus allocation bounds of 16,000 cells, 64,000 XML tokens, 8 MiB total XML and 2 MiB XML text. Excess is refused, never silently truncated. Skill identity or telemetry failures are reported separately. Failed re-extraction preserves the previous good result and original bytes.
Intake and Assistant ranges
GET /crm/intake-artifacts/:id/reading and the Assistant's read_artifact accept sheet (name), row_from/row_to and col_from/col_to. Row and column bounds are one-based and inclusive. Read at most 200 rows and 40 columns; follow returned complete/remaining metadata instead of assuming the first window is the entire workbook. Keep source locations when quoting or preparing records. These are existing intake/Assistant operations, not additional MCP tool names.
Customer profiling preserves repeated company rows as separate contacts, including blank serial cells and source websites. It does not group companies by email domain. A single-customer preparation that detects several companies returns 422 multiple_customers; the Assistant reroutes to the existing batch review. 422 source_range_required means select a smaller source range for ambiguous input and retry preparation. Review proposed companies, every contact and websites before using the existing explicit commit action. Successful reading or preparation alone never means customers were saved.
Governed named human teams
Named human teams use Auth's shared team functions on every surface. New delegated grants auth:teams:read and auth:teams:write are independent: write permits proposing and confirming a reviewed change, not the read tool. Existing tokens gain no authority; request each grant explicitly through POST /auth/tokens. Minting and every read/propose/confirm/recovery require current active owner/admin membership and the corresponding live members:read/members:write capability. Revoked, expired, role-downgraded or unsupported platform/scheduled/sync credentials cannot act.
MCP: auth_teams_read, auth_teams_change_propose, auth_teams_change_confirm, auth_teams_change_reject. Propose takes the change fields plus idempotency_key; confirm/reject take proposal_id and idempotency_key. CLI: atlas organisation teams read '<json>'; atlas organisation teams propose '<json>' --idempotency-key KEY; atlas organisation teams confirm PROPOSAL_ID --idempotency-key KEY; atlas organisation teams reject PROPOSAL_ID --idempotency-key KEY.
REST action transport: POST /assistant/v1/actions/auth.teams.read, POST /assistant/v1/actions/auth.teams.change, and existing POST /assistant/v1/proposals/:id/confirm or /reject. Send Idempotency-Key for proposals and decisions. Results use the existing atlas.action.v1 envelope and the same Auth team/assignment payload. Team changes are administration proposals; policy holds, expiry, rejection and current authority apply before effects. A proposal is bound to its original principal, organisation, normalized input, revision basis and idempotency key. Delegated tokens cannot override policy; an owner decision remains governed by the existing policy flow.
{"operation":"list","status":"active","limit":50}
{"operation":"team","team_id":"TEAM_ID","limit":50}
{"operation":"assignment","email":"[email protected]"}
{"operation":"create","name":"Sales"}
{"operation":"rename","team_id":"TEAM_ID","name":"Customer Success","expected_revision":1}
{"operation":"archive","team_id":"TEAM_ID","expected_revision":2}
{"operation":"assign","email":"[email protected]","team_id":"TEAM_ID","expected_assignment_revision":0,"expected_team_revision":1}
{"operation":"assign","email":"[email protected]","team_id":null,"expected_assignment_revision":1}
Read lists retain status active (default), archived or all, stable ID/email order, opaque cursor, default 50 and maximum 100 rows. Return next_cursor unchanged. Names are trimmed, nonempty and at most 80 Unicode characters. Unknown/extra fields are rejected. Rename/archive require the current expected_revision; assignment requires expected_assignment_revision and, for a non-null destination, expected_team_revision. Removing an assignment must omit the destination revision. Archive requires an empty active team. No role or global membership mutation is exposed.
Auth commits effect, audit and operation receipt atomically. After a timeout/lost response, retry the same proposal decision/key: recovery returns only the matching original result after live admission and never dispatches again, even if that already-applied proposal subsequently expired. A missing receipt cannot bypass expiry. Reused keys/input or stale revisions conflict; revoked authority is forbidden; unavailable authority/storage is retryable failure, never an empty success. All responses are no-store. Receipt migration 0023_organisation_team_operation_receipts.sql, scopes and Auth producer deploy before Agent adapters; public session team REST stays compatible. The binding-only /internal/teams/actions/read and /change/prepare, /change/execute, /change/recover require exact request/body-bound assertions and have no public alias.
A confirmation timeout may leave Auth still committing. The proposal stays pending; rejection and expiry return a conflict while its outcome is unresolved. Retry confirmation only recovers the original receipt and never redispatches. If no receipt becomes available, the proposal remains pending rather than assuming the effect failed.
Workbench customer analytics through MCP and CLI
The read actions crm.workbench.customer_summary.read and crm.workbench.customer_contributors.read use the existing crm:read grant. Ordinary tenant sessions and explicitly granted delegated tokens resolve current company, assigned-team, self or empty scope in Auth before the CRM query and again before returning. A manager without an active named-team assignment receives explicit empty scope. No team-administration grant or confirmation is needed.
MCP exposes crm_workbench_customer_summary_read and crm_workbench_customer_contributors_read as read-only tools. Summary input is exactly {}. Contributors input is {"metric":"customers","scope_revision":"<scope_revision>","limit":50}, with optional opaque cursor. Metrics are customers, active, at_risk and open_pipeline; limit defaults to 50 and accepts 1–100. Extra fields and caller-supplied organisation, owner or scope hints are rejected.
atlas workbench customers summary
atlas workbench customers contributors '{"metric":"open_pipeline","scope_revision":"<revision>","limit":50}'
CLI uses POST /assistant/v1/actions/crm.workbench.customer_summary.read and POST /assistant/v1/actions/crm.workbench.customer_contributors.read, returning the existing action envelope. Forward cursor bytes unchanged and use the matching scope revision. Each contributor page refreshes all four totals from the same current CRM snapshot as its items; pagination does not freeze a historical snapshot.
Results retain customer-current-book-v1, public scope metadata and evaluated_at. Pipeline amount_by_currency keeps whole currency units in separate groups; unknown_amount_count counts missing amounts. Pipeline items identify both customer_id/customer_name and engagement name/ID. The internal owner roster is never returned.
Responses use Cache-Control: no-store. Invalid input/cursor is 400; credential and authority denials retain 401/403; changed scope is 409 scope_changed (read a fresh summary); an unavailable Auth/CRM service is 503, never a fabricated zero. Platform, scheduled and sync callers are unsupported. Public session CRM routes remain session-only; bearer clients use the governed actions. Deploy the exact Auth allowlists and CRM assertion producers before Agent adapters; no new migration or scope is required.
Knowledge pages and source access
These interfaces are implemented but inactive by default. Exposure requires a complete target census and accepted Product impact review. This reference does not establish staging or production availability.
ekb_page_list
ekb_page_read
ekb_page_revisions_list
ekb_page_revisions_read
ekb_page_create_propose / ekb_page_create_confirm / ekb_page_create_reject
ekb_page_update_propose / ekb_page_update_confirm / ekb_page_update_reject
ekb_page_decide_propose / ekb_page_decide_confirm / ekb_page_decide_rejectRead inputs use the REST fields, with pageId or revision where needed. Propose takes the flat operation fields plus idempotency_key; confirm/reject takes {proposal_id,idempotency_key}. A proposal is not a completed write. Confirmation may still be refused after permission or source changes. Proposal previews and historical receipts do not expose replayable page text.
ekb.page.list, ekb.page.read, ekb.page.create, ekb.page.update, ekb.page.decide, ekb.page.revisions.list, ekb.page.revisions.read.
Personal pages remain owner-only. Company contributors need current knowledgeFiles write permission; review needs knowledge write permission. Ordinary company readers see only the approved revision; view=current requires author or reviewer access. Every read and retry rechecks all sources. Withdrawn, corrected or unreadable sources withhold the entire derivative, including summaries, citations, related titles and counts. Legacy content without complete lineage and Sales-dependent derivatives remain unavailable. The core fallback uses current original passages for lexical retrieval; semantic-only search returns source_unavailable, and unverified vector ranking does not enter model context. Original file titles, passages, downloads and existing permissions are preserved.
Reads require ekb:read. Content-returning delegated writes require both explicitly granted ekb:read and ekb:write. The body idempotencyKey identifies the EKB operation; proposal and confirmation idempotency_key values are separate. Retry with the identical body and key. A 409 conflict requires reading and reviewing the current revision again. A 404 source_unavailable does not identify inaccessible sources; 503 read_unavailable means the read could not be established. Internal adapters may use the signed receiptOnly=true query to recover an existing receipt only; an absent receipt returns 404 and never creates an operation.
Merge customers
Current customer access is required. Reads and review use crm:read; commit, resume and cancel use crm:write, with CRM's current role and customer permissions still enforced. The verified credential supplies the organisation and actor; inputs cannot include org_id. This describes the local candidate capability, not production availability; keep it disabled until the complete journey passes acceptance.
- Select 2–10 customers. Start a read-only review with
customer_idsand optionalsurvivor_id. - Edit the returned
selectionand review the complete selection again. Inspect each value's source and timestamp, conflicts, related records and owner consequences.latestdoes not replace required explicit decisions. Resolve ties, primary-contact and plan choices, and other blockers first. Values inchoicesandcustom_field_sourcesare source customer IDs. - Show the human the final name, retained original count, owner and access changes, then obtain explicit confirmation. Before sending, durably save one unique
request_id, the complete selection,preview_digestandexpires_at. Addconfirmed:truewhen committing; a generic--yescannot skip review. - Inspect the same operation until
state:completeconfirms publication.pendingis still processing;blockedneeds the stated recovery. After response loss, look up the samerequest_idinstead of creating a new request. Resume only the existingoperation_id, without replacement choices.
Expired review or changed data requires another review, never a bypass of preview_digest. Cancellation can be requested only before apply starts; trust state:cancelled. Cancellation is not Undo. Continue recovery after apply has begun. After completion, inspect linked retained read-only originals through merge history. Current access still filters their contents; automatic Undo is unavailable.
crm_customer_merge_preview
crm_customer_merge_commit
crm_customer_merge_request
crm_customer_merge_status
crm_customer_merge_resume
crm_customer_merge_cancel
crm_customer_merge_history
crm_customer_merge_originalPreview accepts bootstrap or the complete selection. Commit accepts the complete explicitly confirmed commit body. Request takes {request_id}; status, resume and cancel take {operation_id}; history takes {customer_id}; original takes {operation_id,source_id}. Tools are listed only with the signed CRM bridge configured and the corresponding scope; calls still check current authority. Results preserve http_status and data; a 202 pending result is not completion. Submit confirmation only after the human explicitly approves, never by inferring approval.
Complete fields and REST paths
Keep the same request_id through 409 merge_blocked, preview_stale, preview_expired and request-lookup 404. A concurrent submission can already have been admitted. After a fresh review and explicit confirmation, retry with that same key. On idempotency_conflict, look up the same key and recover the existing operation instead of replacing its plan. Retire the key only after confirmed state:complete or state:cancelled.
Search Atlas
Use atlas.search to find records and content your identity can read. It performs no writes, sends or AI calls. This describes the implementation candidate; it does not establish live deployment or acceptance.
{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"atlas_search","arguments":{"query":"电机","kinds":["customer","task"],"limit":10}}}Supply query as 1–100 UTF-16 units without control characters. Optional kinds selects unique categories; limit is 1–20 results per category (default 10). Categories: customer, contact, opportunity, task, work, mail, document, knowledge, chat, assistant.
The atlas.action.v1 envelope carries data.query, items and sections. Every requested category reports complete, unavailable or error. hasMore counts only further accessible matches. A failed category does not erase successful categories. Retry the same query after a failure.
Chat search uses GET /crm/communications/authority/readable?strict=1. A verified denial or empty grant set returns 200 {items:[]}; unavailable or malformed authority and storage failures return 503. Search reports these failures as error with no chat items or counts. It rechecks mailbox grants before returning results; changed grants also retire the category. Existing authority probes without this option retain their empty-set behavior.
Entry retains the existing crm:read scope. Ordinary member sessions carry this transport scope independently of CRM settings permissions; each owning service still enforces its access rules. Tasks additionally require tasks:read; documents and Knowledge require ekb:read. EKB-only or Tasks-only tokens use the existing domain actions. Delegated tokens cannot read private chat or work through this action; those categories retain ordinary-session access. assistant is unavailable until the separately owned identity backend is available. An incomplete or stale mail index returns mail as unavailable; subject or excerpt matches never masquerade as complete body search.
Each result contains kind,id,title and, when needed, subtitle,snippet,customerId,connectionId,threadKey,fileId,sourceId. Titles and subtitles are bounded to 200 units; snippets to 300. Results contain no arbitrary URLs or execution callbacks. Matching precedes limits in the owning service and retains organisation, owner, task privacy, mailbox, conversation-source and Knowledge visibility checks.
After the separately authorized migration 0167_comm_mail_search_text.sql and CRM release, the existing CRM scheduled handler automatically invokes runScheduledMailContentBackfill on configured cron ticks for Inbox-enabled organisations. Each tick processes at most 10 sources within a 5-second budget, using a durable cursor that resumes and retries without blocking later sources. Missing schema leaves this maintenance inactive. Inspect the count-only [crm.cron] mail content backfill log; traversal completion does not prove every body was indexed. Unfinished, failed or stale readable sources keep mail unavailable. New ingestion indexes canonical text; source changes, discard and deletion invalidate stale text. Search never triggers indexing. Verify deployment identity and readable-corpus readiness separately before relying on live search.
Email receipt and legacy backfill sources use unique SHA-256-bound immutable artifact keys. Deploy the producer, attachment/reply reader compatibility and version-2 index/backfill together. Legacy version-1 indexes remain unavailable until rebuilt. Backfill freezes the current retained snapshot; it cannot reconstruct bytes already overwritten by the historical mutable-key race. Original legacy blobs are retained. Any rollback must preserve reader compatibility with the new keys; prefer a forward repair.
Automatic Assistant capabilities
New named assistants automatically use Atlas’s existing task-time capability resolution: enabled organization skills, callable connected plugin tools, built-in functions and authorized knowledge retrieval. Published organization guidance and the current user’s active memory resolve through their existing owners. No manual assignment, installation, new permission or memory publication is performed.
The directory advertises setupSchema: atlas.assistant-setup.v1. A clear bilingual job name infers focus; an unclear or conflicting name returns 400 assistant_purpose_required before a proposal. Supply optional identity.purpose as one trimmed description of 1–400 characters without control characters. Review the effective focus, then explicitly confirm. A saved custom identity may include setup: {mode: automatic, focus, source: name|clarified}; legacy identities omit it. Avatar-only edits retain focus; a changed name infers again or asks for clarification, and an explicit purpose overrides it. Focus steers task skill selection as untrusted user data; it grants no authority.
Shared governance traces retain run identity, usage and policy metadata without private conversation content, plans or tool inputs and outputs. Owner conversation history remains available.