Skip to main content

The MCP server

jevlin mcp serves the machine paths as Model Context Protocol tools over stdio, for a host that prefers MCP to a shell skill. It runs only while a host holds it open, and setup does not register it.

A host starts jevlin mcp and holds it open: newline-delimited JSON-RPC 2.0 on stdin and stdout, and it ends when the host closes its stdin. stdout carries nothing but protocol messages.

The four tools​

toolrunsarguments
searchjevlin search --stdinThe stdin request
fetchjevlin fetch --stdinReading a page in full
decidejevlin decide --stdin, where the router offers decisionsDecisions
decide_modelsjevlin decide --modelsNone: {} or absent

How a call is answered​

whatvalue
A tool's argumentsThe --stdin request for that command; version may be left out. Each tool's input schema has exactly the request's fields.
The answerThe envelope --stdin prints, as the result's one text item and, from protocol revision 2025-06-18 on, as structuredContent too.
A refused request, or a call before setup or without a keyA tool result with isError set and that envelope's code and action. The server keeps running.
Protocol revisions2025-11-25, 2025-06-18, 2025-03-26 and 2024-11-05.
OrderOne request at a time, in the order they arrive.
The traceharness is mcp:<name>, the client's own name (mcp when the name is not a plain token), with one session per host process. JEVLIN_HARNESS, when the host's environment sets it, takes precedence.
-logOne line per message on stderr, naming the method, the tool and the outcome code, never what a request carried.
-config fileAs for every command; add it after mcp for an installation other than the machine's own.

The tools answer a field in another case, or a VERSION key, as the commands do: unknown_field, and the router is never called. The decide tool hands jevlin decide the arguments as the caller wrote them, with "version": 1 in front when they carry none, so state and questions reach the router byte for byte.

A decide call, and the start of its result (the text item carries the same envelope, on one line):

{"jsonrpc":"2.0","id":7,"method":"tools/call","params":{"name":"decide","arguments":{
"model":"vendor/model","state":{"page":"…"},"questions":{"kind":{"type":"choice","instructions":"…"}}}}}
{"jsonrpc":"2.0","id":7,"result":{"content":[{"type":"text","text":"{\"version\":1,\"command\":\"decide\",…}"}],
"structuredContent":{"version":1,"command":"decide","ok":true,…,"result":{"answers":{
"kind":{"type":"choice","choice":"docs","probabilities":{"blog":0.09,"docs":0.91},"confidence":0.88}},…}}}}

Registering it​

Setup does not register the server. To add it by hand, with jevlin on the host's PATH (or its full path in its place):

hosthow
Claude Codeclaude mcp add jevlin -- jevlin mcp
Codex, in ~/.codex/config.toml[mcp_servers.jevlin], then command = "jevlin" and args = ["mcp"]
Cursor, in ~/.cursor/mcp.json{"mcpServers": {"jevlin": {"command": "jevlin", "args": ["mcp"]}}}

Each host's page shows the same lines under MCP instead of the skill: Claude Code, Codex, Cursor.