CodeServer MCP

CodeServer MCP

Provides stateful development sessions for code-server, enabling persistent shells, background processes, sandboxed file operations, and file watching through MCP.

Category
访问服务器

README

CodeServer MCP

A production-oriented Model Context Protocol server for code-server, built around stateful development sessions rather than stateless file operations.

Architecture

Core Modules

workspace/ — Sandboxed file operations scoped to WORKSPACE_ROOT

  • read.py — Read files with optional line-range slicing
  • write.py — Atomic file writes (create/overwrite)
  • patch.py — Targeted edits via unified diff or find/replace (never resend the whole file)
  • search.py — Ripgrep-based search with structured results
  • tree.py — Recursive directory listing (respects .gitignore-style ignore rules)
  • watch.py — Async file watching; detect changes made by the editor, git, build tools

terminal/ — Persistent shells & background processes

  • pty.py — Real pseudo-terminal wrapper (ptyprocess) for authentic terminal behavior (colors, pagers, history)
  • shell.py — Persistent shell sessions that survive crashes/restarts
  • process.py — Background process manager with log capture

util/

  • paths.py — Workspace sandboxing: every file operation goes through resolve_path() which proves the result still lives inside WORKSPACE_ROOT
  • diff.py — Unified diff helpers for generating and applying patches

Key Design Decisions

  1. Real PTYs, not subprocesses

    • Shells are real pseudo-terminals (ptyprocess), so programs that check isatty() behave naturally.
    • Output includes ANSI colors, spinner sequences, and pager control codes.
    • Shell history and readline state persist across calls.
  2. Stateful vs. Stateless

    • Unlike generic filesystem MCP servers, shells and processes are first-class, long-lived entities.
    • A shell can run npm run dev, and the dev server keeps running. Later calls can read its output, resize its terminal, or send it signals.
    • Session recovery on restart: PTY metadata is stored in SQLite so crashed dev servers can be reconnected.
  3. Sandboxing

    • Every workspace operation (read/write/patch/search/tree/watch) goes through util.paths.resolve_path().
    • All paths are canonicalized and checked to be within WORKSPACE_ROOT — symlinks cannot escape.
  4. Patching, not Overwriting

    • replace_text() and apply_patch() let Claude make surgical edits without resending entire files.
    • Diffs are generated and returned so clients (Claude) can see what changed.
  5. Async-first

    • All I/O is async (asyncio, aiofiles, aiosqlite).
    • Long-lived watches and process log tailing don't block.

Installation

Docker (Recommended)

docker-compose up -d
# MCP server now listens on localhost:8080

Local (Python 3.12+)

python -m venv .venv
source .venv/bin/activate  # Windows: .venv\Scripts\activate
pip install -r requirements.txt
export WORKSPACE_ROOT=/path/to/code
export MCP_PORT=8080
python app.py

Environment Variables

  • MCP_HOST (default: 0.0.0.0) — Listen address
  • MCP_PORT (default: 8080) — Listen port
  • WORKSPACE_ROOT (default: /workspace) — Sandbox root; all file operations must stay within this
  • RG_BIN (default: rg) — Path to ripgrep binary if not on PATH
  • LOG_LEVEL (default: info) — Uvicorn log level

MCP Tools

Workspace

  • workspace_read_file(path, start_line, end_line) — Read a file (with optional line range)
  • workspace_write_file(path, content, mode, create_dirs) — Write or create a file
  • workspace_replace_text(path, old, new, expected_count) — Find and replace (safe, requires uniqueness)
  • workspace_apply_patch(path, diff_text) — Apply a unified diff
  • workspace_search(pattern, path, glob, case_sensitive, fixed_string, max_results) — Ripgrep-based search
  • workspace_tree(path, max_depth, max_entries) — Directory listing
  • workspace_watch_start(path) — Start watching a directory for changes
  • workspace_watch_poll(watch_id, timeout) — Poll a watch for events
  • workspace_watch_stop(watch_id) — Stop a watch
  • workspace_watch_list() — List active watches

Terminal

  • terminal_shell_create(cwd) — Create a new persistent PTY shell
  • terminal_shell_execute(shell_id, command, timeout) — Run a command in a shell
  • terminal_shell_read(shell_id) — Read pending output (non-blocking)
  • terminal_shell_resize(shell_id, rows, cols) — Resize the terminal
  • terminal_shell_list() — List active shells
  • terminal_shell_terminate(shell_id) — Kill a shell
  • terminal_process_start(command, cwd, proc_id) — Start a background process
  • terminal_process_logs(proc_id, lines) — Read process logs
  • terminal_process_stop(proc_id, timeout) — Stop a process
  • terminal_process_list() — List active processes

Usage Examples

Create a Persistent Dev Server Shell

# Create a shell
shell_resp = await terminal_shell_create(cwd=".")
shell_id = shell_resp["id"]  # "shell-abc123"

# Start a dev server (runs in background)
await terminal_shell_execute(shell_id, "npm run dev")

# Read output later
output = await terminal_shell_read(shell_id)
print(output["output"])  # "VITE ready in 314ms..."

# Even if the MCP server crashes, the shell survives.
# On restart, terminal_shell_list() will still see it.

Edit a File Without Resending It

# Read a file
file_resp = workspace_read_file("src/app.py")
before = file_resp["content"]

# Client (or Claude) modifies it locally
after = before.replace("const x = 1", "const x = 2")

# Send only the diff
diff = generate_unified_diff(before, after, "src/app.py")
patch_resp = await workspace_apply_patch("src/app.py", diff)
print(patch_resp["diff"])  # Shows what changed

Watch for Changes

# Start watching the src/ directory
watch_resp = await workspace_watch_start("src")
watch_id = watch_resp["id"]

# Do work (edit files, run git pull, etc.)
await asyncio.sleep(5)

# Poll for changes
poll_resp = await workspace_watch_poll(watch_id, timeout=1)
for event in poll_resp["events"]:
    print(event["change"], event["path"])  # "modified src/main.py"

Reconnection & Session Recovery

When the MCP server restarts:

  1. Shells: Their PTY metadata is loaded from the database and re-spawned. Background processes (like npm run dev) will still be running on the system; reconnecting to the shell picks up where you left off.

  2. Processes: Background processes are re-attached to if they're still alive (by PID lookup).

  3. Watches: Not persisted (ephemeral); will need to be recreated.

This design assumes you're running this in a long-lived container (Docker or systemd) and not losing the PID space.

Security

  • Workspace sandboxing: resolve_path() ensures all operations stay within WORKSPACE_ROOT. Symlinks are resolved and validated.
  • No command injection: Process commands are passed as strings to subprocess.Popen(..., shell=True), so be careful with user input. Consider restricting this tool in production.
  • No authentication: This server is designed for a trusted network (your local machine, or behind a VPN/Tailscale). Run it behind a reverse proxy with auth in production.

Performance

  • First-call startup: ~50ms (database init, shell spawn)
  • Shell execute: 5–100ms depending on command
  • File operations: <5ms (mostly I/O latency, not CPU)
  • Search: 50–500ms depending on repo size and pattern complexity
  • Watch poll: 0ms if no changes, else <50ms to report changes

Testing

Run the workspace module smoke test:

export WORKSPACE_ROOT=/tmp/fake_workspace
python test_workspace_manual.py

This tests sandboxing, file I/O, patching, searching, tree walking, and watching.

TODO / Future

  • [ ] LSP diagnostics integration (pull errors from code-server's language servers)
  • [ ] VS Code Tasks runner
  • [ ] Port detection (surface forwarded ports from code-server)
  • [ ] Editor state (which files are open, cursor position)
  • [ ] Git wrappers (optional; can be used via shells)
  • [ ] Docker wrappers (optional; can be used via shells)
  • [ ] More comprehensive logging and telemetry
  • [ ] Pytest suite (currently only manual smoke tests)

Contributing

This is a single-developer project. If you'd like to extend it:

  1. Add new tools in the appropriate module (workspace/, terminal/, or a new one).
  2. Register them in app.py with @mcp.tool().
  3. Update this README.

Built for Claude on code-server. Not affiliated with Anthropic or Coder.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选