Skip to content

API and MCP

The gateway is https://casefork-gateway.samudrala153.workers.dev. The Salesforce package calls callout:Casefork_Gateway/v1/decide. A headless caller can use the same decide path over MCP. Both use the Casefork token for that org. A missing or unknown token is HTTP 401.

The response keys are choice, confidence, probabilities, request_id, and other_label. Provider and cost are not in the response. Any other top-level field on the request is rejected.

Send Authorization: Bearer with the Casefork token, and header X-Casefork-Org-Id with the 18-character org id. The org id on the header must be the org stored for that token.

Authorization: Bearer <Casefork token>
X-Casefork-Org-Id: <18-character org id>

Example request:

{
"subject": "Invoice",
"description": "Charged twice",
"queues": [{ "api_name": "Billing", "description": "Invoices and payments" }],
"other_label": "None of the named queues."
}

exemplars is optional. Each exemplar has subject, description, and choice. Lines after a prior-examples block in description must be exemplar lines (- queue=).

Example response:

{
"choice": "Billing",
"confidence": 0.91,
"probabilities": { "Billing": 0.91 },
"request_id": "6f1c0b3e-1a2b-4c5d-8e9f-0123456789ab",
"other_label": "None of the named queues."
}

When the call cannot be completed, the HTTP body is fail_closed and a request id, and the status is not 200. Salesforce then holds the Case for review.

{ "error": "fail_closed", "request_id": "6f1c0b3e-1a2b-4c5d-8e9f-0123456789ab" }

POST https://casefork-gateway.samudrala153.workers.dev/mcp speaks MCP over Streamable HTTP. Each body is one JSON-RPC 2.0 request. The response is application/json. There is no SSE stream and no session.

The auth header is the Casefork token already used by POST /v1/decide:

Authorization: Bearer <Casefork token>

The org id is the org stored for that token. Do not put an org id in the tool arguments. A missing or unknown token is HTTP 401, before any JSON-RPC handling. The only tool is casefork.decide. tools/call runs the same decide path as POST /v1/decide. A JSON-RPC array is rejected.

Example tools/call:

{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "casefork.decide",
"arguments": {
"subject": "Invoice",
"description": "Charged twice",
"queues": [{ "api_name": "Billing", "description": "Invoices and payments" }],
"other_label": "None of the named queues."
}
}
}

Example response:

{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "{\"choice\":\"Billing\",\"confidence\":0.91,\"probabilities\":{\"Billing\":0.91},\"request_id\":\"6f1c0b3e-1a2b-4c5d-8e9f-0123456789ab\",\"other_label\":\"None of the named queues.\"}"
}
],
"structuredContent": {
"choice": "Billing",
"confidence": 0.91,
"probabilities": { "Billing": 0.91 },
"request_id": "6f1c0b3e-1a2b-4c5d-8e9f-0123456789ab",
"other_label": "None of the named queues."
},
"isError": false
}
}

The text item and structuredContent carry the same five keys as POST /v1/decide.

When the decide path fails closed, the tool result has choice fail_closed and is not a JSON-RPC error. isError stays false.

{
"choice": "fail_closed",
"confidence": 0,
"probabilities": {},
"request_id": "6f1c0b3e-1a2b-4c5d-8e9f-0123456789ab",
"other_label": "None of the named queues."
}

What is stored from either call is in Security and data.