kev-decision-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@kev-decision-mcpEvaluate my decision options for the billing issue and permute the top choice."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Kev MCP Server
A small FastMCP adapter (stdio by default, optional streamable HTTP) exposing the Kev jev model (https://github.com/jaredpalmer/kev) pointer-head decision API (default http://127.0.0.1:8008, configurable via KEV_API_BASE_URL) as four agent tools. The model identifier is intentionally fixed to kev-latest from https://github.com/jaredpalmer/kev for decision calls; this is not a text-generation interface.
Tools
state may be any JSON value (string, object, list, number, boolean, or null); it is passed to Kev unchanged.
kev_evaluate(state, questions): POST/v1/systemone; returns the upstream JSON object, including answers, usage, andlatency_ms.kev_permute(state, questions, question, n_perm=6, seed=0): POST/v1/systemone/permute. The API requires its documented wrapper{request, question, n_perm, seed}. Supply exactly one Choice question and its key asquestion;n_permis 1–64.kev_separate(state, questions): POST/v1/systemone/separate.kev_list_models(): GET/v1/models.
Related MCP server: RepoPulse MCP Server
Question types
questions maps answer keys to typed question objects following the Kev API schema. Several questions can be packed into one kev_evaluate call; answers come back under the same keys.
Type | Question object | Answer fields |
|
|
|
|
|
|
|
|
|
Example request questions and the corresponding answer:
{
"issue": {
"type": "choice",
"instructions": "Issue?",
"criteria": {
"billing": "Duplicate charge",
"other": "Other"
}
}
}{
"issue": {
"type": "choice",
"choice": "billing",
"confidence": 0.6,
"probabilities": {"billing": 0.8, "other": 0.2}
}
}confidence is a separate model signal, not the top probability (for example, a confidence of 0.27 has been observed when the top probability was 0.45). Base decision thresholds on probabilities (or noul/score), not on confidence.
Transport timeouts, connection errors, HTTP errors, invalid JSON, and unexpected non-object API responses are surfaced as tool errors with concise context. Default HTTP timeout is 60 seconds (5 seconds to connect); a single HTTP client is reused across calls. No credentials are embedded.
Configuration
Variable | Default | Purpose |
|
| Kev API origin. Set this when Kev runs on another machine, e.g. |
|
| MCP transport: |
|
| Bind host for |
|
| Bind port for |
| unset | Optional bearer token for |
| unset | Path to a file containing the bearer token (whitespace trimmed). Used when |
| unset | Comma-separated extra |
| unset | Comma-separated extra |
Command-line flags take precedence over environment variables.
Install and run
Requires Python 3.10+ and uv (or another PEP 517 package installer).
git clone https://github.com/HappyMonkeyAI/kev-decision-mcp.git
cd kev-decision-mcp
uv sync
uv run kev-mcp-serverBy default the server uses stdio transport and should be started by an MCP host, not run in a shell by itself. To use Python directly after installing dependencies:
uv run python -m kev_mcp_server.serverIf Kev is not on the same machine, point the adapter at it:
KEV_API_BASE_URL=http://192.168.5.157:8008 uv run kev-mcp-serverStreamable HTTP (optional)
To serve MCP over the network instead of stdio:
uv run kev-mcp-server --transport streamable-http # http://127.0.0.1:8765/mcp
KEV_MCP_TRANSPORT=streamable-http \
KEV_MCP_HOST=0.0.0.0 \
KEV_MCP_PORT=8765 \
KEV_MCP_ALLOWED_HOSTS=192.168.5.80:8765 \
uv run kev-mcp-serverThe MCP endpoint is /mcp. Authentication is off unless KEV_MCP_AUTH_TOKEN or KEV_MCP_AUTH_TOKEN_FILE is set (the server logs a warning when HTTP runs without a token). With a token, every request must carry Authorization: Bearer <token> (compared in constant time); anything else gets 401 with a JSON body. Keep the default 127.0.0.1 bind unless you need remote clients, and only bind to 0.0.0.0 (or a LAN address) on a trusted network. Non-loopback binds require KEV_MCP_ALLOWED_HOSTS, a comma-separated list of exact Host header values accepted by FastMCP (for example, 192.168.5.80:8765). Host and Origin validation remains enabled to protect against DNS rebinding; set the optional comma-separated KEV_MCP_ALLOWED_ORIGINS when browser clients need specific origins. Requests without an Origin header are allowed by FastMCP.
Sharing over a Cloudflare quick tunnel
A Cloudflare quick tunnel gives the local HTTP server a public https://<random>.trycloudflare.com URL without opening any ports. Always set a token first, and keep the server bound to loopback:
mkdir -p ~/.config/kev-mcp
python3 -c 'import secrets; print(secrets.token_urlsafe(32))' > ~/.config/kev-mcp/token
chmod 600 ~/.config/kev-mcp/token
KEV_MCP_TRANSPORT=streamable-http \
KEV_MCP_HOST=127.0.0.1 \
KEV_MCP_PORT=8765 \
KEV_MCP_AUTH_TOKEN_FILE=~/.config/kev-mcp/token \
uv run kev-mcp-server
# in another shell
cloudflared tunnel --no-autoupdate --url http://127.0.0.1:8765 --http-host-header 127.0.0.1:8765cloudflared prints the public hostname; the MCP URL is https://<name>.trycloudflare.com/mcp. Clients must send Authorization: Bearer <token>.
Why --http-host-header: cloudflared forwards the public Host header (<name>.trycloudflare.com) by default, and FastMCP's DNS-rebinding protection on a loopback bind only accepts 127.0.0.1:*, localhost:* and [::1]:*, so requests would fail with 421 Invalid Host header. Rewriting the Host header to 127.0.0.1:8765 keeps protection on without having to reconfigure the server each time a quick tunnel gets a new random hostname. (Alternatively, add the hostname to KEV_MCP_ALLOWED_HOSTS, which extends the loopback defaults, e.g. for a named tunnel with a stable hostname.) Browser-based clients that send an Origin header also need that origin in KEV_MCP_ALLOWED_ORIGINS.
Quick tunnels are intended for testing: the hostname changes whenever cloudflared restarts and there is no uptime guarantee. The bearer token is the only access control, so treat it like a password and rotate it (rewrite the file and restart the server) if it leaks.
Register with Hermes
Add this entry to ~/.hermes/config.yaml under mcp_servers (merge it with existing entries):
mcp_servers:
kev:
command: "/home/user/kev-decision-mcp/run-stdio.sh"
timeout: 90
connect_timeout: 30The executable wrapper pins the stdio launch command and avoids argument-list serialization differences between Hermes versions. The server has already been registered in this Hermes profile using:
hermes config set mcp_servers.kev.command /home/user/kev-decision-mcp/run-stdio.sh
hermes mcp test kevOther MCP hosts can launch the same stdio command directly. For Claude Desktop, use this server entry in its MCP config:
{
"mcpServers": {
"kev": {
"command": "uv",
"args": ["--directory", "/home/user/kev-decision-mcp", "run", "kev-mcp-server"]
}
}
}Verification
uv run pytest
uv run python -m compileall -q src tests
uvx --from 'fastmcp<3' fastmcp inspect src/kev_mcp_server/server.py:mcp
hermes mcp test kevAutomated tests mock the HTTP API. A successful local test does not guarantee the upstream model is reachable; the server was also exercised through MCP against the live API for each tool during implementation.
Available Tools
4 toolskev_evaluateA
Evaluate a decision state using Kev's pointer-head model; several questions may be packed into one call.
state is any JSON value (string, object, list, number, bool, or null) describing the situation.
questions maps answer keys to typed question objects:
choice: {type:'choice', instructions?, criteria:{name: description}} -> {choice, probabilities, confidence}
score: {type:'score', instructions?, criteria:[ordered labels, 1-255 items]} -> {score (probability-weighted expected value), legend, probabilities, confidence}
noul: {type:'noul', instructions?, criteria?} -> {noul: probability of yes, 0-1}
confidenceis a separate model signal, not the top probability (e.g. 0.27 when the top probability was 0.45), so base decision thresholds onprobabilities. Returns the upstream model, answers (keyed like questions), usage, and latency_ms.
| Name | Required | Description | Default |
|---|---|---|---|
| state | Yes | ||
| questions | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
There are no annotations, so the description carries the full behavioral disclosure burden. It explains the three question modes with their return shapes, explicitly warns that confidence is a separate signal from the top probability, and describes the high-level return fields (upstream model, answers, usage, latency_ms). This goes well beyond a minimal description.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Though longer than average, the description is dense and well-structured with bullets and code-formatted types. The main purpose is front-loaded, followed by parameter semantics, a key caveat, and return information. Every sentence adds necessary value, and the length is justified by the tool's complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the sparse schema and lack of annotations, the description is remarkably complete. It covers all valid question types, the meaning of each output field, the confidence caveat, and the overall response structure. The output schema exists, but the description adds essential interpretation details and usage nuances, leaving no major invocation gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 0% description coverage, and the description fully compensates. It defines 'state' as any JSON value and documents the 'questions' object with concrete formats for choice, score, and noul questions, including output fields. An agent can construct a valid call without needing additional parameter documentation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb ('Evaluate') and a clear resource ('a decision state using Kev's pointer-head model'). It also states that several questions may be packed into one call and enumerates the three question types, so an agent can immediately distinguish this from sibling tools like kev_list_models or kev_permute.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context: use this tool when you need to evaluate a decision state with Kev's pointer-head model, and it even advises that multiple questions can be packed into a single call. However, it does not explicitly mention sibling alternatives or state when not to use this tool, so it lacks full exclusionary guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
kev_list_modelsA
List Kev models and metadata such as device, temperature, and prefix-cache statistics.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It does convey that the tool lists models and metadata, implying a read-only operation, but it does not explicitly state side-effect safety, authentication requirements, or list behavior (e.g., pagination, ordering). This is adequate but not rich.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single concise sentence that front-loads the core action ('List Kev models') and then adds valuable metadata examples. Every word earns its place, with no redundancy or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given zero parameters, an existing output schema, and a simple list operation, the description is nearly complete. It covers what is returned at a high level and would allow an agent to invoke the tool correctly, though it could mention output shape or pagination if applicable.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters and the schema is empty, so the baseline for 0 parameters is 4. The description does not need to explain parameter behavior since none exist; it appropriately focuses on the tool's action.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific verb ('List') and resource ('Kev models'), and adds concrete metadata examples (device, temperature, prefix-cache statistics). This distinctly differentiates it from the sibling tools (kev_evaluate, kev_permute, kev_separate), which suggest different operations.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives like kev_evaluate, kev_permute, or kev_separate. There is no explicit 'when to use' or 'when not to use' context, leaving the agent to infer from the tool name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
kev_permuteA
Evaluate one Choice question under multiple option orders to check order sensitivity.
state is any JSON value (string, object, list, number, bool, or null). questions must contain exactly
one question of type 'choice' ({type:'choice', instructions?, criteria:{name: description}}) and
question must be its key; n_perm is 1-64 and seed controls reproducibility.
| Name | Required | Description | Default |
|---|---|---|---|
| seed | No | ||
| state | Yes | ||
| n_perm | No | ||
| question | Yes | ||
| questions | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses key constraints: state can be any JSON value, questions must contain exactly one choice question, n_perm is 1-64, and seed controls reproducibility. However, it does not describe what the tool returns, whether it mutates state, or how errors/invalid input are handled.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded with the main purpose. The parameter constraints are packed into two later sentences without unnecessary filler. It could be slightly more structured, but every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given that an output schema exists and the description fully explains the parameters and input constraints, an agent has enough to invoke the tool correctly. The only real gap is lack of explicit behavioral details about output/error cases, but the output schema mitigates that.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, but the description compensates thoroughly. It explains that state accepts any JSON value, questions must be an object with exactly one choice question of the specified shape, question must be that question's key, n_perm is bounded 1-64, and seed controls reproducibility. This gives meaningful semantics for all five parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Evaluate') and resource ('one Choice question under multiple option orders') and states the goal ('check order sensitivity'). It clearly indicates this is a specialization of evaluation, though it does not explicitly name sibling alternatives like kev_evaluate.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied: this tool exists for testing order sensitivity of a Choice question. However, the description does not explicitly say when to prefer this over kev_evaluate or kev_separate, nor does it state any exclusions, so the agent must infer the boundary from the sibling names.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
kev_separateA
Evaluate each question independently against the same state for a packed-vs-separate comparison.
state is any JSON value (string, object, list, number, bool, or null). questions uses the same
format as kev_evaluate: choice {type:'choice', instructions?, criteria:{name: description}},
score {type:'score', instructions?, criteria:[ordered labels, 1-255 items]}, or
noul {type:'noul', instructions?, criteria?}. Base thresholds on probabilities, not confidence.
| Name | Required | Description | Default |
|---|---|---|---|
| state | Yes | ||
| questions | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses that thresholds should be based on probabilities, not confidence, and explains the state format. However, it does not explicitly state whether the tool is read-only or has side effects, nor does it describe the return format. The evaluation nature implies no mutation, but this is not stated. Moderate behavioral transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two concise paragraphs. The primary purpose is front-loaded, followed by the parameter specifics. It avoids fluff and every sentence adds value. It could be slightly more structured (e.g., bullet points), but it remains efficient and readable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (nested question objects, multiple types, threshold guidance) and the absence of annotations, the description covers the essential usage details. An output schema exists, so return values need not be described. It explains how to construct questions and the key behavioral rule about thresholds. Minor gaps like error handling or explicit read-only status are acceptable given the output schema and sibling context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0% and the schema is generic (state with no type, questions as arbitrary object). The description thoroughly defines state as any JSON value and details the exact structure of questions, including types (choice, score, noul) and criteria formats. This provides essential meaning that the schema completely lacks.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: evaluate each question independently against the same state, for a packed-vs-separate comparison. It names a specific verb (evaluate), resource (questions against state), and the distinguishing purpose (separate comparison). This differentiates it from siblings like kev_evaluate without ambiguity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives context by mentioning 'packed-vs-separate comparison' and explicitly links the questions format to kev_evaluate, implying when this variant is appropriate. It lacks an explicit exclusion ('use this instead of X when...'), but the purpose statement effectively routes an agent to the correct tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
4 tool updates
v0.1.0- First observed
kev_evaluate - First observed
kev_list_models - First observed
kev_permute - First observed
kev_separate
TDQS
Scored across 4 tools
Each tool has a distinct purpose: listing models, standard evaluation, order-sensitivity testing, and packed-vs-separate comparison. The three evaluation tools share a common foundation but are clearly differentiated by their constraints and outputs, though they could still be confused without careful reading.
All tools follow a consistent kev_<verb> snake_case pattern, making the set predictable and uniform. The verbs (list, evaluate, permute, separate) are domain-specific but consistently applied.
Four tools is well-scoped for a decision evaluation server. Each tool adds a distinct capability—model discovery, packed evaluation, order sensitivity, and independent evaluation—without redundancy or bloat.
The decision evaluation domain is fully covered: model metadata, packed evaluation supporting multiple question types, order-sensitivity checking, and independent evaluation for comparison. There are no obvious missing operations or dead ends for the stated purpose.
Maintenance
Related MCP Connectors
Deterministic AI agent microtools, no accounts/API keys. fetch_extract: 98% token cut. 38 tools.
Deterministic reasoning stack for AI agents: simulate, decide & compute, plus cross-domain tools.
Calibrated world model for AI agents. 40 tools: world state, markets, trading. Kalshi + Polymarket.
Decision Layer for AI Agents — 58+ tools, Advisor, MCP. Free key: POST /v1/register {}.
Related MCP Servers
- FlicenseAqualityCmaintenanceEnables an LLM client to perform basic arithmetic on two numbers — addition, subtraction, multiplication, and division — plus reverse a supplied text string, through five simple tools exposed over stdio. Inputs and structured text results follow JSON schemas, with invalid operations such as division by zero surfaced as tool errors.5-
- AlicenseNot gradedqualityBmaintenanceExposes code-review and issue-triage tools to AI assistants over stdio, letting them evaluate unified pull-request diffs for maintainer remarks, slice diffs into categorized AST hunks, and classify GitHub issues by priority while synthesizing minimal reproduction stubs.1Apache 2.0
- AlicenseAqualityCmaintenanceProvides AI clients with real-time tools for math evaluation, timezone-aware time lookup, live weather retrieval, and persistent note management, all accessible over the Model Context Protocol via stdio.6MIT
- AlicenseNot gradedqualityAmaintenanceEnables natural-language interaction with TypeSafe's Jev decision API, supporting mixed question calls, batch evaluation, model listing, and confidence or composite-score gates over stdio.7MIT