tools/call
Invoke one namespaced CoreSpeed tool and read its result or isError payload.
https://api.corespeed.io/mcptools/callBilling holds and API-key spend caps are checked before a metered tool
executes. Those refusals arrive as tool-level errors inside HTTP 200, not as
HTTP failures — see Errors. A suspended organization
is refused earlier, with HTTP 403 org_suspended, before any tool runs.
Where Smart Approvals is on, a write that needs a person's approval returns an
approval receipt instead of running; call manage__approval_wait with its
approval_id.
Authorizations
AuthorizationstringheaderrequiredBearer <token>— an MCP OAuth token, ansk-cs-…API key orsk-csa-…agent key, or a user session JWT.x-api-key: <sk-cs-…>is accepted in its place.Acceptstringheaderrequiredapplication/json, text/event-stream— the Streamable HTTP transport requires both media types. This 2025-era request is answered as onetext/event-streamevent; itsdata:line is the JSON-RPC response.Content-Typestringheaderrequiredapplication/json. The transport rejects anything else with415.
Request
params.namestringrequiredA name returned by
tools/list, e.g.memory__remember. A name that is unknown or not on this caller's surface is not an HTTP error: it comes back as HTTP200with a JSON-RPCerror— code-32602, messageTool <name> not found— and noresult. Nothing about a misspelled tool name shows up in the HTTP status.params.argumentsobjectoptionalArguments matching that tool's
inputSchema. Optional in the MCP request schema — for a tool that takes none, omit it or send{}— but required in practice for every tool whoseinputSchemahas required properties. A schema violation is a tool-level error, not a transport error: HTTP200withresult.isError: trueand the textInput validation error: Invalid arguments for tool <name>: ….
Response fields
result.contentarrayrequiredContent blocks. Text tools return
{ "type": "text", "text": "…" }; media tools return signed artifact URLs.result.isErrorbooleanoptionaltruewhen the tool refused or failed. The HTTP status is still200, so branch on this field before treating a call as successful.result.structuredContent.errorobjectoptionalOn a failed call, the machine-readable half:
code— the value to branch on — plus only publishable facts (a provider'sstatus,request_id,retry_after_seconds, thealiasesto choose from, theallowedtools of a share). The text block is for the agent to read. Hold refusals carry their envelope as JSON in the text instead, and an approval receipt or refusal carries its facts in_meta. Every code is in Errors & status codes.result._metaobjectoptionalCoreSpeed facts about the call:
io.corespeed/holdon a hold refusal, andio.corespeed/approvalon any result shaped by Smart Approvals.
The manage__* tools answer an API key as its principal, with the
permissions the key was minted with — an agent key holds none. Two carry a
rule of their own: manage__keys_create and manage__agents_key_create
refuse every API key (api_key_cannot_mint — a key does not mint keys),
and manage__agents_create and the environments_* writes refuse an agent
principal (member_principal_required). The remote-connector lifecycle
writes need connections:org, and manage__approval_wait answers only for
the caller's own approval requests.
curl https://api.corespeed.io/mcp \
-H "Authorization: Bearer $CORESPEED_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "memory__remember",
"arguments": {
"memory": "Rollout changes require a two-day review window.",
"scope": "shared"
}
}
}'{
"jsonrpc": "2.0",
"id": 3,
"result": {
"content": [
{
"type": "text",
"text": "Memory shared with the organization."
}
],
"structuredContent": {
"id": "0b9a6f3e-…",
"memory": "Rollout changes require a two-day review window.",
"scope": "shared"
}
}
}{
"jsonrpc": "2.0",
"id": 3,
"result": {
"content": [
{
"type": "text",
"text": "More than one Notion account is connected (work, personal); pass `account` with one of those aliases (search)."
}
],
"structuredContent": {
"error": { "code": "ambiguous_account", "aliases": ["work", "personal"] }
},
"isError": true
}
}{
"jsonrpc": "2.0",
"id": 3,
"result": {
"content": [
{
"type": "text",
"text": "An API key cannot mint a key: a key's spend cap does not carry to the keys it would mint. Mint it from a signed-in CoreSpeed session."
}
],
"structuredContent": { "error": { "code": "api_key_cannot_mint" } },
"isError": true
}
}