Metadata-Version: 2.4
Name: opencode-server-mcp
Version: 0.1.0
Summary: MCP server for controlling OpenCode servers via the OpenCode Server API
Author-email: ThomasTSteinbach <thomas.t.steinbach@deutschebahn.com>
Requires-Python: >=3.13
Requires-Dist: docker>=7.1.0
Requires-Dist: httpx>=0.28.1
Requires-Dist: mcp[cli]>=1.3.2
Requires-Dist: pydantic>=2.10.5
Provides-Extra: dev
Requires-Dist: bandit>=1.7.0; extra == 'dev'
Requires-Dist: mypy>=1.14.0; extra == 'dev'
Requires-Dist: pip-audit>=2.7.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=1.3.0; extra == 'dev'
Requires-Dist: pytest-cov>=6.0.0; extra == 'dev'
Requires-Dist: pytest-xdist>=3.8.0; extra == 'dev'
Requires-Dist: pytest>=8.3.4; extra == 'dev'
Requires-Dist: respx>=0.22.0; extra == 'dev'
Requires-Dist: ruff>=0.8.4; extra == 'dev'
Requires-Dist: types-docker>=7.1.0.20260109; extra == 'dev'
Description-Content-Type: text/markdown

# opencode-server-mcp

MCP server for controlling OpenCode servers running in Docker containers via the OpenCode Server API.

## Overview

`opencode-server-mcp` is a Model Context Protocol (MCP) server that provides tools for interacting with OpenCode servers running in Docker containers. It enables MCP clients (like Claude Desktop, VS Code, Cursor) to programmatically control OpenCode sessions through standardized MCP tools.

## Features

### Session Management
- **List Sessions** - View all active sessions within a specific OpenCode server
- **Create Sessions** - Create new chat sessions for AI interactions
- **Delete Sessions** - Remove sessions from OpenCode servers for cleanup
- **Send Messages** - Send messages to sessions with explicit model selection
- **Multi-Server Support** - Work with multiple OpenCode server containers simultaneously

### Server Lifecycle Management (Docker-Based)
- **Auto-Start Default Server** - Automatically starts one OpenCode container during MCP initialization
- **Start Additional Servers** - Launch additional isolated OpenCode containers as needed
- **Configurable Isolation** - Control what host resources containers can access
- **Stop Managed Servers** - Stop and remove Docker containers cleanly
- **List Managed Servers** - View all managed containers with port mappings
- **Automatic Cleanup** - Orphaned containers are automatically cleaned up on startup and shutdown
- **Version Alignment** - Automatically detects local OpenCode version and uses matching Docker image tag

### Configuration Options
- **Mount Global Config** - Optionally mount `~/.config/opencode/opencode.json` for API keys
- **Mount Global Agents** - Optionally mount `~/.config/opencode/AGENTS.md` for agent configuration
- **Mount Working Directory** - Optionally mount a host directory into the container
- **Custom Config** - Pass configuration as JSON to override container defaults
- **Get Config** - Retrieve current server configuration

## Requirements

- **Docker** - Docker daemon must be running (containers use `ghcr.io/anomalyco/opencode`)
- **OpenCode** - Local OpenCode installation for version alignment (optional, will use 'latest' if not installed)
- **Python 3.13+** - For running from source
- **uv/uvx** - Recommended for installation

### Version Alignment

The MCP server automatically detects your locally installed OpenCode version and uses the matching Docker image tag. This ensures behavior consistency between your local OpenCode and the containerized servers.

**How it works:**
1. On startup, the server runs `opencode --version` to detect the local version
2. It derives the Docker image tag (e.g., `ghcr.io/anomalyco/opencode:1.1.20`)
3. If the image doesn't exist locally, it's automatically pulled
4. All containers use this version-aligned image

**Configuration options:**
- The version is detected automatically, no configuration needed
- If OpenCode is not installed locally, the server uses `latest` tag
- You can override the version by setting custom Docker image in the code (advanced use only)

## Installation

The recommended way to use this MCP server is via `uvx`, which runs the package directly from PyPI without manual installation.

### Claude Code, Cursor

**Configuration Files:**
- **Claude Code:** `~/.claude.json` (User Scope) or `project_root/.mcp.json` (Project Scope)
- **Amazon Q CLI:** `~/.aws/amazonq/mcp.json` (User Scope) or `./.amazonq/mcp.json` (Project Scope)
- **Cursor:** `~/.cursor/mcp.json` (Global) or `.cursor/mcp.json` (Project Root)

```json
{
  "mcpServers": {
    "opencode": {
      "command": "uvx",
      "args": ["opencode-server-mcp"],
      "env": {
        "OPENCODE_TIMEOUT": "60"
      }
    }
  }
}
```

### OpenCode

**Configuration Files:** `opencode.json` (Project Root) or `~/.config/opencode/opencode.json` (Global)

```json
{
  "mcp": {
    "opencode": {
      "type": "local",
      "command": ["uvx", "opencode-server-mcp"],
      "environment": {
        "OPENCODE_TIMEOUT": "60"
      },
      "enabled": true
    }
  }
}
```

### VS Code with GitHub Copilot

**Configuration Files** `.vscode/mcp.json` (Workspace Root)

```json
{
  "servers": {
    "opencode": {
      "command": "uvx",
      "args": ["opencode-server-mcp"],
      "env": {
        "OPENCODE_TIMEOUT": "60"
      }
    }
  }
}
```

### Configuration Parameters

Configure the MCP server using environment variables:

- `OPENCODE_TIMEOUT` - Request timeout in seconds (default: `30`)

## Local Execution

### From Source

```bash
# Clone the repository
git clone <repository-url>
cd opencode-server-mcp

# Install dependencies with uv
uv sync --all-extras

# Run the server
uv run opencode-server-mcp
```

### As a Package (uvx)

The simplest way to run the MCP server is using `uvx`, which downloads and runs the package directly:

```bash
uvx opencode-server-mcp
```

### As a Package (pip/uv)

```bash
# Install with uv
uv add opencode-server-mcp

# Or install with pip
pip install opencode-server-mcp
```

## Development

This project uses [mise](https://mise.jdx.dev/) for SDLC operations. All development tasks are available as mise tasks.

### Setup

```bash
# Install mise (if not already installed)
curl https://mise.run | sh

# Install dependencies
mise run install
```

### Available Tasks

```bash
# Core operations
mise run check              # Run all quality checks (lint + format + typecheck)
mise run fix                # Auto-fix lint and format issues
mise run test               # Run unit tests
mise run test:integration   # Run integration tests
mise run test:all           # Run all tests
mise run test:docker        # Run tests in isolated Docker containers (recommended)
mise run test:cov           # Run unit tests with coverage
mise run build              # Build the package
mise run clean              # Clean build artifacts

# CI/CD operations
mise run ci:local           # Run full local CI pipeline
mise run ci:security        # Run security checks (bandit + pip-audit)
mise run ci                 # Show GitLab CI status
mise run ci:view            # View pipeline details

# Documentation
mise run docs:api           # Regenerate API documentation

# Package management
mise run pkg:add <package>      # Add a dependency
mise run pkg:add:dev <package>  # Add a dev dependency
mise run pkg:lock               # Update the lockfile

# Release management
mise run release:list       # List all releases
mise run release:view <tag> # View release details
```

## Testing

> **⚠️ CRITICAL:** Always use `./scripts/run-tests-docker.sh` for running tests. Direct execution via `uv run pytest` will interfere with running OpenCode instances and produce unreliable results due to lack of isolation.

### Docker-Based Testing (Recommended)

To ensure tests don't interfere with other running OpenCode instances, use the Docker-based test runner:

```bash
# Run all tests in isolated Docker containers (up to 20 in parallel)
./scripts/run-tests-docker.sh

# Run with pattern filter (e.g., only session-related tests)
./scripts/run-tests-docker.sh --pattern "session"

# Run specific test function
./scripts/run-tests-docker.sh --pattern "test_session_creation_tracked_in_database"

# Run with custom parallelism (e.g., 25 tests at once)
./scripts/run-tests-docker.sh --parallel 25

# Run tests grouped by file (faster, less isolation)
./scripts/run-tests-docker.sh --file-mode

# Combine options
./scripts/run-tests-docker.sh --file-mode --pattern "test_models" --parallel 25

# Show help
./scripts/run-tests-docker.sh --help
```

**Isolation Modes:**
- **Default (function mode)**: Each test function runs in a separate Docker container - maximum isolation
- **File mode** (`--file-mode`): Tests grouped by file - faster, but less isolation

**Parallel Execution:**
- By default, up to **20 tests run in parallel** for faster execution
- Use `--parallel N` to change the concurrency level
- Each parallel test runs in a completely isolated Docker container
- Progress indicator shows completion status in real-time

Each container provides:
- Fresh OpenCode installation
- Isolated file system and processes
- No shared state between tests
- No interference with IDE or development tools

**Requirements:**
- Docker installed and running
- Docker daemon accessible

### Local Testing

For faster iteration during development, you can run tests locally:

```bash
# Run all tests
uv run pytest

# Run specific test categories
uv run pytest tests/unit/ -v
uv run pytest tests/integration/ -v
uv run pytest tests/client/ -v

# Run specific test file
uv run pytest tests/unit/test_client.py -v
```

**Note:** Local tests may interact with OpenCode instances on your system. Use Docker-based testing for full isolation.

## License

[Add license information]

## Contributing

[Add contributing guidelines]
