Skip to main content
Glama

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 continuity

The 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

  1. Python 3.11+

    python --version
  2. opencode CLI — for the opencode_* tools

    npm install -g opencode-ai
    opencode --version  # should print 1.x.x
  3. Gemini CLI — for the gemini_* tools (optional)

    npm install -g @google/gemini-cli
    gemini --version  # should print 0.36.x or higher
  4. Qwen Code CLI — for the qwen_* tools (optional)

    npm install -g @qwen-code/qwen-code
    qwen --version  # should print 0.14.x or higher
  5. A 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 polycode

Verify the CLI is accessible:

polycode --help

Windows note: If polycode is not found after install, find the full path with where polycode in 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

~/.claude.json

Gemini CLI

~/.gemini/settings.json

Qwen Code

~/.qwen/settings.json

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

project_dir

string

No

Absolute path to the project. Defaults to current working directory.

model

string

No

Model in provider/model format. Defaults to OPENCODE_DEFAULT_MODEL.

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

session_id

string

Yes

From opencode_start_session.

message

string

Yes

Your prompt.

timeout_seconds

int

No

Default: 120.

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

session_id

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

session_id

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

model

string

Yes

ollama/qwen3.5:cloud

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

timeout_seconds

int

No

15

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

prompt

string

Yes

The prompt to send.

session_id

string

No

Resume a previous session. Leave empty to start a new one.

model

string

No

E.g. gemini-2.5-flash. Defaults to the CLI's configured model.

timeout_seconds

int

No

Default: 120.

project_dir

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

project_dir

string

No

Defaults to current directory.

timeout_seconds

int

No

Default: 10.

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

timeout_seconds

int

No

15

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

prompt

string

Yes

The prompt to send.

session_id

string

No

Resume a previous session. Leave empty to start a new one.

model

string

No

E.g. qwen-plus. Defaults to the CLI's configured model.

timeout_seconds

int

No

Default: 120.

project_dir

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)

ollama/qwen3.5:cloud

OpenAI

openai/gpt-4o

Anthropic

anthropic/claude-sonnet-4-5

Google

google/gemini-2.5-flash

GitHub Copilot

github-copilot/claude-sonnet-4.6


Configuration

Variable

Default

Description

OPENCODE_DEFAULT_MODEL

ollama/qwen3.5:cloud

Default model for new opencode sessions

OPENCODE_PORT

0 (random)

Port for the opencode server

OPENCODE_STARTUP_TIMEOUT

10

Seconds to wait for opencode to start

OPENCODE_REQUEST_TIMEOUT

120

Seconds before a generation times out

OPENCODE_LOG_LEVEL

INFO

Log level: DEBUG, INFO, WARNING, ERROR

OPENCODE_SERVER_PASSWORD

(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

error

Exception class name

message

What went wrong

detail

Structured context (stderr, attempted values, etc.)

recoverable

Whether retrying makes sense

suggestion

Exact next step to fix it

Common errors:

Error

Cause

Fix

OpencodeBinaryNotFoundError

CLI not on PATH

Install the CLI listed in suggestion

OpencodeStartupError

opencode failed to start

Increase OPENCODE_STARTUP_TIMEOUT; check opencode serve manually

OpencodeTimeoutError

Generation took too long

Increase OPENCODE_REQUEST_TIMEOUT or simplify the prompt

OpencodeSessionError

Session ID not found

Call opencode_list_sessions to see active sessions

OpencodeValidationError

Bad input or auth error

Read the suggestion field — includes exact CLI auth command if needed

OpencodeProtocolError

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 polycode

opencode 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 → reads suggestion field for the fix

  • qwen_check_auth → reads suggestion field 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 -v

Contributing

  1. Fork the repo

  2. pip install -e ".[dev]"

  3. Write tests first (TDD)

  4. pytest tests/ --ignore=tests/test_integration.py must pass

  5. pyright . must show 0 errors

  6. Open a PR


License

MIT — see LICENSE

Available Tools

13 tools
gemini_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

    A4.2/5.0

    Scored across 13 tools

    Disambiguation5/5

    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.

    Naming Consistency5/5

    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.

    Tool Count5/5

    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.

    Completeness4/5

    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

    ActivityInactive
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • F
      license
      Not graded
      quality
      B
      maintenance
      MCP server that bridges coding agents (Claude Code, Codex, Gemini CLI) via ACP for pair programming, enabling agents to consult each other as tools.
      3
      -
    • A
      license
      Not graded
      quality
      C
      maintenance
      An 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 npm
      2
      MIT