
jackandjac/token-saver-mcp-java
Developer toolsMCP server that delegates simple Claude Code / Codex / Wibey tasks to a local LLM via langchain4j and langgraph4j.
Overview
An MCP server that lets Claude Code / Codex / Wibey (or any MCP-compliant coding agent) delegate simple, well-scoped tasks to your local LLM — code snippets, isolated refactors, documentation, code reviews, basic Q&A — so you spend premium tokens on coordination and architecture, not on work a local model can already do. This is a complete rewrite in Java on langchain4j (local LLM client), langgraph4j (orchestration), and the official MCP Java SDK (stdio server). Credit for the original idea and the Python/FastMCP prototype goes to csabakecskemeti/cc_token_saver_mcp — this project builds on that concept with a graph-based classify/delegate/escalate flow, server-side file reading, timeouts, and actionable errors. The server exposes two MCP tools — query_local_llm and query_local_llm_with_context — that Claude Code is instructed to try first for simple subtasks.
README
Token Saver MCP Java
An MCP server that lets Claude Code / Codex / Wibey (or any MCP-compliant coding agent) delegate simple, well-scoped tasks to your local LLM — code snippets, isolated refactors, documentation, code reviews, basic Q&A — so you spend premium tokens on coordination and architecture, not on work a local model can already do.
This is a complete rewrite in Java on langchain4j (local LLM client), langgraph4j (orchestration), and the official MCP Java SDK (stdio server).
Credit for the original idea and the Python/FastMCP prototype goes to csabakecskemeti/cc_token_saver_mcp — this project builds on that concept with a graph-based classify/delegate/escalate flow, server-side file reading, timeouts, and actionable errors.
How it works
The server exposes two MCP tools — query_local_llm and query_local_llm_with_context — that Claude Code is instructed to try first for simple subtasks. Every call runs through a small langgraph4j graph instead of just forwarding straight to the model:
START -> classify -> delegate -> END (task judged within the local model's competence)
\-> escalate -> END (task judged too complex; local LLM never called)
classify makes a cheap, low-temperature call to the local model to judge whether the task is actually simple enough for it. If not, escalate returns a structured ESCALATE: ... message telling Claude Code to handle the task itself — so a task that’s too complex for the local model comes back as a clear signal, not a low-quality answer.
Features
- Server-side file reading. Both tools accept an optional
file_pathsarray. The server reads the files itself and passes their content straight to the local LLM — Claude Code passes a path instead ofRead()-ing the file into its own context first. This is where the real token savings on large files come from. - Bounded waits. Both tools accept an optional
timeout_seconds(default fromLOCAL_LLM_TIMEOUT_SECONDS), enforced with a hard timeout around the call so a stalled local backend can’t hang a tool call indefinitely. - Actionable errors. Backend failures (connection refused, unreachable host, timeout) come back as a clear message naming the configured URL and the next step — e.g. “Local LLM backend unreachable at http://127.0.0.1:8000/v1. Check that it’s running…” — with
isError: trueset correctly, instead of a raw exception string. - Thinking-mode control. Qwen3-style reasoning models can burn hundreds of tokens on a hidden chain-of-thought preamble before answering (measured: ~46s/228 tokens for a trivial “say hello” vs ~1s/1 token with it off).
LOCAL_LLM_ENABLE_THINKING(defaultfalse) passeschat_template_kwargs.enable_thinkingthrough to the backend. The internal classifier always runs with thinking off regardless of this setting, since a one-word verdict never needs it. No-op on models/backends that don’t recognize the field.
Requirements
- Java 17+
- Maven
- A local OpenAI-compatible LLM server (LM Studio, Ollama, vLLM, MLX, etc.)
Build
mvn -q package
Produces a single runnable jar at target/token-saver-mcp-java.jar.
Configuration
Create a .env file next to pom.xml:
# Local LLM Configuration
OPENAI_API_KEY=none
OPENAI_BASE_URL=http://127.0.0.1:8000/v1
LOCAL_MODEL_NAME=Qwen3.6-35B-A3B-8bit
LOCAL_LLM_TEMPERATURE=0.7
LOCAL_LLM_TOP_P=0.80
LOCAL_LLM_MAX_TOKENS=32768
LOCAL_LLM_TIMEOUT_SECONDS=60
LOCAL_LLM_ENABLE_THINKING=false
.env is resolved relative to the jar’s own install directory, not the process’s working directory, so it’s found correctly even when ~/.claude.json launches the jar from an arbitrary project folder. Real environment variables (e.g. set directly in the ~/.claude.json server entry) take precedence over .env.
Register with your coding agent
This is a standard stdio MCP server built on the official MCP Java SDK — nothing here is Claude-Code-specific, so any MCP-compliant client that can spawn a subprocess and speak JSON-RPC over stdin/stdout can use it.
Claude Code
Either edit ~/.claude.json directly:
"mcpServers": {
"token-saver": {
"type": "stdio",
"command": "java",
"args": ["-jar", "/token-saver-mcp-java/target/token-saver-mcp-java.jar"]
}
}
or use the CLI, which validates the config for you (--scope user makes it available across all your projects, not just this one):
claude mcp add --scope user token-saver -- java -jar /token-saver-mcp-java/target/token-saver-mcp-java.jar
Codex CLI
Add to ~/.codex/config.toml (or .codex/config.toml in a trusted project, to scope it to that project only):
[mcp_servers.token-saver]
command = "java"
args = ["-jar", "/token-saver-mcp-java/target/token-saver-mcp-java.jar"]
Other MCP clients
Point any MCP-compliant client (Wibey, or others) at the same stdio command — java -jar /token-saver-mcp-java/target/token-saver-mcp-java.jar — following that client’s own server-registration mechanism.
Tools
query_local_llm — prompt (required), file_paths, system_message, temperature, max_tokens, timeout_seconds (all optional).
query_local_llm_with_context — prompt (required), context and/or file_paths (at least one required), task_type (code_review | documentation | refactor | general), system_message, timeout_seconds (all optional).
Install
This server does not publish a one-line install command.
Open the repository installation guide New to MCP? Start with the mcpskill.org guide →Configuration
"mcpServers": {
"token-saver": {
"type": "stdio",
"command": "java",
"args": ["-jar", "<path>/token-saver-mcp-java/target/token-saver-mcp-java.jar"]
}
}