No inbound port
Nothing listens on the machine serving a project. The CLI opens the connection and holds it, so there is nothing to expose and nothing to forward
Speaks MCP, so it works with
Claude
ChatGPT
Cursor
VS Code
Copilot
Devin
Antigravity
Amp
Zed
Grok
Perplexity
OpenCode
Anything that speaks Streamable HTTP and OAuth 2.1 can connect. There is no Exeora plugin to install on the client side
How it works
No inbound network path, no copy of your code, and no shared blast radius between projects
The machine opens an outbound WebSocket to Exeora and holds it. There is no inbound port, no tunnel to configure and no VPN, which is why the same command works on a laptop behind NAT and on a box behind a corporate firewall
Exeora routes tool calls; it does not store your repository. Files are read, searched and edited where they already are, and only the result of a call crosses the wire
Each project gets its own MCP endpoint, and an access token is bound to that endpoint alone. An agent connected to one project cannot reach another
Features
One outbound connection, one resource per project, rules you can tighten, and a log that records what happened without recording what was in it
Nothing listens on the machine serving a project. The CLI opens the connection and holds it, so there is nothing to expose and nothing to forward
Outbound HTTPS is the only requirement. Home routers, corporate proxies and cloud VMs with no public address all work unconfigured
Each project is its own OAuth resource under its own path. A token minted for one endpoint is refused at another, and ownership is checked in the database too
With no executor connected a call fails at once. Every call also carries an absolute deadline the executor rechecks on arrival, so a command from hours ago never runs when a sleeping laptop or a paused VM comes back
Every path is resolved through realpath before anything touches disk. A `..` or a symlink pointing outward is rejected rather than followed
A project can be read only, limited to the commands you name, or open with a deny list. Whenever a list is in force, shell metacharacters are refused unless the project turns shell on
Turning approve on asks a person before anything that edits, writes or runs. MCP 2026-07-28 clients are asked in the conversation; everyone else is asked on the terminal and in the dashboard at once
Which tool ran, how it ended, how long it took, and which client asked for it. Never the arguments, never the output
Revoking a machine closes its live socket immediately. It stops serving that instant, not whenever a token happens to expire
The relay uses the WebSocket hibernation API, so a machine that stays connected all day is not billed as compute all day
Streamable HTTP with OAuth 2.1, PKCE, dynamic client registration and RFC 9728 metadata. No plugin to install, no fork, no lock-in
Tools
The same contract is compiled into the gateway and the CLI, so what the agent is promised and what runs cannot drift apart
read_filereadsRead a text file whole, or a range of lines. Output is capped, and the reply says when it was cut so the agent knows to ask for the rest
list_filesreadsList a directory, one level or recursive, optionally filtered by a glob. Recursive walks respect .gitignore and always skip .git and node_modules
grepreadsSearch file contents with a regular expression. Returns paths with 1-based line numbers, under the same .gitignore rules
edit_filewritesReplace an exact region of a file. If the text appears more than once the edit is refused rather than guessed, and the reply is a unified diff
write_filewritesWrite a file in full, creating parent directories. Overwrites entirely, which is why edit_file is the better tool for an existing file
run_commandwritesRun a shell command in the project directory. Bounded by a wall-clock budget, killed along with everything it started, and stdin is closed so nothing hangs waiting for input
start_commandwritesStart something that outlives one call: a dev server, a watch task, a long test run. Answers at once with a handle, and the process dies with the connection so nothing is left running unwatched
get_command_outputreadsRead a running process's output from a cursor. Only the recent output is kept, and a reader that fell behind is told so rather than handed a log with a silent hole in it
send_command_inputwritesWrite to a running process's input, for one waiting on an answer
kill_commandwritesStop a running process and everything it started. Stopping one that already exited is reported, not treated as a failure
Compare
A tunnel exposes a port you then have to defend. A sandbox gives an agent a copy of your project rather than the project
What you are agreeing to
A new project allows everything until you narrow it. From the dashboard you can set it to read only, name the commands it may run, refuse specific ones in any mode, choose which tools exist, and ask to confirm every change before it happens. Paths stay confined to the project root either way, but that confinement is not a sandbox: a command that runs still runs as you, with your environment and your network.
An allow list with shell turned on is only a suggestion. Confirmation only reaches a person who is there: in the conversation on MCP 2026-07-28, and otherwise on the machine's terminal or in the dashboard. Revoking a machine from the dashboard closes its connection immediately, so that is the stop button.
The full model is in what a project allows.
FAQ
Mostly about what Exeora can see, what it cannot stop, and how to make it stop
No. The gateway routes tool calls and returns their results; it never receives a copy of your repository. What does cross the wire is whatever a tool returns, for example the lines a grep matched, and none of that is stored. The audit log records the tool name, the outcome and the duration, never arguments or output.
The connection drops and calls to that project fail immediately with LOCAL_EXECUTOR_OFFLINE. Nothing is queued, by design: every call also carries an absolute deadline that the CLI rechecks on arrival, so a command asked for hours ago cannot run when the machine wakes up.
Yes. From the dashboard you can set a project to read only, name the commands it may run, refuse specific ones in any mode, choose which tools exist, and ask to confirm every change before it happens. A project may also carry an exeora.toml that can only narrow those rules, never widen them. See what a project allows.
If the machine can make outbound HTTPS requests, yes. The CLI opens the connection outward and keeps it, so there is no inbound rule to request, no port to forward and no VPN to join.
One row per tool call: which project, which tool, whether it succeeded, the error code when it did not, how long it took, and which OAuth client asked, so you can tell Claude apart from ChatGPT. Arguments and output are never written.
Revoke the machine from the dashboard. That closes its live socket at once and stops it serving anything, rather than waiting for a token to expire. Removing a project takes its MCP URL out of service the same way.
Yes. Each machine registers separately and each project belongs to one machine, so a laptop, a build server and a Raspberry Pi can serve different projects under the same account at the same time.
Any client that speaks MCP over Streamable HTTP with OAuth 2.1. That covers Claude, ChatGPT, Cursor, VS Code, Copilot, Devin, Antigravity, Amp, Zed, Grok, Perplexity, OpenCode and others today. Dynamic client registration and CIMD are both supported, so a client that insists on either will work.
Roadmap
Named here because they are not in this release, and it is better to say so than to let a demo imply otherwise
Identity already sits behind a provider interface, and the database column is plain text. Adding one is a file and two secrets, not a migration
start_command runs a dev server or a watch task today, but it dies when the CLI disconnects. Keeping one alive across a dropped socket means deciding what happens to output nobody read, which is a different question
There are none. Nothing is metered, nothing is charged, and no limit exists beyond the rate limiting that stops a caller hammering the gateway
One command, one browser sign-in, and a URL you paste into whichever client you already use. Run it wherever the work is
Requires Node 22 or newer ยท macOS, Linux and Windows