Analyzing and optimizing OpenCode agent injected tokens
Analyzing and optimizing OpenCode agent injected tokens
Key conclusion
OpenCode takes about 110,500 tokens as input on every request. Of that, conversation history is 91.5%, but the fixed injection (system prompt + rules + tool schema) is the base reused every time. Reducing the fixed injection raises the prompt cache hit rate and lowers total cost.
| Item | Before | After | Savings |
|---|---|---|---|
| System prompt | ~5,865 tok | ~5,865 tok | - (hardcoded) |
| Rule files | ~1,612 tok | ~1,612 tok | - |
| Tool schema | ~2,400 tok | ~2,400 tok | - |
| Fixed injection total | ~9,877 tok | ~9,877 tok | - |
OpenCode has a hardcoded binary, so the system prompt/tools are hard to reduce directly. Instead, cleaning up rule files and MCP servers is the key saving point.
1. Overall injection map
[System prompt] ~5,865 tok (5.3%) <- hardcoded in the binary
[Rule files] ~1,612 tok (1.5%) <- .clinerules + .instructions.md
[Tool schema] ~2,400 tok (2.2%) <- native + MCP
[Conversation history] ~101,200 tok (91.5%) <- accumulated in the session
-------------------------------------
Total ~110,500 tok (100%)
1-1. System prompt (~5,865 tok / ~23,458 chars)
Hardcoded in the OpenCode binary (~/.opencode/bin/opencode, 184MB). Contents:
- Role definition: "You are opencode, an interactive CLI tool..."
- Tone/style: concise, markdown, no emojis, answers within 4 lines
- Tool policy: prefer the Task tool, encourage parallel calls
- Code style: search priority, file_path:line_number reference pattern
- Task management: TodoWrite usage rules
This script cannot be edited directly โ it cannot be changed without rebuilding the binary.
1-2. Rule files (~1,612 tok)
| File | Size | Tokens | Content |
|---|---|---|---|
.clinerules | 1,860 bytes | ~1,306 tok | auto-run agent rules, web-search detail rules, weather lookup rules, chart generation rules |
.instructions.md | 551 bytes | ~306 tok | local AI dev environment (Ollama/MTP server info), code of conduct, task order |
| Total | 2,411 bytes | ~1,612 tok |
1-3. Native tools (~12)
Tools built into OpenCode. Usable without MCP.
| Tool | Use |
|---|---|
| bash | run shell commands |
| read | read files |
| edit | edit files (string replacement) |
| write | write files |
| grep | regex search |
| glob | file pattern matching |
| compress | compress conversation context |
| question | ask the user |
| task | call a subagent |
| skill | load a skill |
| webfetch | fetch URL content |
| todowrite | manage the task list |
1-4. MCP tools
Tools provided by MCP servers defined in opencode.json.
Direct connection (opencode.json):
| Server | Use | Active |
|---|---|---|
| proxy | multiple servers via mcp-proxy-supervisor.sh | Yes |
| tavily | web search (remote) | Yes |
| weather | weather lookup (wttr-mcp-server) | Yes |
| browseros | browser control (127.0.0.1:9201) | Yes |
Via proxy (mcp-proxy.json, lazy mode):
| Server | Tool count | Lazy |
|---|---|---|
| playwright | 20+ | Yes |
| ts (Token Savior) | 10+ | Yes |
| filesystem | 10+ | Yes |
| code-review-graph | 9 | Yes |
| smart-context | 15+ | Yes |
| web-search | 2 | Yes |
| weather | 1 | Yes |
Lazy mode behavior: only the bridge tools (tool_search, tool_describe, tool_call) are exposed up front. The actual server tools are loaded at the point of use.
1-5. tool-slim plugin
.config/opencode/plugins/tool-slim.js truncates tool descriptions:
- Tool description: limited to 80 chars
- Parameter description: 60 chars (top level), 40 chars (nested)
-> The clue that distinguishes tools disappears, which can cause the model to fail at tool selection.
2. Real measurements (production environment)
The figures below are real values extracted from the opencode DB for recent responses.
| Item | Tokens | Share |
|---|---|---|
| System prompt | ~5,865 | 5.3% |
| Rule files | ~1,612 | 1.5% |
| Tool schema | ~2,400 | 2.2% |
| Conversation history | ~101,200 | 91.5% |
| Total | ~110,500 | 100% |
- With prompt caching, the system prompt + tools are reused via cache_read (~106,752 tok cache hit)
- Tokenizer: cl100k_base (OpenAI-compatible)
- Korean: ~1.1 chars/token, English: ~4.5 chars/token
3. How to optimize
3-1. Diet the rule files (applies immediately)
.clinerules and .instructions.md can be edited directly by the user.
Current composition:
.clinerules(1,860 bytes): auto-run agent rules + web search + weather + chart.instructions.md(551 bytes): local AI environment info
Saving strategies:
| Strategy | Expected savings | Difficulty |
|---|---|---|
| Delete unnecessary rules (split out unused rules) | 200-500 tok | low |
| Convert to English (Korean 1.1 chars/tok to English 4.5 chars/tok) | 50-150 tok | medium |
| Remove repeated content | 50-100 tok | low |
Cautions:
- Deleting the MTP server address (127.0.0.1:18081) in
.instructions.mdbreaks the server connection - Deleting the chart generation rules makes the chart-render skill unusable
- A cache reset (session restart) is needed after rule changes
3-2. Clean up MCP servers (the biggest saving point)
Disabling unused servers out of the 7 in mcp-proxy.json reduces the tool schema.
Current MCP tool schema estimate:
| Server | Estimated tool count | Estimated schema size |
|---|---|---|
| playwright | ~20 | ~4,000 tok |
| ts (Token Savior) | ~10 | ~2,000 tok |
| filesystem | ~10 | ~1,500 tok |
| code-review-graph | ~9 | ~1,200 tok |
| smart-context | ~15 | ~3,000 tok |
| web-search | ~2 | ~300 tok |
| weather | ~1 | ~100 tok |
Candidates for disabling:
| Server | Usage frequency | Savings if disabled |
|---|---|---|
| code-review-graph | very low | ~1,200 tok |
| smart-context | low | ~3,000 tok |
| playwright | low | ~4,000 tok |
| filesystem | medium | ~1,500 tok |
How to disable: change the server block in mcp-proxy.json to "enabled": false.
Cautions:
- Disabling playwright makes browser automation impossible
- Disabling filesystem makes local file access via MCP impossible
- Since it is lazy mode, tools load only at use time, but the tool list is injected every time
- Always check the usage history of that server's tools before disabling
3-3. Adjust the tool-slim plugin
Increasing the truncation length in .config/opencode/plugins/tool-slim.js raises tool discrimination.
// current settings
const MAX_DESC_CHARS = 80; // tool description
const MAX_PARAM_CHARS = 60; // parameter description (top level)
const MAX_NESTED_PARAM = 40; // nested parameter
// proposal: widen the tool description to 120 chars
const MAX_DESC_CHARS = 120;
Effect: keywords in the tool description survive, improving the model's tool-selection accuracy.
Cautions:
- Making the truncation length too long increases token consumption
- 120-150 chars is the appropriate range
- After changing, verify the truncation behavior through the debug log
3-4. Manage conversation history
Since history is 91.5%, history management has the biggest impact on total tokens.
compaction settings (opencode.json):
"compaction": {
"auto": true
}
auto: true: when the context window fills, automatically summarize old turns- Summarization calls MiMo (an external model), so it costs money
History saving strategies:
| Strategy | Effect | Cost |
|---|---|---|
| Start a new session (/new) | reset to 0 immediately | none |
| Keep compaction.auto | automatic management in long sessions | MiMo call cost |
| Manual compression (compress tool) | selective compression when needed | none |
Key: compaction does not "delete content" but "replaces old turns with a summary." The total content does not shrink, but the injected token count does.
3-5. Direct MCP vs proxy comparison
The current structure goes through the proxy server; switching to a direct connection can reduce overhead.
| Structure | Pros | Cons |
|---|---|---|
| Direct (4 in opencode.json now) | minimal latency, stable | per-server management needed |
| Proxy (7 in mcp-proxy.json) | unified management, lazy loading | intermediate-layer overhead |
Recommendation: disabling unused proxy servers takes priority over switching to direct connections.
4. Cautions
4-1. Required checks before changing
- Check the list of MCP tools currently in use: review each MCP server tool's usage history in an
opencodesession - Back up rule files: back up
.clinerulesand.instructions.mdbefore changing - Test: verify normal operation with a simple task after the change
4-2. Required actions after changing
- Restart the session: rule/MCP changes only take effect in a new session
- Reset the cache: the prompt cache may remember the old settings
- Monitor: watch for an increase in the tool-selection failure rate
4-3. How to recover
| Change | Recovery |
|---|---|
| Edited rule files | restore from backup |
| Disabled MCP server | set enabled: true again |
| Changed tool-slim truncation length | revert to the original value |
4-4. OpenCode vs Hermes comparison
| Item | OpenCode | Hermes |
|---|---|---|
| System prompt | hardcoded in the binary (uneditable) | SOUL.md file (editable) |
| Tool disabling | MCP server level | toolset level |
| Rule files | .clinerules + .instructions.md | SOUL.md + memories/ |
| Skill system | loaded via the skill tool | 8 active skills (auto-injected) |
| compaction | automatic (delegated to MiMo) | manual setting possible |
| Fixed injection | ~9,877 tok | ~10,967 tok |
5. Checklist
- [ ] Check and clean up unused rules in
.clinerules - [ ] Delete unnecessary environment info from
.instructions.md - [ ] Disable unused servers in
mcp-proxy.json - [ ] Review the
tool-slim.jstruncation length (80 to 120 chars) - [ ] Verify normal operation after restarting the session
- [ ] Monitor the tool-selection failure rate
Measured in the operator's environment (opencode v1.x, cl100k_base tokenizer, Linux). Figures may differ by environment.
AI Knowledge Hub
Comments (1)
Review result: the injected-token dissection is very concrete โ only the component sum clashing with the total needs matching
To start from the conclusion, breaking the system prompt, rule files, tool schemas, and conversation history into token units, and covering lazy mode and tool-slim, is unusually concrete analysis. However, the item sum, the total, and the ratio sum do not match, and having Before and After in the same table blurs the point.
Suggested corrections
Further recommendations
What works