polycode
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., "@polycode Start a new opencode session and implement a binary search."
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.
A production-grade MCP (Model Context Protocol) server exposing 13 tools that let Claude Code (or any MCP client) control three AI coding agents — opencode, Gemini CLI, and Qwen Code — with full session continuity, auth checking, and structured error handling.
How It Works
Claude Code (or Gemini CLI / Qwen Code)
│ calls tools (MCP stdio)
▼
polycode server (this package — auto-started by the MCP client)
│
├── spawns opencode serve → talks to any of 182 models via opencode
├── invokes gemini CLI → Gemini API with session continuity
└── invokes qwen CLI → Qwen API with session continuityThe MCP client (Claude Code, Gemini CLI, Qwen Code) auto-starts this server when the session begins. You never start it manually.
Related MCP server: personal-mcp
Requirements
Python 3.11+
python --versionopencode CLI — for the
opencode_*toolsnpm install -g opencode-ai opencode --version # should print 1.x.xGemini CLI — for the
gemini_*tools (optional)npm install -g @google/gemini-cli gemini --version # should print 0.36.x or higherQwen Code CLI — for the
qwen_*tools (optional)npm install -g @qwen-code/qwen-code qwen --version # should print 0.14.x or higherA model provider for opencode — for the default
ollama/qwen3.5:cloud, Ollama must be running locally. See Changing the Model for alternatives.
Installation
pip install polycodeVerify the CLI is accessible:
polycode --helpWindows note: If
polycodeis not found after install, find the full path withwhere polycodein PowerShell and use it in the MCP config below.
MCP Client Setup
All three supported MCP clients use the same config format — only the config file path differs.
macOS / Linux:
{
"mcpServers": {
"polycode": {
"command": "polycode",
"env": {
"OPENCODE_DEFAULT_MODEL": "ollama/qwen3.5:cloud"
}
}
}
}Windows — use the full path to the binary. Find it by running where polycode in PowerShell, then paste the result as the command value:
{
"mcpServers": {
"polycode": {
"command": "C:\\Users\\YourName\\AppData\\Local\\Programs\\Python\\Python313\\Scripts\\polycode.exe",
"env": {
"OPENCODE_DEFAULT_MODEL": "ollama/qwen3.5:cloud"
}
}
}
}MCP Client | Config file |
Claude Code |
|
Gemini CLI |
|
Qwen Code |
|
Restart your MCP client after saving. All 13 tools appear automatically.
Tools Reference
opencode tools (8)
These tools control opencode — a multi-provider AI coding agent. Sessions are stateful — messages within a session share full context across any of the 180+ supported models.
opencode_start_session
Start a new opencode session. Must be called before opencode_send_message.
Parameter | Type | Required | Description |
| string | No | Absolute path to the project. Defaults to current working directory. |
| string | No | Model in |
Returns:
{
"session_id": "ses_2a29...",
"model": "ollama/qwen3.5:cloud",
"project_dir": "/path/to/project"
}opencode_send_message
Send a prompt to an active session. Blocks until opencode finishes responding.
Parameter | Type | Required | Description |
| string | Yes | From |
| string | Yes | Your prompt. |
| int | No | Default: |
Returns:
{
"response": "Here is the updated function...",
"session_id": "ses_2a29...",
"message_index": 1,
"partial": false
}opencode_get_history
Retrieve the full message history for a session (tracked in-process).
Parameter | Type | Required |
| string | Yes |
Returns:
{
"session_id": "ses_2a29...",
"messages": [
{"role": "user", "content": "...", "timestamp": "2026-04-05T19:00:00Z"},
{"role": "assistant", "content": "...", "timestamp": "2026-04-05T19:00:05Z"}
]
}opencode_list_sessions
List all active opencode sessions.
Returns:
{
"sessions": [
{
"session_id": "ses_2a29...",
"model": "ollama/qwen3.5:cloud",
"project_dir": "/path/to/project",
"message_count": 4,
"created_at": "2026-04-05T19:00:00Z"
}
]
}opencode_end_session
Close a session and free its resources.
Parameter | Type | Required |
| string | Yes |
Returns: {"session_id": "ses_2a29...", "closed": true}
opencode_list_models
List all models available in opencode across all authenticated providers, grouped by provider. Only providers you are authenticated/connected to will show models.
Returns:
{
"models": ["ollama/qwen3.5:cloud", "openai/gpt-4o", "google/gemini-2.5-flash", "..."],
"by_provider": {
"ollama": ["ollama/qwen3.5:cloud", "..."],
"openai": ["openai/gpt-4o", "..."],
"google": ["google/gemini-2.5-flash", "..."]
},
"total": 182,
"default_model": "ollama/qwen3.5:cloud"
}opencode_set_model
Change the default model for new sessions (takes effect immediately for all subsequent opencode_start_session calls).
Parameter | Type | Required | Example |
| string | Yes |
|
Returns: {"previous_model": "ollama/...", "new_model": "openai/gpt-4o"}
opencode_shutdown
Gracefully stop the opencode server and close all active sessions.
Returns: {"stopped": true, "sessions_closed": 2}
Gemini CLI tools (4)
These tools invoke the gemini CLI directly. Sessions are persisted to disk by the CLI — pass session_id to continue a conversation across calls.
Requires: gemini CLI installed and authenticated (OAuth or GEMINI_API_KEY).
gemini_check_auth
Check whether the Gemini CLI is authenticated before making prompt calls.
Parameter | Type | Required | Default |
| int | No |
|
Returns:
{
"authenticated": true,
"method": "api_key_or_oauth",
"detail": "OK — model: gemini-2.5-flash-lite",
"suggestion": ""
}If authenticated is false, suggestion tells you how to fix it.
gemini_prompt
Send a prompt to Gemini CLI. Returns the response and a session_id that can be passed back to continue the conversation.
Parameter | Type | Required | Description |
| string | Yes | The prompt to send. |
| string | No | Resume a previous session. Leave empty to start a new one. |
| string | No | E.g. |
| int | No | Default: |
| string | No | Working directory. Defaults to current directory. |
Returns:
{
"response": "The word you asked me to remember is BLUEBIRD.",
"model": "gemini-2.5-flash-lite",
"session_id": "69cfc177-319c-484c-9..."
}Multi-turn example:
# Turn 1 — new session
gemini_prompt(prompt="Remember the word BLUEBIRD")
→ { session_id: "69cfc177-..." }
# Turn 2 — continue session
gemini_prompt(prompt="What word did I ask you to remember?", session_id="69cfc177-...")
→ { response: "BLUEBIRD" }gemini_list_sessions
List saved Gemini CLI sessions for the current project.
Parameter | Type | Required | Description |
| string | No | Defaults to current directory. |
| int | No | Default: |
Returns:
{
"sessions": [
{"raw": "0: [2026-04-05] Remember the word BLUEBIRD"},
{"raw": "1: [2026-04-05] Explain the polycode architecture"}
]
}Qwen Code CLI tools (3)
These tools invoke the qwen CLI directly. Sessions are persisted to disk by the CLI — pass session_id to continue a conversation across calls.
Requires: qwen CLI installed and authenticated (qwen auth qwen-oauth or qwen auth coding-plan).
qwen_check_auth
Check whether the Qwen Code CLI is authenticated before making prompt calls.
Parameter | Type | Required | Default |
| int | No |
|
Returns:
{
"authenticated": true,
"method": "qwen-oauth",
"detail": "=== Authentication Status ===\n✓ Authentication Method: Qwen OAuth\n Type: Free tier",
"suggestion": ""
}If authenticated is false, suggestion tells you the exact command to run.
qwen_prompt
Send a prompt to Qwen Code CLI. Returns the response and a session_id that can be passed back to continue the conversation.
Parameter | Type | Required | Description |
| string | Yes | The prompt to send. |
| string | No | Resume a previous session. Leave empty to start a new one. |
| string | No | E.g. |
| int | No | Default: |
| string | No | Working directory. Defaults to current directory. |
Returns:
{
"response": "The word you asked me to remember was REDPANDA.",
"model": "coder-model",
"session_id": "ead03e7a-afff-4ccd-a..."
}Multi-turn example:
# Turn 1 — new session
qwen_prompt(prompt="Remember the word REDPANDA")
→ { session_id: "ead03e7a-..." }
# Turn 2 — continue session
qwen_prompt(prompt="What word did I ask you to remember?", session_id="ead03e7a-...")
→ { response: "REDPANDA" }Changing the opencode Model
The model format is provider/model-name. Set it via env var:
"env": {
"OPENCODE_DEFAULT_MODEL": "openai/gpt-4o"
}Or call opencode_set_model at runtime. Call opencode_list_models to see all 182 available models across your connected providers.
Common models:
Provider | Model string |
Ollama (local) |
|
OpenAI |
|
Anthropic |
|
| |
GitHub Copilot |
|
Configuration
Variable | Default | Description |
|
| Default model for new opencode sessions |
|
| Port for the opencode server |
|
| Seconds to wait for opencode to start |
|
| Seconds before a generation times out |
|
| Log level: |
| (unset) | Optional HTTP Basic Auth password for the opencode server |
Error Handling
Every tool always returns a structured response — never a raw exception:
{
"error": "OpencodeBinaryNotFoundError",
"message": "gemini CLI not found on PATH. Install: npm install -g @google/gemini-cli",
"detail": {},
"recoverable": false,
"suggestion": "Install opencode via: npm install -g opencode-ai"
}Field | Description |
| Exception class name |
| What went wrong |
| Structured context (stderr, attempted values, etc.) |
| Whether retrying makes sense |
| Exact next step to fix it |
Common errors:
Error | Cause | Fix |
| CLI not on PATH | Install the CLI listed in |
| opencode failed to start | Increase |
| Generation took too long | Increase |
| Session ID not found | Call |
| Bad input or auth error | Read the |
| Unexpected CLI output shape | Update the CLI to the latest version |
Troubleshooting
"polycode not found" on Windows
Use the full path in your MCP config. Find it with:
where polycodeopencode server times out on startup
Cloud models do a network handshake on first use. Increase the timeout:
"env": { "OPENCODE_STARTUP_TIMEOUT": "30" }Tools appear but calls hang
On Windows, subprocesses can inherit a blocked stdin from the MCP stdio pipe. This package sets stdin=DEVNULL on all subprocesses — ensure you are on polycode >= 0.1.0.
gemini_prompt or qwen_prompt returns an auth error
Run the auth check first:
gemini_check_auth→ readssuggestionfield for the fixqwen_check_auth→ readssuggestionfield for the fix
Then authenticate interactively (gemini or qwen auth qwen-oauth) and retry.
Running Tests
git clone https://github.com/h19overflow/polycode
cd polycode
pip install -e ".[dev]"
# Unit tests — no CLIs required
pytest tests/ --ignore=tests/test_integration.py -v
# Integration tests — requires opencode + ollama
pytest tests/test_integration.py -m integration -vContributing
Fork the repo
pip install -e ".[dev]"Write tests first (TDD)
pytest tests/ --ignore=tests/test_integration.pymust passpyright .must show 0 errorsOpen a PR
License
MIT — see LICENSE
Available Tools
13 toolsgemini_check_authA
Check whether the Gemini CLI is authenticated before making any gemini_prompt calls.
Always call this first if you are unsure whether Gemini is set up. Returns: authenticated (bool), method, detail, suggestion. If authenticated is false, read the suggestion field — it contains the exact fix.
Inputs: timeout_seconds. Returns: object
gemini_list_sessionsA
List saved Gemini CLI sessions for the current project.
Returns a list of sessions with their index and first-message preview. Use this to find a session_id to resume a previous conversation.
Inputs: project_dir, timeout_seconds. Returns: object
gemini_promptA
Send a detailed prompt to the Gemini CLI. Returns response text, model used, and session_id.
MODEL SELECTION:
Default work → gemini-3-flash-preview (fast, capable, most tasks)
Complex work → gemini-3.1-pro-preview (deep reasoning, architecture, hard bugs)
Bulk/batch work → gemini-2.5-flash-lite (fastest, cheapest, high-volume tasks)
SESSION CONTINUITY: First call returns a session_id. Pass it back on the next call to continue the conversation. Gemini persists session history to disk — context is preserved across calls.
ALWAYS write detailed prompts. Include file paths, numbered steps, and output format.
Inputs: prompt (required), model, session_id, project_dir, +1 more. Returns: object
opencode_end_sessionA
Close an opencode session and free its resources.
Call this when a task is complete. Do not leave sessions open indefinitely.
Inputs: session_id (required). Returns: object
opencode_get_historyA
Return the full message history for an opencode session (tracked in-process).
Each message has: role (user/assistant), content, timestamp. Use this to review what has been sent and received before sending the next message.
Inputs: session_id (required). Returns: object
opencode_list_modelsA
List all models available in opencode across all connected providers, grouped by provider.
Only providers you are authenticated with will return models. Returns: models (flat list), by_provider (grouped dict), total count, default_model.
Use this before opencode_start_session to pick the right model for the task.
Inputs: no named parameters. Returns: object
opencode_list_sessionsA
List all currently active opencode sessions with session_id, model, project_dir, message count, and creation time.
Use this to find a session_id if you have lost track of it.
Inputs: no named parameters. Returns: object
opencode_send_messageB
Send a detailed instruction to an active opencode session and return the response.
PROMPTING RULES:
Specify EXACT file paths (absolute). Never say 'the config file' — say the full path.
Break multi-step work into numbered steps within the same message.
Specify the output format: 'return a code block', 'return JSON', 'list changed files'.
If the task involves multiple files, list all of them explicitly.
If you want opencode to run a command, say exactly which command and in which directory.
Inputs: message (required), session_id (required), timeout_seconds. Returns: object
opencode_set_modelA
Change the default model used for all new opencode sessions.
Takes effect immediately for all subsequent opencode_start_session calls. Does not affect already-open sessions.
Inputs: model (required). Returns: object
opencode_shutdownA
Gracefully stop the opencode server and close all active sessions.
Call this when you are done with all opencode work in the current session. Gemini and Qwen CLI tools are not affected — they are stateless subprocesses.
Inputs: no named parameters. Returns: object
opencode_start_sessionA
Start a new opencode session. Call this before opencode_send_message.
Returns session_id, model, and project_dir. Store session_id — every subsequent call to opencode_send_message requires it.
Use opencode for coding tasks: writing, editing, refactoring, debugging, explaining code. For tasks requiring reasoning or research, prefer gemini_prompt or qwen_prompt instead.
Inputs: model, project_dir. Returns: object
qwen_check_authA
Check whether the Qwen Code CLI is authenticated before making any qwen_prompt calls.
Always call this first if you are unsure whether Qwen is set up. Returns: authenticated (bool), method (qwen-oauth / coding-plan / api-key), detail, suggestion. If authenticated is false, read the suggestion field — it contains the exact command to run.
Inputs: timeout_seconds. Returns: object
qwen_promptA
Send a detailed prompt to the Qwen Code CLI. Returns response text, model used, and session_id.
MODEL SELECTION:
Default work → leave model empty (CLI picks best for your tier)
Complex work → qwen-max (deep reasoning, architecture, hard bugs)
Standard work → qwen-plus (balanced, most coding tasks)
Bulk/batch work → qwen-turbo (fastest, cheapest, high-volume tasks)
SESSION CONTINUITY: First call returns a session_id. Pass it back on the next call to continue the conversation. Qwen persists session history to disk — context is preserved across calls.
ALWAYS write detailed prompts. Include file paths, numbered steps, and output format.
Inputs: prompt (required), model, session_id, project_dir, +1 more. Returns: object
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 13 tools
Each tool is clearly prefixed by provider and uses a distinct verb_noun combination. opencode_start_session, opencode_send_message, gemini_prompt, qwen_prompt, etc. have unambiguous boundaries, and even the similar prompt tools are separated by provider.
All 13 tools follow the exact snake_case pattern of provider_action_noun (e.g., opencode_list_sessions, gemini_check_auth, qwen_prompt). There are no deviations or mixed conventions.
13 tools is well within the ideal range and appropriate for the server's scope of managing three separate coding CLIs. Each tool serves a distinct operational need, and none are redundant.
Opencode has full lifecycle coverage, and gemini/qwen include auth and prompting. However, qwen lacks a list_sessions equivalent, which is a minor gap compared to gemini and could hinder session resumption.
Maintenance
Related MCP Connectors
MCP server for building and testing AI agents with multi-model experimentation and insights.
MCP server for your apps' tools and custom tools, plus hosted AI agents and approval-gated workflows
Shared memory MCP server for Claude Code, Codex, Gemini CLI and Cursor. Cited, editable.
MCP server connecting AI agents to 100+ apps (Gmail, Slack, Notion, GitHub) via one-click OAuth.
Related MCP Servers
- AlicenseNot gradedqualityFmaintenanceAn MCP server that orchestrates AI coding assistants (Claude Code CLI and Gemini CLI) to perform complex programming tasks autonomously, allowing remote control of your local development environment from anywhere.19 npm140MIT
- FlicenseNot gradedqualityBmaintenanceMCP server that bridges coding agents (Claude Code, Codex, Gemini CLI) via ACP for pair programming, enabling agents to consult each other as tools.3-
- AlicenseNot gradedqualityCmaintenanceAn MCP server that bridges CLI coding agents like Claude Code, Codex, opencode, and Antigravity into any MCP client, enabling synchronous and asynchronous task execution, follow-up input, and a structured code review tool.34 npm2MIT
- AlicenseAqualityDmaintenanceMCP server that enables Claude Code to delegate tasks to DeepSeek and other LLMs, offering 20 tools for code review, analysis, testing, and code generation.201MIT