GPT Harness
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@GPT Harnessrun 'ls' in my current workspace"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
GPT Harness
A self-hosted MCP gateway that gives ChatGPT Web real command execution, file patching, and workspace management on a VPS you control.
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. Readthe 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.
Custom MCP connectors in ChatGPT requiredeveloper 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_patchvalidates withgit apply --checkbefore touching the working tree, and rejects traversal, absolute paths, and.gitmutation.An admin portal. A separate service at
/adminfor 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 .envEdit .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:
Connect ChatGPT — create the Auth0 API and application, expose the gateway over HTTPS, and register the custom MCP connector.
Deploy properly — dedicated service user, systemd units, reverse proxy, and versioned releases with rollback.
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 |
|
|
| hidden |
|
| hidden | hidden |
|
| hidden |
|
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 policyworkspace.use {"name":"project"}— create or resolve a projectworkspace.delete {"name":"project","confirmation":"project"}— permanently delete an exact generationexec.sandbox {"workspace":"project","command":"npm test"}— workspace-bounded commandexec.network {"workspace":"project","command":"npm ci"}— one network-enabled command, when exposedexec.full {"workspace":"project","command":"sudo systemctl status example","cwd":"/"}— host command, when full mode is onapply_patch {"workspace":"project","patch":"diff --git ..."}— validate and apply a unified diffprocess.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.
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.
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 buildThe 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:acceptanceThese 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:
Choose the newest stable, non-prerelease release.
Verify the artifact source, version, and SHA-256.
Run
codex app-server generate-ts --out src/codex/generated --prettier ./node_modules/.bin/prettierand review protocol changes. Only the stablecommand/execfamily andsandboxPolicyare used in production.Run type checks, fake-transport tests, and the full real-backend acceptance suite.
Smoke-test MCP locally.
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 documentationThis server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/salman-frs/gpt-harness'
If you have feedback or need assistance with the MCP directory API, please join our Discord server