MCP
The API as tools for AI agents
Every installation serves a Model Context Protocol endpoint next to its API. An MCP client such as Claude Code connects with an API token and gets one tool per read operation: customers, tenants, users, projects, releases, the licence, the brand and Private AI, as the token's scopes allow.
Read-only by construction.
Tools are generated from the API's GET operations only. No POST, PUT, PATCH or DELETE operation is ever a tool, so there are no write tools to call, whatever the token may do. Give an agent a token that carries only *-read-global keys anyway: it keeps the agent read-only if that ever changes, and a token is an operator credential.
Connect Claude Code
claude mcp add --transport http ataila https://portal.example.com/api/v1/mcp --header "Authorization: Bearer <token>" If the portal's certificate comes from a private certificate authority, Claude Code (a Node program) must trust it, for example with NODE_EXTRA_CA_CERTS=/path/to/ca.pem in its environment.
Any other MCP client
A client that reads the common JSON configuration takes the same three facts: the URL, the transport and the header.
{
"mcpServers": {
"ataila": {
"type": "http",
"url": "https://portal.example.com/api/v1/mcp",
"headers": {
"Authorization": "Bearer <token>"
}
}
}
} Try it by hand
curl -s https://portal.example.com/api/v1/mcp \
-H "Authorization: Bearer <token>" -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"whoami_get","arguments":{}}}' The endpoint
| URL | https://<your portal>/api/v1/mcp |
|---|---|
| Transport | MCP Streamable HTTP, stateless: every message is a POST answered with application/json. No SSE stream, no Mcp-Session-Id. GET answers 405, DELETE answers 204. |
| Protocol versions | 2025-11-25, 2025-06-18, 2025-03-26. initialize echoes the client's version when it is one of these, else answers 2025-11-25. The MCP-Protocol-Version request header is not enforced. |
| Methods | initialize, notifications/initialized (202, no body), ping, tools/list, tools/call. Any other method is JSON-RPC error -32601; a body that is not JSON is -32700 with HTTP 400. Batches are accepted. |
| Capabilities | Tools only: no prompts, no resources, no logging. |
| Server | Name ataila-cloud-platform; its version is the platform release. |
| On and off | The same switch as the rest of /api/v1: while the API is off, the endpoint answers 404. |
Authentication
The same bearer credential as every other /api/v1 operation: Authorization: Bearer <token>, with a personal token (ataila_pat_…) or a service-account token (ataila_sat_…); as on every operation, a portal session JWT is accepted as well. A missing or invalid credential is an HTTP 401 problem document, not a JSON-RPC error. A token's IP allowlist, when one is set, applies to the tool calls too. It is compared with the client address as the installation records it, which is the real client only where the installation's entry point passes that address on; where it does not, a token allowlisted to a client's address is refused: the allowlist fails closed. A revoked token stops at once on the API worker that revoked it and wherever the shared cache answers; while the shared cache is unreachable, another worker may accept it for up to 30 seconds more.
Tools
- One tool per read operation of
/api/v1, generated from the API's own routes and contract. The name is the operation id, the title its summary, the description its summary and description. - Arguments are the operation's path parameters (required) and query parameters (required only when the operation requires them). Unknown or missing arguments are JSON-RPC error
-32602, and nothing is sent. A path argument must be a single path segment. tools/listshows only what the caller may call with its effective permissions. The operations still enforce them: calling an unlisted tool returns the operation's own403as a tool error.- Results are one
textitem holding the API's JSON answer, plusstructuredContentwith the same JSON. An error answer isisError: truewith the problem document as the text. - Lists are paged: pass a page's
next_cursorascursorto get the next. - The licence bundle is always
nullover MCP. Tool results land in a model's context, and the bundle is the one read whose value is itself a credential. Every member the contract marks SENSITIVE is nulled, and the tool's description says so. A result that carried a non-nullsecretwould be withheld as an error.
In API 1.0.0 (platform release 1.0.187) there are 47 tools. Each links to its operation in the reference:
AI models
- ai_models_list List AI models
- ai_models_load_targets_list List load targets
- ai_models_runs_get One store run
- ai_models_storage_get Model storage
- ai_models_get One AI model
- ai_models_node_caches_list List a model's node caches
- ai_models_node_caches_get One node cache
AI nodes
- ai_catalog_list List the launch catalogue
- ai_clusters_list List DGX clusters
- ai_nodes_list List AI nodes
- ai_nodes_get One AI node
AI gateway
- ai_gateway_get The AI gateway
- ai_gateway_keys_list List virtual keys
- ai_gateway_keys_get One virtual key
- ai_gateway_tiers_list List serving tiers
- ai_gateway_tiers_get One serving tier
Audit
- audit_events_list List audit events
- audit_events_get One audit event
Brand
- brand_get This platform's brand
- brand_assets_list List brand assets
- brand_assets_get One brand asset
Customers
- customers_list List customers
- customers_get One customer
Licence
- licence_get This platform's licence
- licence_socket_facts The socket census
Meta
- meta_get API and platform facts
- whoami_get The calling principal
Operations
- operations_get One operation
Users
- permissions_list The permission catalogue
- users_list List users
- users_get One user
- user_roles_list A user's role grants
- user_roles_get One role grant
Projects
- projects_list List projects
- projects_get One project
- project_members_list A project's members
- project_members_get One project member
- project_provisioning_get A project's provisioning state
- project_stages_list A project's provisioning stages
Releases
- prod_lock_get The PROD data lock
- release_operations_list Release history of a project
- release_state_get Release state of a project
- release_operations_get One release operation
Tenants
- tenants_list List tenants
- tenants_get One tenant
- tenant_memberships_list A tenant's memberships
- tenant_memberships_get One membership
Rate limit, licence and records
- A tool call costs two requests. The
POSTcounts once against the token's 600 requests per minute, and everytools/callin it counts once more (the read it makes). A batch costs one plus one pertools/call.initialize,pingandtools/listcost only thePOST. - Each tool call runs as a
GETthrough/api/v1with the caller's credential, so it gets exactly the answer a direct call would, including429 rate_limited. - The licence treats the endpoint as a read: it works in every licence state.
- Reads are not audited, so neither the
POSTnor its tool calls write audit records. Changes, which the API makes only through its own write operations, are.