MCP
Six tools, one decision each.
A remote plug for agents. After connect, the agent sees jev_* tools and calls one when it needs a typed branch. The tool does not replace the agent’s main model.
https://jevai.ai/api/mcp. Protocol 2025-03-26, stateless Streamable HTTP. initialize, ping, and tools/list do not call Jev. tools/call does, and it needs your TypeSafe key.Connect
[mcp_servers.jevai] url = "https://jevai.ai/api/mcp" bearer_token_env_var = "JEV_API_KEY" tool_timeout_sec = 30
Use HTTPS on the apex host. The Bearer value is your TypeSafe key.
Tools
| Tool | When | Decision |
|---|---|---|
jev_guard_tool_call | Immediately before a side effect | allow, confirm, review, deny |
jev_route_model | Several models could run the task | one of the ids you passed |
jev_route_task | The task might be risky or muddy | proceed_fast, deep_review, split_task, block |
jev_check_research | Evidence is already in hand | supported, mixed, unsupported, insufficient |
jev_review_completion | Before saying the job is done | complete, partial, not_done, blocked |
jev_decide | No preset fits | your own choice, score, and noul questions |
The result’s structuredContent is the TypeSafe response plus meta.questions, so you can see the exact questions that were asked. Treat probabilities as a signal. Your code still chooses the threshold.
Fields match the REST presets on the API hub.
Handshake
initialize, ping, and tools/list do not touch Jev and do not spend quota. tools/call does. Protocol version is 2025-03-26. The server is stateless: there is no session id to keep.
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "jev_route_task",
"arguments": {
"task": "Customer pasted a stack trace and asks why Apple Pay checkout returns 500.",
"stakes": "Production checkout"
}
}
}
Send Authorization: Bearer with the TypeSafe key on that call. The result has content[0].text as a JSON string and the same object on structuredContent. isError is true when TypeSafe rejects the call or the arguments do not match the tool. An unknown tool name is an error result, not a transport failure.
What the agent should do with it
- Call one tool at the branch, not all six “just in case.” Fan-out belongs inside a single
jev_decidewhen the questions share a state. - Read
meta.questionsif a decision looks wrong. That is the exact choice, score, or noul the preset compiled. Fix the fields you sent before you blame the model. - Apply your threshold in the agent, after the tool returns. A choice of
allowwith low confidence is not an allow. - Do not ask these tools to draft the user-facing message. They will not. They return a decision.
Limits
Decision calls are capped at 30 a minute per IP on this host, separate from TypeSafe’s own limits. Bodies over the proxy cap are rejected before they are forwarded. Model ids other than Jev are rejected. Timeouts surface as an error result rather than a hang: the upstream call is cut at 35 seconds, which is far past a normal Jev response.