GPT Harness

GPT Harness

A self-hosted MCP gateway that gives ChatGPT Web real command execution, file patching, and workspace management on a VPS you control.

Category
访问服务器

README

GPT Harness

A self-hosted MCP gateway that gives ChatGPT Web real command execution, file patching, and workspace management on a VPS you control.

[!WARNING] This is a personal experiment, not a product. It is built for a single owner, has no support channel, no stability guarantees, and no migration path between versions. In its most permissive configuration it hands whoever holds your ChatGPT session administrative control of your server. Read the security model before you run it, and use it at your own risk.

Why this exists

ChatGPT Web is good at reasoning about code, but its built-in agentic tooling is usage constrained — you run out of agent capacity long before you run out of chat.

GPT Harness takes a different route. Instead of using ChatGPT's own agent, you connect it to a custom MCP server running on your machine. ChatGPT stays the reasoning layer and picks the tools; your VPS does the actual work. Because the interaction happens through ordinary chat turns, the ceiling is your ChatGPT message quota rather than a separate agent-tool allowance.

The execution side is not homegrown. Commands run through Codex app-server, which supplies the filesystem and network sandbox, so the gateway's job is authentication, workspace identity, tool surface, and process lifecycle — not inventing its own isolation.

[!NOTE] Custom MCP connectors in ChatGPT require developer mode, which OpenAI ships as a beta. Availability and write support have shifted between plans over time — this was set up and verified on a Plus account, but check Developer mode and MCP apps in ChatGPT for what your account can do today.

What it does

  • Persistent workspaces. Every direct child of your workspace root is a project with a durable generation ID. New chat sessions inherit a default workspace; existing ones keep their own selection.
  • Three execution modes. Sandboxed workspace commands, an opt-in network-enabled command, and — if you deliberately enable it — unsandboxed host commands.
  • Long-running processes. Commands that outlive their yield window return an opaque handle you can poll, write stdin to, and stop, with bounded output and retention.
  • Unified diff patching. apply_patch validates with git apply --check before touching the working tree, and rejects traversal, absolute paths, and .git mutation.
  • An admin portal. A separate service at /admin for creating and cloning workspaces, reviewing configuration changes before applying them, and inspecting activity — which stays up even when the gateway is down.

How it works

flowchart LR
    A[ChatGPT Web] -->|HTTPS + OAuth| B[Caddy]
    B -->|/mcp| C[Gateway]
    B -->|/admin| D[Admin portal]
    C -->|JSON-RPC| E[Codex app-server]
    E --> F[(Workspaces)]
    D -.->|control.sock| C
    D --> G[(SQLite state)]

The gateway validates every tool call against your Auth0 issuer, audience, JWKS signature, expiry, and exact OAuth subject — one account, pinned. It then maps the tool to a command/exec call on a single pinned Codex app-server connection.

The admin portal runs as its own systemd service with no health dependency on the gateway. It reads live runtime state over a private /run/gpt-harness/control.sock Unix socket that the reverse proxy never exposes, so when the gateway is down the portal degrades into a recovery mode you can still fix configuration from.

Requirements

  • A Linux VPS you control, with a domain and TLS
  • Node.js 24 and npm 11+
  • The pinned Codex CLI (currently 0.145.0 — see Upgrading the Codex pin)
  • An Auth0 tenant
  • A ChatGPT account with developer mode available

Getting started

Local first, so you can see the tool surface before wiring up a public host.

git clone https://github.com/salman-frs/gpt-harness.git
cd gpt-harness
npm ci
cp .env.example .env

Edit .env and point HARNESS_WORKSPACE_ROOT and HARNESS_STATE_DIR at disposable local directories, then set the Auth0 values from the setup guide. Start the gateway:

npm run dev

/healthz is unauthenticated and answers immediately; MCP is served at /mcp. Tool discovery works anonymously for protocol compatibility, but no tool will execute without a valid token.

From there:

  1. Connect ChatGPT — create the Auth0 API and application, expose the gateway over HTTPS, and register the custom MCP connector.
  2. Deploy properly — dedicated service user, systemd units, reverse proxy, and versioned releases with rollback.
  3. Understand what you're accepting — the trust boundary and the risks that come with it.

Tools

Which tools appear depends on how you configure HARNESS_MODE and HARNESS_NETWORK at startup:

Configuration Workspace command Network command Host command
default + on-request exec.sandbox, network restricted exec.network, one command hidden
default + always exec.sandbox, network enabled hidden hidden
full exec.sandbox, network enabled hidden exec.full

Start with default + on-request. It keeps writes inside the active workspace and makes outbound network a per-command decision. Use full only if you actually want ChatGPT administering the host.

Every mode exposes:

  • workspace.list {} — projects, active workspace, mode, and effective network policy
  • workspace.use {"name":"project"} — create or resolve a project
  • workspace.delete {"name":"project","confirmation":"project"} — permanently delete an exact generation
  • exec.sandbox {"workspace":"project","command":"npm test"} — workspace-bounded command
  • exec.network {"workspace":"project","command":"npm ci"} — one network-enabled command, when exposed
  • exec.full {"workspace":"project","command":"sudo systemctl status example","cwd":"/"} — host command, when full mode is on
  • apply_patch {"workspace":"project","patch":"diff --git ..."} — validate and apply a unified diff
  • process.poll, process.write, process.stop — manage long-running command handles

Changing mode or network policy requires a service restart and a refresh or reconnect of the ChatGPT app, so the client rescans the tool list.

Every exec and patch call names its workspace explicitly. MCP clients may open a fresh transport for each tool call, so workspace.use cannot safely carry selection state into a later request. The persisted default is informational; commands never fall back to it.

Notes that will save you time

Codex workspace-write protects top-level .git, .agents, and .codex metadata. You can edit files and run git status or git diff, but git init, git add, and git commit need host provisioning or exec.full.

In default + on-request, sandboxed commands cannot create TCP or Unix listeners. To run a temporary dev server, start it with exec.network, bind it explicitly to 127.0.0.1, and probe it with another exec.network call. Never bind validation servers to 0.0.0.0.

Processes started through exec tools are temporary and die on timeout or gateway shutdown. Anything that needs to survive has to be handed to a real supervisor — sudo systemctl enable --now example.service or docker compose up -d.

Admin portal

The portal creates blank workspaces, clones credential-free GitHub SSH or HTTPS repositories through private staging directories, shows local-only Git status, performs explicit bounded git fetch --prune, changes the default workspace, and permanently deletes an exact name-and-generation identity. Clone and fetch progress streams over SSE.

Configuration changes are reviewed before they are applied: the portal shows a diff, stops active temporary processes only after you confirm, restarts the gateway, verifies the expected fingerprint, and automatically restores the previous backup if health checks fail.

<!-- Screenshots: add files to docs/images/ and uncomment. Dashboard Workspaces Configuration review -->

Security

The hard boundaries are OAuth, startup configuration, the Codex per-command sandbox, and the Linux permissions of the dedicated service user. Everything else is a convention, not a control.

[!CAUTION] HARNESS_MODE=full exposes an unsandboxed host command tool. If the service user also has NOPASSWD: ALL, a compromised ChatGPT session is a compromised server. Enable full mode deliberately or not at all.

Two things are worth internalising before you connect anything real: the model can read any file in a workspace, including .env secrets, and command output is returned verbatim up to its cap — so a command that prints a secret hands that secret to ChatGPT. Prompt instructions are not a secret boundary. The full picture, including residual risks that are accepted rather than mitigated, is in docs/security.md.

Development

npm ci
npm run format
npm run check
npm test
npm run build

The default test run uses a fake transport. To exercise the real pinned Codex binary:

HARNESS_TEST_CODEX_BIN="$(command -v codex)" npm run test:acceptance
HARNESS_TEST_CODEX_BIN="$(command -v codex)" HARNESS_TEST_FULL=true npm run test:acceptance

These are deterministic and harmless. They cover multiple workspaces on one connection, restricted and enabled network policy, streamed stdin and output, patching in a non-Git workspace, process termination, and — with HARNESS_TEST_FULL — host and sudo access.

Browser tests for the admin portal run separately with npm run test:browser.

Upgrading the Codex pin

Codex app-server is a pinned external security boundary, so upgrades are gated:

  1. Choose the newest stable, non-prerelease release.
  2. Verify the artifact source, version, and SHA-256.
  3. Run codex app-server generate-ts --out src/codex/generated --prettier ./node_modules/.bin/prettier and review protocol changes. Only the stable command/exec family and sandboxPolicy are used in production.
  4. Run type checks, fake-transport tests, and the full real-backend acceptance suite.
  5. Smoke-test MCP locally.
  6. Update the version and hash only after every gate passes.

Project layout

src/auth/         OAuth resource-server validation
src/codex/        App-server JSON-RPC client, generated types, process registry
src/server/       HTTP and MCP SDK integration
src/tools/        Exec and unified-diff behavior
src/admin/        Admin portal server, APIs, and recovery mode
src/config/       Structured config review, apply, restart, and rollback
src/control/      Private gateway/admin Unix-socket control plane
src/metrics/      Redacted activity and aggregate metrics
src/storage/      SQLite state and migrations
src/workspace/    Generation-safe workspace lifecycle and Git helpers
admin-web/        React admin portal frontend
tests/            Unit, integration, and real-backend acceptance tests
deploy/           systemd units, sudoers, reverse proxy example, release scripts
docs/             Setup, deployment, and security documentation

推荐服务器

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

官方
精选