dev-mcp

dev-mcp

A self-contained Docker Compose deployment that exposes MCP tools for files, shell commands, background processes, and Git operations, enabling ChatGPT to work with a host directory via OAuth authentication.

Category
访问服务器

README

dev-mcp

dev-mcp is a self-contained Docker Compose deployment that lets ChatGPT use MCP tools to work with files, shell commands, background processes, and Git in one host directory. It does not use an OpenAI API key, run Codex CLI, or expose the Docker socket to the MCP services.

Internet / ChatGPT
        │ HTTPS :443
        ▼
      Caddy ── internal HTTP ──▶ gateway ── Unix socket ──▶ runner
                                   │                         │
                              gateway-data              /workspace:rw
                              (OAuth only)               runner-data

The gateway cannot see /workspace. The runner cannot see OAuth state or the administrator password hash. The services use separate Docker networks and share only the runner's Unix socket volume.

Requirements

  • A Linux host with Docker Engine and Docker Compose v2
  • Git, for cloning this repository
  • A public DNS A/AAAA record pointing to the host
  • Inbound TCP 80/443; UDP 443 is recommended for HTTP/3

The runner builds directly from the official fedora:44 image. No local base image, dev container repository, host Node.js installation, Codex installation, Docker socket, SSH key, or host home mount is required.

Quick setup

On a new host:

git clone https://github.com/Crasnec/dev-mcp.git
cd dev-mcp
./scripts/setup.sh

The interactive setup command:

  • creates the host workspace directory;
  • detects the host UID and GID;
  • asks for the public domain and ACME email;
  • generates the administrator scrypt hash without storing the password;
  • writes a mode-0600 .env file with absolute host paths;
  • builds the Fedora runner, gateway, and Caddy stack;
  • starts the services with Docker Compose.

Host Node.js is optional. If Node.js 22 is unavailable, setup uses a temporary node:22-alpine container only for password hashing.

Setup uses Let's Encrypt staging by default. Once DNS, HTTPS, OAuth, and MCP tool calls work, switch to production certificates:

./scripts/setup.sh --force --production
./scripts/verify-deployment.sh

--force intentionally replaces the host-specific .env; the OAuth and runner named volumes are preserved. Use --no-start to create and validate .env without starting containers.

Certificate issuance requires correct DNS and public access to ports 80 and 443. See the Caddy HTTPS quick-start for the external requirements.

Connect ChatGPT

Enable developer mode, create a developer-mode app, and use this MCP endpoint:

https://<MCP_DOMAIN>/mcp

The gateway supports Dynamic Client Registration and opens an Authorization Code + PKCE login page. Follow the OpenAI ChatGPT connection guide.

After any deployment that changes tool names, descriptions, annotations, or OAuth schemes, open the app in Settings → Plugins, choose Refresh, and test it in a new conversation. Existing ChatGPT conversations may retain an older tool snapshot.

Moving to another host

The repository contains everything needed to rebuild the service. On the new host, clone it and run ./scripts/setup.sh; do not copy node_modules, build output, a local development image, SSH credentials, or Codex state.

Host-specific configuration stays in the ignored .env file. OAuth clients/tokens, the project registry, process logs, and Caddy certificates live in Docker named volumes and are not part of Git. A fresh host therefore starts with fresh OAuth state; refresh or recreate the ChatGPT app after DNS points to the new deployment.

To migrate state instead of starting clean, back up and restore these volumes using your normal Docker volume procedure:

  • dev-mcp_gateway-data
  • dev-mcp_runner-data
  • dev-mcp_caddy-data
  • dev-mcp_caddy-config

Do not copy the transient runner-ipc volume.

Manual configuration

If you do not want the setup script:

cp .env.example .env
chmod 600 .env
npm run password-hash  # requires local Node.js 22 and a TTY
$EDITOR .env
docker compose config --quiet
docker compose up -d --build
./scripts/verify-deployment.sh

Set WORKSPACE_DIR and CADDYFILE_PATH to absolute paths visible to the Docker daemon. Set DEV_UID and DEV_GID to the owner of the workspace files.

For optional resource limits, add the example override explicitly:

docker compose -f compose.yaml -f compose.limits.yaml.example up -d --build

MCP tools

Every tool returns a short text summary and structured content in this form:

{
  "ok": true,
  "data": {},
  "truncated": false,
  "continuation": "optional opaque cursor"
}

Errors include error.code, error.message, and optional error.details.

Area Tools
Projects project_list, project_register, project_clone, project_unregister, project_delete
Files file_list, file_read, file_search, file_apply_patch
Commands command_run, command_output
Processes process_start, process_list, process_status, process_logs, process_stop
Git git_status, git_diff, git_log, git_commit

command_run and process_start require network_intent to be none, read, or write. This value is used for OAuth authorization, ChatGPT confirmation policy, and auditing; it is not a runner-side network firewall. Command and Git output over 64 KiB is saved in runner data and paginated through command_output. Process logs use the process_logs cursor.

Tool annotations distinguish reads, writes, destructive actions, and external communication. Shell calls always advertise destructiveHint: true and openWorldHint: true. The design follows the OpenAI tool guidance.

OAuth scopes

The gateway provides:

  • /.well-known/oauth-protected-resource and path-specific /mcp metadata;
  • /.well-known/oauth-authorization-server;
  • /oauth/register, /oauth/authorize, /oauth/token, and /oauth/revoke.

It supports a single administrator using Authorization Code + PKCE (S256) and public-client DCR. Authorization codes are one-time and valid for five minutes. Access tokens last 15 minutes, refresh tokens last 30 days, and refresh tokens rotate on use. Codes and tokens are stored only as SHA-256 hashes in gateway-data.

Scope Operations
workspace:read Project, file, and Git reads
workspace:write Registration, patching, deletion, and commits
command:run Synchronous commands, processes, and logs
command:network Cloning or commands/processes with non-none network intent

Each tool publishes its OAuth policy. Insufficient-scope results include an MCP authentication challenge so ChatGPT can request additional authorization. The implementation follows the OpenAI Apps SDK authentication requirements and the MCP OAuth protected-resource model.

Security boundary

  • Only the runner receives ${WORKSPACE_DIR} as /workspace:rw. The workspace root itself cannot be registered as a project.
  • File paths receive lexical checks followed by realpath checks. Absolute paths, parent traversal, symlink escapes, and patch escapes are rejected.
  • Public cloning accepts credential-free HTTPS URLs from GitHub, GitLab, and Bitbucket. SSH, URL credentials, loopback, and private targets are rejected.
  • Neither service receives the Docker socket, SSH keys, host home, ~/.codex, or Codex credentials.
  • Child processes receive a clean PATH, runner-only HOME, locale, and optional Git author values. Gateway variables and OAuth tokens are not inherited.
  • Gateway and runner use read-only root filesystems, dropped capabilities, non-root users, and no-new-privileges.
  • The runner image includes Bash, Git, ripgrep, Node.js, Python, Rust, and common native build tools, but no Docker CLI, Codex CLI, or sudo.
  • Compose applies no default CPU, memory, or command-duration limit. It limits synchronous commands to four and background processes to eight by default; .env can change these values.
  • Audit records are stored in gateway-data/audit.jsonl. Patch bodies and continuation/token values are omitted; command strings are limited to 2,000 characters.

This service deliberately exposes arbitrary shell execution and destructive file operations to an OAuth-authorized client. Use a unique administrator password and consider firewall, rate limiting, or an additional access-control layer.

Development and verification

npm ci
npm run style
npm run typecheck
npm test
npm run build
docker compose config --quiet

Tests cover PKCE, one-time codes, refresh rotation, revocation, path and symlink escapes, project registration through commit, long-output pagination, and background process lifecycle. After deployment, scripts/verify-deployment.sh checks public HTTPS metadata, the authentication challenge, mount isolation, network separation, and read-only roots.

推荐服务器

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 模型以安全和受控的方式获取实时的网络信息。

官方
精选