Skip to main content
Glama

codex-codebuddy-mcp

A minimal Python MCP server that lets Codex control CodeBuddy Code through its Agent Client Protocol (ACP) interface.

Features

  • Session creation starts CodeBuddy and establishes the ACP session.

  • One CodeBuddy process and ACP session per bridge session.

  • Local launch and remote launch over OpenSSH stdio.

  • Explicit bridge session IDs with MCP client ownership checks.

  • Per-session model switching through ACP.

  • At most two active CodeBuddy turns by default across the MCP server.

  • Explicit permission approval modes: MCP elicitation or compatible two-step flow.

  • Cancellation and deterministic child-process cleanup.

Related MCP server: cross_yapper

Requirements

  • Python 3.11 or newer

  • uv

  • CodeBuddy Code with ACP support (codebuddy --acp)

  • OpenSSH when using remote launch

Install and run

uv sync
uv run codex-codebuddy-mcp

The bridge has built-in defaults. In a source checkout, the repository-level config.yaml can override them:

max_read: 1048576 # 1 MiB, one ACP stdout/stderr line
max_output: 65536 # 64 KiB, one MCP result
max_concurrency: 2 # simultaneous active prompt turns
approval_mode: elicitation
timeout_seconds: 900 # default prompt/permission-turn timeout
startup_timeout_seconds: 60 # ACP initialize/session startup timeout
turn_cancel_timeout_seconds: 5 # wait for ACP turn cancellation
local_process_terminate_timeout_seconds: 5 # wait before local SIGKILL
remote_ssh_cleanup_timeout_seconds: 10 # wait for remote cleanup SSH command
stdout_overflow_retry_tolerance: 1 # oversized stdout turns tolerated before termination
stderr_tail_buffer_size: 80 # stderr lines retained for diagnostics

Installed wheels use the built-in defaults unless CODEX_CODEBUDDY_MCP_CONFIG names a YAML file. The KB, MB, and GB suffixes are accepted as binary multiples for backward compatibility; max_concurrency must be a unitless integer. The values can be overridden for an individual session by passing max_read and/or max_output to create_codebuddy_session. Timeout values are seconds. stdout_overflow_retry_tolerance is the number of oversized stdout responses that may be discarded while keeping the process available; 0 terminates the process on the first overflow. stderr_tail_buffer_size is measured in stderr lines. The prompt tools' timeout_seconds and the session creation tool's startup_timeout_seconds also accept per-call overrides. max_concurrency applies globally to all bridge sessions and is loaded when the MCP server starts.

Example Codex MCP configuration:

[mcp_servers.codebuddy]
command = "uv"
args = [
  "run",
  "--project",
  "/absolute/path/to/codex-codebuddy-mcp",
  "codex-codebuddy-mcp",
]

The MCP server writes protocol data to stdout and diagnostics to stderr.

Tools

create_codebuddy_session

Starts CodeBuddy, establishes the ACP session, and returns both a bridge_session_id and the codebuddy_session_id, along with the ACP-reported model_id and model_name. The model fields are returned when the session is created, not repeated on every prompt result. The bridge does not maintain a model allowlist. If CodeBuddy does not report model metadata, those two fields are null, rather than echoing an unverified model argument. If startup or session recovery fails, this call returns an error and does not leave a usable bridge session behind.

cwd and model_id are required. cwd sets the working directory for the CodeBuddy session. If it is present but empty or contains only whitespace, the bridge asks the user to enter a working directory through MCP elicitation. Clients without elicitation support receive an error that asks the caller to retry with a non-empty cwd. model_id must be non-empty and is passed to CodeBuddy as --model; do not repeat --model in codebuddy_args.

Local example arguments:

{
  "cwd": "/path/to/project",
  "model_id": "deepseek-v4.1-flash",
  "launch_mode": "local",
  "permission_mode": "auto",
  "approval_mode": "elicitation",
  "max_read": 4194304,
  "max_output": 65536
}

SSH example arguments:

{
  "cwd": "/home/dev/project",
  "model_id": "deepseek-v4.1-flash",
  "launch_mode": "ssh",
  "ssh_host": "dev-box",
  "ssh_args": ["-T"],
  "codebuddy_command": "/usr/local/bin/codebuddy"
}

SSH authentication uses the system ssh command, SSH config, and agent. Passwords are not accepted by this bridge. Values supplied through env are forwarded to CodeBuddy but should be treated as MCP tool input; prefer parent-process or remote host configuration for secrets.

approval_mode controls the bridge-to-MCP permission path. elicitation is the default and requires the MCP client to support elicitation; failures are returned as errors. compatible explicitly uses the two-step permission_required plus respond_codebuddy_permission flow. It does not silently fall back between modes.

By default the bridge reuses the CodeBuddy login already present on the target machine. If no login is available it returns an authentication-required error. auth_method_id can explicitly request external, internal, iOA, or selfhosted authentication; CodeBuddy may open or wait for its normal login flow, so use this only when interactive authentication is intended.

permission_mode defaults to auto and is passed to CodeBuddy as --permission-mode auto. The supported values are acceptEdits, bypassPermissions, default, plan, dontAsk, and auto. The bridge allows max_concurrency active turns at the same time across sessions; turns in one ACP session remain serialized. max_read controls the asyncio subprocess stream limit used for reading each ACP stdout/stderr line. Its YAML default is 1048576 bytes (1 MiB). Increase it when a single ACP JSON line can be larger; it must be a positive integer. On the first stdout overrun, the bridge discards that response, cancels the current turn, and keeps the process available so the caller can request a compressed answer. Changing max_read requires creating a new bridge session. A successful turn clears the overrun count; once stdout_overflow_retry_tolerance is exceeded, the process is terminated. Oversized stderr lines are discarded without stopping the session. max_output controls the MCP result threshold and defaults to 65536 bytes (64 KiB).

The concurrency limit applies to active session/prompt turns, including turns waiting for a permission decision. It does not limit the number of started CodeBuddy processes. A third session may be created and remain ready, but its prompt waits for a turn slot and fails when its timeout expires. In compatible approval mode, an unanswered permission request is cancelled after the calling tool's timeout_seconds, which releases its global turn slot. Operations within one bridge session are serialized by that session's lock.

The registry is in memory. Restarting the MCP server loses bridge session IDs, owner bindings, locks, pending permissions, in-flight buffers, and process handles. Persist the returned codebuddy_session_id if recovery is needed; a new bridge session can pass it as resume_session_id. The bridge cannot discover old CodeBuddy sessions automatically.

switch_codebuddy_model

Switches the model for an existing bridge session between turns:

{
  "bridge_session_id": "...",
  "model_id": "deepseek-v4.1-flash"
}

The bridge sends ACP session/set_model with the bound CodeBuddy session. CodeBuddy must acknowledge the change; ACP errors are returned directly and do not change the bridge's recorded model. A successful call returns model_id and model_name once, together with both session IDs. Switching while a prompt or permission request is active is rejected; finish or cancel that turn first.

prompt_codebuddy

Sends a text prompt to the already-started CodeBuddy session. A completed turn returns the final text, stop reason, tool summaries, and CodeBuddy session ID.

max_output controls the maximum UTF-8 byte size of every prompt result and defaults to 65536. When the serialized result is larger, the bridge writes the complete JSON result to a 0600 file in the local temporary directory and returns output_path, output_bytes, and text_available_in_file=true instead of embedding the large text in the MCP response. Permission metadata remains in the compact response so the caller can continue the same turn; the caller can read the complete result from that path with its local file tools. MCP/JSON-RPC does not define one universal maximum, but the calling Codex or harness may enforce a per-message limit, so a conservative max_output is useful for long reports. The bridge removes tracked output files when their bridge session closes or the server shuts down.

For reports that exceed the file threshold, the same bridge session remains available for follow-up prompts and additional sections.

With approval_mode="compatible", the tool returns:

{
  "status": "permission_required",
  "permission": {
    "request_id": "...",
    "tool_name": "Bash",
    "raw_input": {"command": "..."},
    "options": [
      {"kind": "allow", "name": "Allow", "optionId": "allow"},
      {"kind": "reject", "name": "Deny", "optionId": "deny"}
    ]
  }
}

respond_codebuddy_permission

Pass the exact request_id and one of the returned optionId values. The call continues the same CodeBuddy turn and may complete or return another permission request. It also accepts max_output with the same file externalization behavior.

cancel_codebuddy_turn and close_codebuddy_session

Completing a prompt does not close CodeBuddy. Cancellation keeps the CodeBuddy process available. Closing cancels active work, terminates the local process or SSH channel, and removes the bridge session. On SSH, the bridge records a unique remote PID file and performs a second SSH cleanup command that terminates that process group. The remote shell uses set -m, starts CodeBuddy as a monitored job, and waits for it so the SSH stdio channel stays connected for ACP responses. This handles CodeBuddy processes that outlive the SSH channel; abrupt network loss or a remote process that ignores termination cannot be guaranteed by the local client.

Tests

Run the default suite, including a real installed CodeBuddy ACP handshake:

uv run pytest

The handshake starts the actual codebuddy-code binary, validates ACP initialization and login state handling, and creates an ACP session when the installed CLI is already authenticated. It does not send a model prompt or consume model quota. A second real startup test verifies that the default permission mode passed to CodeBuddy is auto, rather than plan. These tests skip only when codebuddy is not installed.

An opt-in end-to-end model test is also provided. It sends a real prompt and may consume quota:

RUN_CODEBUDDY_MODEL_TEST=1 uv run pytest -m model

The real permission-forwarding test is parameterized over both supported forwarding modes. It prompts CodeBuddy to request approval for a harmless printf through Bash, verifies either the compatible two-step response or MCP elicitation, selects an allow option, and checks that the same turn completes. It is separately opt-in because each mode sends a model prompt and executes the approved command:

RUN_CODEBUDDY_PERMISSION_TEST=1 uv run pytest \
  tests/test_server.py::test_real_codebuddy_permission_request_is_forwarded

Run static checks:

uv run ruff check .

Available Tools

5 tools
cancel_codebuddy_turnA

Cancel the active turn while keeping the CodeBuddy session available.

Inputs: bridge_session_id (required). Returns: object

close_codebuddy_sessionC

Close and remove a CodeBuddy bridge session.

Inputs: bridge_session_id (required). Returns: object

create_codebuddy_sessionA

Configure an isolated CodeBuddy ACP session without starting its process.

Use launch_mode="ssh" to run CodeBuddy remotely over an existing OpenSSH configuration. The CodeBuddy process starts lazily on the first prompt.

Inputs: cwd (required), env, ssh_args, ssh_host, +7 more. Returns: object

prompt_codebuddyA

Send a text prompt to the bound CodeBuddy session.

This lazily starts CodeBuddy. The result either completes the turn or returns a permission request for respond_codebuddy_permission.

Inputs: prompt (required), bridge_session_id (required), timeout_seconds. Returns: object

respond_codebuddy_permissionC

Resolve a pending CodeBuddy permission request and continue the turn.

Inputs: option_id (required), request_id (required), bridge_session_id (required), timeout_seconds. Returns: object

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.7/5.0

    Scored across 5 tools

    Disambiguation5/5

    Each tool targets a clearly distinct action: session creation, session teardown, sending a prompt, resolving a permission request, and cancelling a turn. There is no overlap or ambiguity between these operations.

    Naming Consistency5/5

    All tool names follow a predictable snake_case verb_noun pattern: create_, close_, prompt_, respond_, cancel_. The shared 'codebuddy' anchor makes the set easy to scan and understand.

    Tool Count5/5

    Five tools cover the full interaction lifecycle without redundancy. Each tool corresponds to a distinct phase of using a CodeBuddy session, so the count is well-scoped for the server's purpose.

    Completeness5/5

    The tool surface covers the complete workflow: create a session, prompt it, handle permission requests, cancel turns, and close the session. There are no obvious dead ends or missing operations needed for the advertised functionality.

    Maintenance

    ActivitySlowing
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      D
      maintenance
      Enables MCP clients to spawn and control Codex CLI and Claude Code sessions on the host machine, with session management and filesystem access.
      4
      MIT
    • A
      license
      A
      quality
      C
      maintenance
      Enables MCP-compatible coding agents to execute the local Codex CLI as a coding agent, including code reviews, session resume/fork, and CLI diagnostics.
      9
      12 npm
      MIT
    • F
      license
      Not graded
      quality
      C
      maintenance
      Enables MCP clients such as Codex to asynchronously launch, monitor, steer, and control persistent CodeBuddy CLI sessions, including permission responses, interruption, recovery, and shutdown. It also provides model and account queries plus optional WebUI monitoring.
      -