systemone-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., "@systemone-decision-mcpWhich MCP tools and skills should I use to find the auth function and check Fastify docs?"
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.
systemone-decision-mcp
An MCP server that tells an OpenCode agent which MCP tools and skills a task actually needs, before the agent starts calling them.
Decisions come from a remote decision model reached over an OpenAI-style API. When that model is unreachable, a deterministic engine answers instead, and every response says which engine produced it.
This is a usage guide. Architecture, configuration reference, and benchmark analysis live
in docs/.
What it changes
An agent with many MCP servers tends to fail in two ways. It answers a repository question with built-in grep and never opens the code graph, or it fires a web search at a question that any engineer could answer from memory. Both cost time and context.
This server makes the routing decision explicit for each task: which tools are worth calling, which are noise, and what priority each one carries.
Related MCP server: Agent Decision Kit
What it does not do
It cannot invoke, filter, or observe other MCP servers. MCP has no primitive for that, and any tool claiming otherwise is guessing. The agent performs the calls. The agent also reports them back if it wants an audit.
Recommendations are advice, not permission. OpenCode's own approval prompts still apply to every tool call.
Requirements
Node.js 20 or newer (built and tested on 24.11.1)
npm 9 or newer
OpenCode v2
An OpenAI-style decision endpoint: its URL, a model id, and a bearer token. Without all three the server still runs on the rule-based engine and labels every answer.
Install
git clone https://github.com/mhiqrambg/systemone-decision-mcp.git
cd systemone-decision-mcp
npm install
npm run build
npm run doctornpm run doctor checks the Node version, the environment variables, the endpoint, a
live round trip, the tool catalog, the skill index, and the OpenCode config it can read.
It exits 2 if any check needs attention.
Configure
Five values matter. Everything else has a default.
SYSTEMONE_API_KEY=
SYSTEMONE_ENDPOINT=https://your-host/v1/your-route
SYSTEMONE_MODEL=your-model-id
SYSTEMONE_DEFAULT_THRESHOLD=0.80
SYSTEMONE_REQUIRED_AT=0.93Copy .env.example to .env and fill in the key. The server and the CLI scripts load
.env automatically, from the working directory first and then from the project root. Real
environment variables always take precedence, so a shell export or OpenCode's environment
block overrides the file. Only keys starting with SYSTEMONE_ are accepted from it,
which stops a cloned .env from setting NODE_OPTIONS or PATH.
.env is gitignored. SYSTEMONE_NO_DOTENV=1 disables loading entirely, which is what the test
suite uses.
Full table: docs/CONFIGURATION.md.
Add it to OpenCode
Merge this into opencode.json. Do not replace the file.
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"systemone-decision": {
"type": "local",
"command": ["node", "/absolute/path/to/systemone-decision-mcp/dist/index.js"],
"enabled": true,
"environment": {
"SYSTEMONE_API_KEY": "{env:SYSTEMONE_API_KEY}",
"SYSTEMONE_ENDPOINT": "{env:SYSTEMONE_ENDPOINT}",
"SYSTEMONE_MODEL": "{env:SYSTEMONE_MODEL}"
}
}
}
}{env:SYSTEMONE_API_KEY} is OpenCode's own substitution, so the key never lands in the config
file. Use the full path to dist/index.js. On native Windows, escape the backslashes:
"C:\\Users\\you\\systemone-decision-mcp\\dist\\index.js".
Then copy examples/AGENTS.md into your AGENTS.md. That file tells
the agent when to call the router and what to do with the answer. Without it, the agent has
the tools and no reason to use them.
Confirm the server loaded:
opencode mcp listEight systemone_* tools should appear.
How to use it
Before a complex task
Call systemone_decide_tools with the user request. Include the servers you know are live in this
session, because OpenCode may enable MCP servers per agent rather than in the config file.
{
"user_query": "Find the authentication function in my repository and check whether it follows the latest Fastify documentation.",
"context": {
"available_mcp_servers": ["context7", "codebase-memory-mcp", "github", "media-9router"]
}
}A real response, trimmed:
{
"task_id": "7a3bd74c-e2fa-45c9-9da1-890aa713dfd5",
"decision_status": "success",
"decision_source": "model",
"model_used": "example-model-20260101",
"recommendations": [
{ "tool_id": "context7", "score": 0.98, "priority": "required", "threshold": 0.8 },
{ "tool_id": "codebase_memory", "score": 0.97, "priority": "required", "threshold": 0.8 },
{ "tool_id": "file_search", "score": 0.97, "priority": "recommended", "threshold": 0.75 },
{ "tool_id": "websearch", "score": 0.88, "priority": "recommended", "threshold": 0.8 }
],
"not_recommended": [
{ "tool_id": "codegraph", "score": 0.46 },
{ "tool_id": "web_fetch", "score": 0.28 }
],
"execution_guidance": [
"Use Context7 (required) for library_documentation and framework_documentation.",
"Use Codebase Memory (required) for repository_analysis and code_relationships."
],
"usage": { "input_tokens": 780, "output_tokens": 173, "cost": 0.00003276 }
}Read recommendations and stop there. Anything under not_recommended is a tool that would
have cost a call without adding evidence.
During the task
Call the tools marked required and recommended. Skip optional unless the call is cheap
and you expect it to pay off. Never call something listed under not_recommended for that
task.
If the response says decision_status: "no_tools_needed", answer directly. That status comes
from the capability classifier finding no requirement at all, which is the normal result for
definitions, explanations, and reasoning.
When you are unsure about one tool, call systemone_check_tool_need instead of a full decision. It
costs one question.
After the task
Report what you actually called:
{
"task_id": "7a3bd74c-e2fa-45c9-9da1-890aa713dfd5",
"executed_tools": ["codebase_memory"]
}{
"recommendation_utilization": 0.25,
"missed_recommendations": ["context7", "file_search", "websearch"],
"missed_required": ["context7"],
"warnings": ["context7 was marked required and was not executed; verify the result carefully."]
}A missed recommendation is a gap in evidence, not proof of failure. The task may have changed
shape halfway through. Treat missed_required as a reason to check the answer before handing
it over.
For a fuller report, call systemone_evaluate_result with the final answer text and, if the user
gave a verdict, user_reported_outcome. Task success stays unknown unless someone states
it. Tool-call counts are not treated as evidence of success.
The server remembers task_id in memory, so recommended_tools is optional within the same
process. After a restart, pass the list explicitly.
Skill routing
Call systemone_recommend_skills when the task looks like authoring, review, research, or a
specialised workflow. The server indexes SKILL.md frontmatter from the same directories
OpenCode reads, and returns names with paths.
Real response for a paper-writing request, four of 119 indexed skills:
{
"decision_source": "model",
"considered_count": 119,
"recommendations": [
{ "skill_name": "academic-paper", "score": 0.97, "priority": "required" },
{ "skill_name": "deep-research", "score": 0.96, "priority": "required" },
{ "skill_name": "ml-paper-writing", "score": 0.96, "priority": "required" },
{ "skill_name": "academic-pipeline", "score": 0.86, "priority": "recommended" }
]
}Load a recommended skill with OpenCode's native skill tool. This server never loads skill
bodies and never runs anything a skill mentions.
Reading a decision
Field | Meaning |
| The model's noul value, clamped to 0..1. A model signal, not a probability. |
|
|
| The number the score was compared against |
| Whether that number came from the tool, the category, or the global default |
|
|
|
|
| Always |
A score of 0.94 does not mean the tool is necessary 94 percent of the time. The required
label comes from a policy cutoff. If a tool it marked required turns out to be unhelpful,
raise required_at or the per-category threshold in your settings file.
Availability follows this order: an MCP server listed and enabled counts as available, a
server you passed in available_mcp_servers overrides the config either way, and built-in
tools stay builtin. A tool that is unavailable or disabled is never recommended.
Tool reference
Tool | Use it when |
| A task spans several domains or needs current information |
| The task resembles a workflow you may already have a skill for |
| You want the requirement breakdown without tool scoring |
| One tool, one decision |
| After the work, to compare plan against execution |
| After the work, for metrics plus stated limitations |
| You need to see what is installed and why a tool was skipped |
| You changed OpenCode config or added skills mid-session |
systemone_get_catalog with {"type": "tools", "availability": "disabled"} answers the most
common question during setup: why did nothing get recommended.
Troubleshooting
Every tool shows disabled. The config on disk sets enabled: false and the servers are
enabled per agent. Pass context.available_mcp_servers with the servers the session actually
has. Observed in practice: a config listing 2 of 17 servers as enabled while the running
session had all 17. The server warns about this when more than 70 percent of the catalog
resolves as disabled.
Every tool shows unverified. No OpenCode config was found from the server's working
directory. Set cwd in the MCP entry, or pass the server list explicitly.
Nothing is ever recommended. The capability classifier found no requirement. Check
capabilities.scores in the response. If a requirement you expected scored below 0.5, lower
capability_gate in your settings file.
decision_source says rule_based_fallback. A required value is missing or the model call failed. The
warnings array names the cause. Run npm run doctor.
Skills are missing from the index. SKILL.md must be capitalised, must sit in
<root>/<name>/, and the frontmatter name must equal the directory name.
Requests time out. Raise SYSTEMONE_TIMEOUT_MS or lower SYSTEMONE_MAX_QUESTIONS to shrink the second
stage.
Platform support
Platform | Status |
macOS (arm64, Node 24) | Verified: full suite, live model, benchmark |
Linux (Debian bookworm, Node 24, container) | Verified: full suite including the stdio integration test |
Windows via WSL2 | Expected to work. It is the verified Linux path, with the config locations OpenCode documents. |
Native Windows | Untested. Guards are in place, but no Windows machine was available. |
For native Windows: it reads %USERPROFILE%\.config\opencode first and also checks
%APPDATA%\opencode and %LOCALAPPDATA%\opencode. Config files starting with a UTF-8 BOM are
handled, since Notepad and Out-File add one. CRLF endings in config and in SKILL.md
frontmatter are handled. OpenCode's own docs recommend WSL, so use WSL unless you have a
reason not to.
Security
The key stays in memory and appears in no log, record, or error message. Logs go to stderr with redaction and stdout carries only MCP frames. Inputs are validated and length capped. Skill and config reads are confined to configured roots with 256 KB and 512 KB limits. Nothing discovered from a catalog or a skill is executed, and nothing writes to OpenCode configuration.
Benchmark
Nineteen tasks, three strategies, ground truth declared per case. The full result files are
committed under benchmark-output/, so the numbers below can be checked
against the raw data rather than taken on trust.
Run provenance:
Field | Value |
Generated | 2026-11-03T12:33:00Z |
Endpoint | configured, value not recorded |
Model | configured, value not recorded |
Runtime | Node 24.11.1, macOS arm64 |
Rows | 19 cases x 3 strategies = 57 |
Report files |
Reproduce it:
npm run benchmarkSummary
Strategy | Evaluated | Precision | Recall | F1 | Exact match | Unnecessary rate | Mean latency | Input tokens | Output tokens | Cost USD |
rule_based | 19/19 | 0.792 | 0.983 | 0.829 | 0.579 | 0.105 | 1 ms | 0 | 0 | 0 |
model | 19/19 | 0.814 | 1.000 | 0.871 | 0.474 | 0.075 | 2065 ms | 11604 | 1970 | 0.0005 |
adaptive | 19/19 | 0.796 | 1.000 | 0.845 | 0.474 | 0.092 | 1815 ms | 11604 | 1970 | 0.0005 |
Per-case results, model strategy
Case | Model recommendation | F1 |
| (none) | 1.00 |
| websearch | 1.00 |
| python, file_search | 1.00 |
| context7, websearch, web_fetch | 0.50 |
| database, python | 0.67 |
| semantic_scholar, websearch | 0.67 |
| python, pdf_processing, file_search | 1.00 |
| websearch | 1.00 |
| websearch, python, file_search | 1.00 |
| database | 1.00 |
| (none) | 1.00 |
| context7, codebase_memory, file_search, websearch | 0.67 |
| python | 1.00 |
| browser, web_fetch, websearch | 0.50 |
| (none) | 1.00 |
| context7 | 1.00 |
| semantic_scholar, context7, websearch, codebase_memory, python | 0.89 |
| file_search | 1.00 |
| websearch, context7 | 0.67 |
The CSV holds all 57 rows if you want the rule-based and adaptive results per case.
What the numbers mean, and what they do not
Precision counts a recommendation as correct only when the case listed it as required. That
is why core-04 scores 0.50: it found web_fetch plus two defensible extras. Recall of 1.000
means no required tool was missed in any case.
Exact match is the strict metric and it sits at 0.474. The router errs by adding a plausible tool, not by skipping a necessary one.
edge-04-disabled is a genuine miss. Asked to summarise a Notion page with Notion
unavailable, it recommended browser tools. The case is left visible rather than removed.
Task success is absent on purpose. Measuring it needs real executions and real user verdicts, and inventing it would make the rest of the table worthless.
Without a configured endpoint, model id, and key, the two model strategies are recorded as skipped, not scored.
Analysis, weak cases, and the three ground-truth revisions are in
docs/BENCHMARK.md.
Resource profile
Routing accuracy and machine cost are separate questions, measured separately. The routing benchmark answers "did it pick the right tools". This answers "what does the process cost".
npm run profileThe model is disabled for this run. Two sequential API calls per decision would make every number a measurement of the network. What remains is the cost this server adds on its own: catalog loading, skill indexing, capability gating, ranking, and record writing.
Latest run on an 8-core arm64 machine, Node 24.11.1:
Measurement | Value |
Total startup (catalog, skills, config, discovery, service) | 126 ms |
DecisionService.create | 50 ms |
Tool catalog load | 3 ms, 19 entries |
Skill index build | 69 ms, 119 skills |
OpenCode config discovery | 1.5 ms, 2 files |
Rule-based decision, p50 | 0.05 ms |
Rule-based decision, p95 | 0.13 ms |
Durability | 16,920 decisions per second |
CPU per decision | 0.13 ms (user + system) |
RSS after startup | 93 MB |
RSS at end of run | 109 MB |
Peak RSS | 109 MB |
Heap growth over 200 decisions | 0.16 MB |
Two things in that table need reading carefully.
Startup is dominated by the skill index, not the tool catalog. That is the cost of reading frontmatter from 119 directories, and it is paid once per process.
RSS rises 16 MB while heap stays flat. That is V8 growing its heap and code cache as the first decisions run, not a leak. The leak window measures heap used after a forced GC at iteration 50 and again at 250: 0.16 MB total, which is noise.
Raw data is in benchmark-output/resource-profile.json,
with the same values in CSV and Markdown. Run it yourself before trusting the MB figures:
resident memory depends on the platform allocator and on how many skills you have installed.
node --expose-gc dist/scripts/profile.js --iterations 200 --leak 1000Without --expose-gc the heap figures are noisy, and the report says so in its notes.
Limitations
Advisory only. No dynamic tool filtering and no automatic execution capture. Both need OpenCode plugin hooks that do not exist yet.
Two sequential model calls behind each decision, measured at 1.2 to 2.3 seconds per decision across runs.
Tool metadata is partly hand-written, because OpenCode config exposes server enablement and nothing about individual tools.
The adaptive strategy did not beat the model strategy on the current dataset.
Audit state is per process.
Commands
npm install
npm run build
npm test # unit, stdio integration, and a live model call when configured
npm run benchmark
npm run profile # local CPU and memory cost, model disabled
npm run doctor
npm run typecheck # src + tests, no emit
npm run lint # ESLint with typescript-eslint recommended rulesDocumentation
File | Contents |
Decision pipeline, availability model, what is not implemented | |
Every environment variable, catalog schema, skill roots | |
Metrics, results, weak cases, how to recalibrate | |
Agent instructions to paste into your | |
MCP entry to merge into your config |
License
MIT. See LICENSE.
Available Tools
8 toolssystemone_analyze_taskAnalyse task requirementsARead-only
Classify what a task requires (current information, documentation, repository access, files, computation, database, browser, literature) before deciding on tools. Cheap single-question-batch call.
| Name | Required | Description | Default |
|---|---|---|---|
| user_query | Yes | The user task to classify. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so safety is covered. The description adds cost/latency context ('Cheap single-question-batch call'), which is genuine value beyond annotations, but there is no output schema and no description of what the classification returns (boolean flags, labels, confidence), leaving a real gap for a classification tool.
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?
Two tightly written sentences with the purpose front-loaded and the enumerated categories doing useful work. 'Cheap single-question-batch call' is slightly cryptic and could be clearer about batching semantics, which is the only real flaw.
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?
For a single-parameter, read-only classification tool the description is largely sufficient: the enumerated categories effectively disclose the expected output dimensions even without an output schema. The missing piece is how that classification is returned and consumed, plus the unresolved meaning of 'batch.'
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?
Only one parameter and schema coverage is 100%, with the schema already stating 'The user task to classify.' The description adds only the notion of a 'single-question-batch call,' which is ambiguous about whether one or many queries may be supplied. Baseline 3 is appropriate since the schema carries the parameter burden.
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?
States a specific verb ('Classify') and the exact dimensions being classified (current information, documentation, repository access, files, computation, database, browser, literature), so the agent knows precisely what the call produces conceptually. It does not name the sibling it feeds into (systemone_decide_tools) explicitly, so sibling differentiation is implied rather than stated, keeping it below a 5.
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?
'before deciding on tools' gives a clear workflow position: this is the pre-step that precedes tool selection. There are no explicit exclusions or named alternatives, so an agent infers rather than is told which sibling to call afterward.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
systemone_audit_executionAudit recommendation usageA
Compare the tools this server recommended with the tools the agent reports having executed. Returns utilisation, missed recommendations, and unexpected tools. This server cannot observe other MCP servers, so the execution list must be supplied.
| Name | Required | Description | Default |
|---|---|---|---|
| task_id | Yes | task_id returned by systemone_decide_tools. | |
| priorities | No | ||
| executed_tools | Yes | Tools the agent actually called. | |
| recommended_tools | No | Omit to reuse the recommendations stored for this task_id. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description usefully discloses the return contents (utilisation, missed recommendations, unexpected tools) and the key limitation that cross-server calls are invisible. However, annotations declare readOnlyHint=false, so the call has side effects, and the description never says what is written or stored during the audit — a notable gap for a non-read-only tool.
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?
Three short sentences, front-loaded with the comparison action, then the outputs, then the one operational caveat. Every sentence carries information the agent needs.
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?
For a four-parameter tool with no output schema, the description covers the action, the returned artefacts, and the key input constraint. Missing only side-effect disclosure for the non-read-only annotation and any hint about the nested priorities parameter.
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?
It explains why executed_tools is mandatory and implies recommended_tools can be omitted in favour of stored recommendations, which adds real meaning beyond the schema. It says nothing about the nested priorities object or about how task_id ties to systemone_decide_tools beyond what the schema already documents; with 75% schema coverage, this is baseline-level.
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?
States a specific verb and resource: compares recommended tools against reported executed tools and returns utilisation, missed recommendations, and unexpected tools. This clearly separates it from siblings like systemone_decide_tools or systemone_recommend_skills, though it never names the alternative explicitly.
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 as a post-execution audit step and the description gives one hard constraint (the execution list must be supplied because the server cannot observe other MCP servers). It does not say when to prefer this over evaluate_result or what prerequisite call produces the task_id in prose, so guidance is adequate but incomplete.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
systemone_check_tool_needCheck whether one tool is neededBRead-only
Score a single tool against a task and say whether it clears its threshold. Use when the agent is unsure whether one specific MCP tool is worth calling.
| Name | Required | Description | Default |
|---|---|---|---|
| options | No | ||
| tool_id | Yes | Catalog tool id, e.g. context7 or codebase_memory. | |
| user_query | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish readOnlyHint=true and openWorldHint=true, so the safety profile is covered without the description. Beyond that, the description adds only the idea of a threshold comparison; it does not explain the scoring scale, what happens when options is omitted (is there a default threshold?), or what the verdict looks like. Useful context, but thin for a decision tool with no output schema.
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?
Two tight sentences, front-loaded with the action and followed by the usage trigger. No filler, though a single added clause about the threshold or return value would have cost nothing and closed real gaps.
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?
There is no output schema and the description does not describe the response beyond "whether it clears its threshold" — the score itself, its range, and any explanation field remain unknown. Combined with the undocumented user_query and options parameters, an agent still has to guess at core call semantics for what is a three-parameter, nested-object tool.
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 33%: only tool_id is documented in the schema, while user_query and the nested options.threshold have no descriptions. The description hints at a threshold but never says what it is applied to, how it defaults, or what user_query should contain (a raw user utterance? a summarized task?). With low coverage the description needed to compensate and largely does not.
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 names a specific verb and resource ("Score a single tool against a task") and states the output shape in prose ("say whether it clears its threshold"). The word "single" implicitly contrasts with the batch-oriented sibling systemone_decide_tools, but it never names any sibling, so the differentiation is suggestive rather than explicit.
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?
It gives a usable trigger condition: use when the agent is unsure whether one specific MCP tool is worth calling. That is a clear positive case, but there is no when-not guidance and no mention of the alternative (systemone_decide_tools / systemone_get_catalog) for tasks involving multiple tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
systemone_decide_toolsDecide which MCP tools to useARead-only
Analyse a user task and recommend the most appropriate available MCP tools, with scores, priority tiers, and deterministic reasons. Call this before complex or multi-step tasks. Returns no recommendations when the task needs no external tool.
| Name | Required | Description | Default |
|---|---|---|---|
| context | No | ||
| options | No | ||
| user_query | Yes | The user task to route. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint, so the safety profile is covered. The description adds real behavior beyond that: the response contains scores, priority tiers, and 'deterministic reasons', and an empty recommendation set is a valid outcome. It omits how discovery interacts with the available_mcp_servers override, but the core behavior an agent needs to decide is disclosed.
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?
Three short sentences, front-loaded with the action and followed by the call trigger and the empty-result caveat. No filler, though the output-shape sentence could be trimmed since it partly restates the name.
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?
There is no output schema, and the description only partially compensates by naming the return fields. With nested, sparsely documented parameters and a routing role that overlaps several siblings, an agent still lacks guidance on context/options usage and on how this differs operationally from check_tool_need.
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 only 33% and the schema is nested (context.project_type, context.working_directory, options.threshold, options.max_recommendations), yet the description never mentions context or options at all. Only user_query is effectively covered, via the schema's own 'The user task to route' and the phrase 'Analyse a user task', leaving the tunable threshold and recommendation cap unexplained in both places.
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?
States a specific verb ('recommend') and resource ('available MCP tools') and describes the output shape (scores, priority tiers, deterministic reasons), which separates it from catalog/audit siblings. It does not name which sibling to prefer over systemone_check_tool_need or systemone_analyze_task, so the differentiation is inferable rather than explicit.
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?
'Call this before complex or multi-step tasks' gives a clear trigger condition, and 'Returns no recommendations when the task needs no external tool' tells the agent the negative case exists. It stops short of naming alternatives for simple single-tool tasks, so the exclusion is implied rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
systemone_evaluate_resultEvaluate outcome and tool usageC
Report objective tool-usage metrics alongside explicit limitations. Task success is only reported when the user supplied an outcome; tool calls alone are never treated as proof of success.
| Name | Required | Description | Default |
|---|---|---|---|
| task | Yes | The original user task. | |
| task_id | Yes | ||
| final_result | No | The agent final answer, if available. | |
| executed_tools | Yes | ||
| recommended_tools | No | ||
| user_reported_outcome | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds one genuinely non-obvious rule beyond the annotations: task success is never inferred from tool calls alone, only from a user-supplied outcome. That meaningfully shapes how the agent should populate the outcome argument. However, annotations declare readOnlyHint=false, implying the call has side effects, and the description says nothing about what is written or returned; combined with no output schema, the behavioral picture is incomplete.
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?
Two tight sentences with the evaluative intent front-loaded and the key constraint second. No padding or redundancy. It is efficient, but efficiency is not offsetting for the missing detail elsewhere.
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?
For a six-parameter tool with no output schema and low schema coverage, the definition says far too little: the return shape of the 'metrics', the relationship between executed and recommended tools, and any side effects are all unstated. The one rule it does state is valuable, but a large share of what an agent needs to call this correctly is absent.
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 only 33% — task_id, executed_tools, recommended_tools, and user_reported_outcome carry no schema descriptions. The description partially clarifies the outcome parameter's semantics (success requires a user-supplied outcome), but says nothing about what executed_tools versus recommended_tools mean or how they should be formatted. With such a large coverage gap, the description should compensate and does not.
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 gives a verb and object ("Report objective tool-usage metrics"), but "metrics" and "explicit limitations" are vague about what is actually produced or evaluated. It does not distinguish this from sibling tools such as systemone_audit_execution or systemone_analyze_task, which sound closely related. The title helps somewhat, but an agent reading only the description would be unsure how this differs from an execution audit.
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?
There is no explicit when-to-use guidance, no prerequisites, and no mention of alternatives among the seven sibling tools. The statement about success only being reported when the user supplied an outcome is a behavioral rule, not a usage trigger. The agent must infer that this tool is for post-execution evaluation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
systemone_get_catalogShow tool and skill catalogARead-only
Return the tool catalog with resolved availability, the discovered skill index, and the OpenCode configuration sources that were read. Useful for explaining why a tool was not recommended.
| Name | Required | Description | Default |
|---|---|---|---|
| type | No | Defaults to all. | |
| category | No | ||
| availability | No | ||
| enabled_only | No | Defaults to true. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds useful disclosure about what the response contains and that config sources are surfaced, but says nothing about size, caching, or whether the catalog can be stale relative to refresh_catalog.
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?
A single front-loaded sentence naming the return contents, followed by one short clause on purpose. Nothing is redundant and nothing could be cut without losing information.
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?
With four optional parameters, no output schema, and a read-only annotation set, the description does the main remaining job: it tells the agent what the result contains. Only the category filter's purpose is left unexplained, which is a minor omission for a diagnostic tool.
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 only 50%, but the parameters are self-describing: 'type' and 'availability' are closed enums whose values convey their own meaning, and the two prose-documented fields already carry defaults in the schema. The description's mention of 'resolved availability' reinforces the availability enum, so the remaining gap (category's semantics) is narrow rather than disqualifying.
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?
States a concrete verb and resource ('Return the tool catalog') and enumerates what the payload contains: resolved availability, the skill index, and the config sources read. That is far more specific than its sibling systemone_refresh_catalog, though the description never explicitly contrasts the two.
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?
Provides one implied use case ('explaining why a tool was not recommended'), which is genuine context for when to reach for it. It gives no exclusions and never names the obvious alternative (systemone_refresh_catalog, which presumably rebuilds rather than reads the catalog), so the agent must infer the boundary.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
systemone_recommend_skillsRecommend OpenCode skillsARead-only
Rank the skills discovered on disk against a task and return the ones worth loading, with their SKILL.md path and a reason. Only metadata is read, never the skill body. The agent still loads the skill itself.
| Name | Required | Description | Default |
|---|---|---|---|
| options | No | ||
| user_query | Yes | The user task to match against discovered skills. | |
| available_skills | No | Restrict to these skill names. Omit to consider every discovered skill. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, but the description adds real context beyond them: only metadata is read, never the skill body, which tells the agent the call is cheap and avoids side effects on skill content. It also discloses the return payload shape (path plus reason). It stops short of explaining ranking/threshold behavior or what happens when nothing clears the bar.
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?
Three short sentences, front-loaded with the action and result, with each sentence adding a distinct fact (what it does, what it reads, what the caller must still do). No filler or repetition.
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?
For a read-only ranking tool with a nested options object and no output schema, the definition covers purpose and read scope but leaves the tuning parameters unexplained and gives no sense of result ordering count or empty-result behavior. Adequate, but an agent would still be guessing about threshold semantics.
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 67%, so the description's baseline is a 3. It reinforces that ranking happens "against a task" (pointing at user_query) and that recommendations are drawn from skills "discovered on disk," which loosely frames available_skills as a restriction. It says nothing about the nested threshold or max_recommendations options, which are the least documented 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?
"Rank the skills discovered on disk against a task and return the ones worth loading" names a specific verb (rank), the resource (discovered skills), and the matching criterion (a task), plus what comes back (SKILL.md path and reason). It is clearly distinguishable from siblings like systemone_get_catalog or systemone_refresh_catalog, which manage rather than rank the catalog.
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 agent still loads the skill itself" implies the two-step workflow: recommend here, then load separately, which is useful guidance. However, there is no statement of when to prefer this over systemone_analyze_task or systemone_decide_tools, and no exclusion or precondition guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
systemone_refresh_catalogRefresh discoveryA
Re-read OpenCode MCP configuration, the tool catalog, settings, and the skill index. Never writes to OpenCode configuration and never overwrites user-written catalog metadata.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only supply readOnlyHint=false and openWorldHint=false, leaving the mutation profile ambiguous. The description fills that gap by stating explicitly that it never writes OpenCode configuration and never overwrites user-written catalog metadata, which tells the agent what state is and is not at risk. It stops short of saying whether the rebuilt catalog replaces cached data or whether a refresh can fail mid-way.
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?
Two sentences, zero filler. The positive scope (what is re-read) comes first and the safety guarantees follow, which is the right ordering for a refresh operation.
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?
For a parameterless, non-open-world tool with no output schema, the description covers what is refreshed and what is protected, which is most of what an agent needs. The remaining gap is the absence of any trigger condition or mention of what the refreshed state looks like on return.
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 takes zero parameters, so there is nothing for the description to disambiguate and the baseline of 4 applies. No parameter-level meaning is missing because no parameter exists.
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 names a specific verb ("Re-read") and enumerates the exact resources refreshed: OpenCode MCP configuration, tool catalog, settings, and skill index. That is far more precise than the title "Refresh discovery," though it never distinguishes this operation from the sibling systemone_get_catalog, which an agent could easily confuse it with.
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?
There is no statement of when to call this tool, when not to, or which sibling to use instead. The clause about not writing configuration is a scope guarantee, not usage guidance, so an agent must infer the trigger condition (e.g. after config changes) entirely on its own.
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.
8 tool updates
v0.1.0- First observed
systemone_analyze_task - First observed
systemone_audit_execution - First observed
systemone_check_tool_need - First observed
systemone_decide_tools - First observed
systemone_evaluate_result - First observed
systemone_get_catalog - First observed
systemone_recommend_skills - First observed
systemone_refresh_catalog
TDQS
Scored across 8 tools
Most tools have clearly distinct purposes, but decide_tools, analyze_task, and check_tool_need all sit in the task-to-tool decision space and could require a moment to distinguish. The descriptions do clarify their scopes, keeping the overlap manageable rather than confusing.
Every tool uses the same systemone_ prefix followed by a snake_case verb_noun pattern. Names such as decide_tools, recommend_skills, analyze_task, and refresh_catalog are predictable and consistent.
Eight tools is well scoped for a decision/recommendation server, and each tool earns its place. There is no obvious filler or missing core operation from a count perspective.
The surface covers task analysis, tool and skill recommendation, single-tool checking, execution auditing, result evaluation, and catalog inspection/refresh. Minor gaps exist around managing settings or thresholds directly, but the key lifecycle is covered and intentional limitations are documented.
Maintenance
Related MCP Connectors
A paid remote MCP for OpenAI Codex agent coordination MCP, built to return verdicts, receipts, usage
Decision Layer for AI Agents — 58+ tools, Advisor, MCP. Free key: POST /v1/register {}.
MCP server for your apps' tools and custom tools, plus hosted AI agents and approval-gated workflows
The OpenRouter for tools. One MCP connection gives any AI agent 254 hosted tools, pay per call.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceEnables coding agents to use OpenType's calibrated decision, schema-validated verdict, and model routing tools through MCP.Apache 2.0
- AlicenseNot gradedqualityBmaintenanceEnables coding agents to make structured local decisions, choose bounded browser actions with approvals, and run coding workflows such as file relevance, context pruning, diff screening, and completion checks through MCP or CLI.Apache 2.0
- AlicenseNot gradedqualityAmaintenanceEnables agents and services to ask small decision models typed questions about text, JSON, images, or video, returning labels, scores, or yes/no answers over MCP tools or a Jev-compatible HTTP API.Apache 2.0
- AlicenseNot gradedqualityBmaintenanceEnables an agent to ask a System-1 decision engine which tool should answer a question, returning the winning choice with a confidence score, probability breakdown, and advice, plus a preset for routing code-structure questions and a generic mode for any user-supplied tool list.21 npmMIT