Codex Free
Provides tools for interacting with Git repositories, including viewing status, committing changes, pushing commits to a remote, and viewing commit history.
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., "@Codex FreeCheck the git log and show me the last 5 commits"
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.
Codex Free
Codex Free (but you still have to buy ChatGPT Plus)
A local MCP bridge server that lets ChatGPT Web Pro call tools on your machine: read/write files, run shell commands, git operations, search. Built with Bun + TypeScript, using @modelcontextprotocol/sdk over Streamable HTTP.
ChatGPT talks to a public tunnel URL, which forwards to this server running on your machine, which operates on a project directory you choose.
Since v0.4.0 the tool set also covers the ones Codex gives its own agent — apply_patch, exec_command/write_stdin, view_image, update_plan, clock_curr_time/clock_sleep — so ChatGPT Web can work the way Codex does: patch files in place instead of rewriting them, drive interactive and long-running processes, and keep a plan across a task. v0.5.0 added the project's AGENTS.md, and v0.6.0 Codex's own agent brief, so the client is told how to behave and not just what it can call. v0.7.0 addresses the one thing Codex never had to solve — a context window far smaller than the task — by bounding what a tool call can return and keeping a plan and notes on disk across conversations. v0.8.0 adds Codex's skills: a SKILL.md in the repo or your home directory teaches the client how you do a recurring task, and only the ones that apply are ever read. Schemas and prompt are ported from the Codex source, not reimplemented from guesswork.
Architecture
flowchart LR
ChatGPT["ChatGPT Web Pro"]
Tunnel["Public Tunnel\n(ngrok / cloudflared)"]
Server["Codex Free\nMCP Bridge\n:3000"]
Tools["Tool Registry"]
FS["read_file\nwrite_file\nlist_directory\ntree"]
Search["glob\ngrep"]
Shell["run_command"]
Git["git_status\ngit_push\ngit_commit\ngit_log"]
Edit["apply_patch"]
Exec["exec_command\nwrite_stdin"]
Agent["view_image\nupdate_plan\nclock_curr_time\nclock_sleep"]
Env["get_agent_brief\nget_environment\nget_project_doc"]
Mem["remember\nrecall"]
Skills["skills_list\nskills_read"]
WorkDir[("Project\nDirectory")]
State[("~/.codex-free\nmemory.json")]
SkillDirs[(".agents/skills\n.codex/skills")]
ChatGPT -- "HTTPS" --> Tunnel
Tunnel -- "HTTP\n/mcp" --> Server
Server -- "Streamable HTTP\n(MCP Protocol)" --> Tools
Tools --> FS
Tools --> Search
Tools --> Shell
Tools --> Git
Tools --> Edit
Tools --> Exec
Tools --> Agent
Tools --> Env
Tools --> Mem
Tools --> Skills
FS --> WorkDir
Search --> WorkDir
Shell --> WorkDir
Git --> WorkDir
Edit --> WorkDir
Exec --> WorkDir
Agent --> WorkDir
Env --> WorkDir
Mem --> State
Skills --> SkillDirsRelated MCP server: webgpt MCP
Quick start
bun install
bun run main.ts --work-dir /path/to/your/projectServer starts on http://localhost:3000. MCP endpoint is /mcp.
CLI flags
Flag | Required | Default | Description |
| Yes | - | Project directory the tools operate on |
| No |
| Server port |
| No | - | Bearer token for auth |
| No |
| Config file path |
Tools
Structured primitives — cheaper and safer than shelling out for the same job, and identical on Windows and POSIX:
Tool | Description |
| Read a file's contents, a bounded window at a time, with optional line offset/limit |
| Write content to a file, creating parent directories if needed |
| Execute a command in the work directory (allowlist-restricted) |
| Show git status, parsed into changed files with status codes |
| Push commits to a remote |
| Create a commit, optionally staging all tracked changes |
| Show recent commit history |
| Find files matching a glob pattern |
| Search file contents by regex, with optional context lines |
| List files and directories with name, type, and size |
| Print directory tree as ASCII art |
Ported from Codex (codex-rs/core/src/tools at commit 2230d64, codex-rs/ext/skills at 902bd9e):
Tool | Codex name | Description |
|
| Edit files with a context patch instead of rewriting them |
|
| Run a shell command; returns output, or a session id if it is still running |
|
| Write to (or poll) a running |
|
| Load a local image file for visual inspection |
|
| Track a multi-step plan; saved to disk so a later conversation can pick it up |
|
| Current time in UTC |
|
| Pause for a given duration |
|
| List the |
|
| Read a skill's instructions, or another file in its package |
Codex's dotted names are flattened to underscores because MCP tool names must match ^[a-zA-Z0-9_-]{1,64}$.
Five tools have no Codex counterpart:
Tool | Description |
| Return the whole operating brief — behaviour, environment, saved state and project rules — in one call |
| Report the OS, the shell |
| Read the project's |
| Save one durable note about the task under a short key |
| Return the plan and notes saved by earlier turns or earlier conversations |
Codex needs the first three for none of these reasons: it puts its agent brief in the system prompt, the OS and shell in an <environment_context> message, and AGENTS.md straight into the prompt, all before the first turn. An MCP server has none of those channels — it can only expose tools — so the same facts are tool calls here as well as part of the server's instructions. It needs remember and recall for the opposite reason: its context is large and its session state lives in the CLI process, whereas the client here is a chat window that loses the conversation. See Acting as a Codex agent, Shells and the host, AGENTS.md and Context and memory.
Two deliberate differences from Codex:
apply_patchtakes a JSON string. In Codex it is a freeform tool whose entire body is the raw patch. MCP has no freeform tools, so the patch goes in aninputstring parameter. The patch format itself is unchanged.exec_commandruns with plain pipes, not a PTY. Codex's ownttyparameter documents pipes as the default, so ordinary commands behave the same;tty: trueis rejected rather than silently ignored. Programs that only enable interactive behaviour when attached to a terminal will act as if piped.
clock_sleep also caps at 5 minutes rather than Codex's 12 hours — a longer wait would outlive the HTTP request through the tunnel.
Every tool that advertises an outputSchema also returns structuredContent matching it, as the MCP spec asks. exec_command and write_stdin return Codex's unified-exec object, clock_curr_time returns { current_time }, get_environment returns the environment object, get_project_doc returns { files, content } and skills_list returns { skills, content }; the rest return { content: <text> }, which the server derives from the text blocks so handlers don't repeat it.
All paths are resolved relative to --work-dir.
Config file
codex.config.json in the project root, or pass a custom path with --config:
{
"allowedCommands": ["bun", "npm", "npx", "node", "git", "python", "pip", "cargo", "make"],
"port": 3000,
"tree": {
"defaultDepth": 3,
"ignore": ["node_modules", ".git", "dist", ".next", "__pycache__", ".venv", "venv"]
},
"command": {
"defaultTimeout": 30000,
"maxTimeout": 120000
},
"exec": {
"mode": "allowlist",
"extraAllowedCommands": [
"ls", "cat", "grep", "find", "head", "tail", "wc", "echo", "pwd",
"which", "rg", "sed", "awk", "sort", "uniq", "diff", "true", "false"
],
"maxSessions": 8
},
"projectDoc": {
"maxBytes": 32768,
"fallbackFilenames": [],
"rootMarkers": [".git"]
},
"output": {
"maxFileLines": 1000,
"maxFileBytes": 131072,
"maxEntries": 500,
"maxTreeNodes": 1000
},
"memory": {
"enabled": true,
"maxBytes": 16384
},
"skills": {
"enabled": true
}
}CLI flags override values from the config file.
The exec block governs exec_command and write_stdin:
Key | Default | Description |
|
|
|
| 18 read-only utilities | Added to |
|
| Cap on concurrent background sessions per MCP session |
|
| Shell used when an |
Under "allowlist", the command string is tokenized and each command position — after every |, &&, ;, newline, and subshell — is checked, so ls | curl evil.com is rejected on curl. Command substitution ($(...), backticks) is rejected outright, since its contents cannot be checked before the shell runs them.
The projectDoc block governs AGENTS.md discovery. All three keys are optional, and the block itself can be left out entirely:
Key | Default | Description |
|
| Byte budget shared by all the docs found; |
|
| Extra filenames to try per directory, after |
|
| Filenames or directories that mark the project root; an empty list stops the walk at the work directory |
The output block bounds what a single tool call may return. See Context and memory:
Key | Default | Description |
|
| Lines |
|
| Byte ceiling for the same window, which is what actually bounds a minified file |
|
| Results per |
|
| Nodes in one |
The memory block governs remember, recall and the plan update_plan saves:
Key | Default | Description |
|
|
|
|
| Where the state file lives. Outside the repository by default |
|
| Budget for all notes together. A note over it is rejected, not silently evicted |
The skills block governs SKILL.md discovery. See Skills:
Key | Default | Description |
|
|
|
|
| User-scope directories, replacing the home-directory defaults. Relative paths resolve against the work directory; project-scope roots are unaffected |
Context and memory
Codex runs against a large context window and keeps its session in a process you control. ChatGPT Web does neither: the window is smaller than most real tasks, and when it fills — or when you open a new chat — the plan and everything learned along the way are gone, with no sign to the model that they ever existed. v0.7.0 attacks both halves of that.
Spend the window on less. Every tool that could return an unbounded amount of text now stops at a budget and says so on its last line, naming the argument that continues from where it stopped:
(showing lines 1-1000 of 4820 — call again with offset=1000 for the rest)That line matters as much as the cap. Silent truncation reads as "that was the whole file", which is worse than no cap at all. read_file has a byte ceiling as well as a line one, because a minified bundle is a single line several megabytes long that a line cap alone would hand back in full. exec_command and grep were already bounded, ported that way from Codex.
Keep what would be expensive to rediscover. remember writes one keyed note; recall hands back the notes and the current plan. update_plan now persists too, so the plan survives the conversation that made it. Writing to a key that exists replaces it, and an empty value deletes it — a keyed store stays current where an append log accumulates contradictions until it is worthless.
State lives in ~/.codex-free/projects/<name>-<hash>/memory.json, keyed by the absolute work directory. Nothing is written into the repository you pointed the server at, and two checkouts of the same repo do not share notes.
Because instructions is rebuilt for every MCP session, a new conversation opens with the saved plan and notes already in front of it, under a ## Saved state heading between the environment and AGENTS.md. If the client ignores instructions, one recall gets the same thing.
The division of labour is worth keeping straight: AGENTS.md is what is true of the project and belongs in the repo; notes are what is true of the task in flight and belong here.
Acting as a Codex agent
A tool list says what a model can do; it says nothing about how a careful engineer uses it. Codex closes that gap with a system prompt, and since v0.6.0 so does this bridge — the behavioural half of codex-rs/core/gpt-5.2-codex_prompt.md is ported into the server's instructions.
That brief is what stops the client rewriting a file it never read, reverting your uncommitted work, reaching for git reset --hard, or making a one-step plan. It carries Codex's editing constraints (ASCII by default, comments only where they earn their place, apply_patch over rewrites, and the dirty-worktree rules in full), its planning rules, its code-review posture, and its habit of reporting back concisely without pasting files you already have on disk.
The initialize response layers Codex's four in Codex's own order, each outranking the one above it, plus one Codex has no need for:
The agent brief — how to behave.
The environment — OS, shell, work directory, command policy.
Saved state — the plan and notes left by earlier work, when there are any. See Context and memory.
The skill catalogue — what this project and this user already know how to do, when any is installed. See Skills.
AGENTS.md— the project speaking for itself, behind the--- project-doc ---marker.
Three parts of Codex's prompt are deliberately dropped. Its rg preference is redundant here, since grep and glob are tools that behave the same on every OS. Its final-answer style rules and clickable file-reference syntax both exist to drive a terminal renderer, and an MCP client renders markdown — importing them would produce CLI-flavoured output in a chat window. What those sections were for — brevity, not dumping files, relaying output the user cannot see — is kept.
Starting a chat
instructions is the proper channel, but no client is obliged to show it to its model, and ChatGPT Web is not reliable about it. get_agent_brief returns the identical string, so one line is enough to onboard a conversation:
Call get_agent_brief and follow it for the rest of this chat.
Task: <what you want done>Everything else — the shell you're on, the allowlist, your repo's AGENTS.md — arrives with that one call. If a chat starts drifting back into generic-assistant behaviour, asking for the brief again re-anchors it.
Shells and the host
Windows, macOS and Linux are all supported natively; there is no WSL or POSIX-emulation layer in between. Which shell runs is decided by name, not by host platform, the same way Codex's Shell::derive_exec_args does it:
Shell | Invoked as |
|
|
|
|
|
|
The default comes from $SHELL on every platform, so starting the server from Git Bash on Windows gets bash — with real ls -la, pipes and $VAR — rather than PowerShell. Set exec.defaultShell to override, or pass shell on an individual exec_command call.
Two Windows-specific details are handled: powershell -Command collapses every non-zero child exit code to 1, so commands are wrapped to re-raise $LASTEXITCODE; and exec_command's description gains Codex's PowerShell rules (-LiteralPath over -Path, -WindowStyle Hidden) when the server runs there.
Because the resolved shell decides what a command should even look like, it is published three ways — a client only has to read one of them:
instructionsin theinitializeresponse, as the Environment section of the agent brief.exec_command's description, which names the actual shell binary and its syntax family.get_environment, for clients that read neither.
AGENTS.md
A project's AGENTS.md is how it tells an agent its own conventions — which test command to run, which files not to touch, how commits should look. Codex reads it before the first turn; since v0.5.0 so does this bridge, using the same algorithm as codex-rs/core/src/agents_md.rs.
Discovery walks up from --work-dir to the nearest directory holding a root marker (.git by default), then collects one doc per directory on the way back down, so a monorepo's root conventions arrive before the ones belonging to the subdirectory you pointed the server at. In each directory, AGENTS.override.md wins over AGENTS.md, which wins over anything in projectDoc.fallbackFilenames. The files are concatenated outermost-first under a shared 32 KiB budget, counted in bytes rather than characters; a file that runs past what is left is cut there and reported as truncated, and whitespace-only files are skipped without spending any of it. If no marker is found anywhere above, only the work directory itself is checked.
Like the environment, the result is published more than one way:
instructionscarries the doc inline, behind Codex's own--- project-doc ---separator. Everything past that marker is the project speaking, and it outranks the agent brief above it.get_project_docreturns the identical text for clients that never readinstructions, along with the absolute path of every file it came from and whether each was truncated.
Instructions are built per MCP session, so editing AGENTS.md takes effect on the next connection without restarting the server.
Skills
AGENTS.md says what is true of the project always. A skill says how to do one recurring task well — cut a release, review a PR the way this team reviews PRs, debug the flaky suite — and is only read when that task comes up. Codex has had them since its extension crate landed; v0.8.0 ports the format and the discovery, from codex-rs/ext/skills and codex-rs/skills.
A skill is a directory holding a SKILL.md whose YAML frontmatter names it and says when it applies:
.agents/skills/
└── release/
├── SKILL.md
├── references/versioning.md
└── scripts/tag.sh---
name: release
description: Cut and publish a release of this project
---
1. Check `bun test` and `bunx tsc --noEmit` are clean.
2. Bump the version in `package.json` and `src/server.ts` together.
3. Run `scripts/tag.sh`; see `references/versioning.md` for what the tag must look like.description is required — it is the only thing the model sees before deciding whether the skill is worth reading. name defaults to the directory name. metadata.short-description is optional. A skill whose frontmatter cannot be used is reported by skills_list rather than silently dropped, because the author meant it to be there.
Where they are found, in precedence order:
Scope | Directories |
|
|
|
|
Repo skills come first, so a project decides how a name behaves inside it; a personal skill of the same name is shadowed and skills_list says so rather than merging the two.
What the model sees. The catalogue — a name and a description per skill — goes into instructions under a ## Skills heading, so a chat opens knowing what is available without spending a call to find out. Bodies are not loaded: skills_read fetches one only once a skill has actually been chosen. That is the progressive disclosure that makes a large library affordable on a small context window. The section is omitted entirely when nothing is installed.
Reaching the rest of a package. Reference files, scripts and assets are read with skills_read and the skill's name, passing the file's path as resource. read_file will not do: it is confined to --work-dir, and user-scope skills live in your home directory. Paths inside a skill are relative to the skill's own directory, and a resource that tries to leave it is rejected — so the only thing this opens up is the inside of a skill you or the project deliberately installed. Reading a SKILL.md lists the package's other files, since the model cannot glob a directory it cannot see.
Discovery runs per MCP session, so adding a skill takes effect on the next connection without restarting the server. Set skills.enabled to false to turn the whole thing off.
Connecting to ChatGPT
In ChatGPT, go to Settings > Security and login and enable Developer mode.
Start the server:
bun run main.ts --work-dir /path/to/your/projectExpose it with a tunnel (ngrok, Cloudflare Tunnel, etc.):
ngrok http 3000In ChatGPT, go to Plugins > + New Plugin.
Set the Server URL to the tunnel URL with
/mcpappended, e.g.https://<your-tunnel>/mcp.Set Authentication to "No Auth".
After creating the plugin, go to Permissions and set it to Allow all actions so ChatGPT can call tools without asking for confirmation each time.
In a new chat, enable the plugin from the composer's tools menu, then open with
Call get_agent_brief and follow it for the rest of this chat.— see Acting as a Codex agent.
ChatGPT Plugins only support OAuth, No Auth, and Mixed. The
--api-keyoption is for non-ChatGPT clients or tunnel-level auth. When using ChatGPT, secure access through your tunnel provider instead (e.g. ngrok IP restrictions, Cloudflare Access).
Security
Path traversal prevention: every filesystem tool — including
apply_patchandview_image— resolves paths through a guard that rejects anything outside--work-dir.One bounded exception: AGENTS.md discovery reads above
--work-dir, up to the nearest.git. Nothing else does. It is read-only, opens onlyAGENTS.override.md,AGENTS.mdand anyprojectDoc.fallbackFilenames, andget_project_docreports the absolute path of every file it used. SetprojectDoc.maxBytesto0to switch it off, orprojectDoc.rootMarkersto[]to keep the search inside the work directory.One bounded write outside the work directory:
rememberandupdate_planwritememory.jsonunder~/.codex-free/, deliberately outside the repository so nothing lands in your git history. It holds whatever the model chose to note about the task — read it if you want to know, delete the directory to forget, or setmemory.enabledtofalseto never write it. The write is atomic (temp file plus rename) and guarded by a per-project lock, so a crash mid-write never leaves a torn file and two servers pointed at the same work directory do not lose each other's notes to an interleaved update. See Context and memory.One bounded read outside the work directory: skills may live in
~/.agents/skillsor~/.codex/skills.skills_readopens files there, but only inside a skill package that already exists — theresourcepath is checked against the skill's own directory, so it cannot walk out into the rest of your home directory.skills_listreports the absolute path of every skill it found. Setskills.enabledtofalseto switch it off, orskills.dirsto point the user scope somewhere you choose.Command allowlist:
run_commandonly runs binaries listed inallowedCommands; everything else is rejected.exec_commandchecks the same list plusexec.extraAllowedCommands, at every command position in the string.Optional bearer token auth: set
--api-keyto require anAuthorization: Bearer <key>header on all requests (except/health). Useful for non-ChatGPT clients. ChatGPT Plugins do not support simple bearer token auth.
The allowlist is a guardrail against accidents, not a sandbox. It catches a model reaching for curl or rm -rf; it does not contain a determined one. The defaults already include node, python and bun, each of which runs arbitrary code — node -e "..." can do anything the server process can. Shell redirection can also write outside the work directory even though the command's cwd is confined to it. Treat everything below as reachable by whoever holds the tunnel URL:
everything in
--work-dir, read and writeanything else the user account running the server can touch, via an allowlisted interpreter
the network, from your machine
exec_command sessions that outlive a request are killed when the MCP session closes, and the kill takes the children with it: taskkill /T /F walks the process tree on Windows, and on POSIX each session gets its own process group that is signalled as a whole. A process that deliberately re-parents or daemonises itself still escapes, so check for strays if a run leaves something listening.
Don't expose this without tunnel-level access control (ngrok IP restrictions, Cloudflare Access), and don't point it at directories you don't trust ChatGPT with. If the work directory holds anything sensitive, set exec.mode and the allowlists tighter than the defaults rather than relying on them.
Dev commands
bun run dev # watch mode
bun test # tests
bunx tsc --noEmit # type checkLicense
MIT - see LICENSE.
This 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.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceLocal MCP server bridging ChatGPT Web to local tools for file, shell, git, test, and process management with secure policy controls.MIT
- FlicenseNot gradedqualityCmaintenanceLocal MCP server for Codex to send prompts to ChatGPT Web Pro extension and manage repository tasks safely.
- FlicenseBqualityBmaintenanceA local MCP server that bridges ChatGPT to a Windows PC, offering filesystem, shell, Git, and diagnostic tools via a secure tunnel.17
- AlicenseNot gradedqualityAmaintenanceA lightweight local coding MCP server that exposes a single project directory to ChatGPT via Streamable HTTP, enabling file operations, command execution, search, and web fetching without authentication.38120MIT
Related MCP Connectors
An MCP server that gives your AI access to the source code and docs of all public github repos
A MCP server built for developers enabling Git based project management with project and personal…
A comprehensive Model Context Protocol (MCP) server that enables AI assistants to interact with yo…
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/hypnguyen1209/codex-free'
If you have feedback or need assistance with the MCP directory API, please join our Discord server