Nothing to expose, nothing to forward

Secure execution for AI agents,
on any machine

Connect any MCP client to the development environment on any machine you can run a command on: a server, a VM, a build box, a Raspberry Pi, or your own laptop. No port to open, no source code to upload, no tunnel to wire up.

npx @exeora/cli connect

Run it in the directory you want to serve. It signs you in and registers the machine on the way

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

Three facts that explain the whole design

No inbound network path, no copy of your code, and no shared blast radius between projects

  1. 1

    The CLI dials out. Nothing dials in

    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

  2. 2

    Your code never leaves the machine

    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

  3. 3

    One URL per project

    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

Built so the dangerous parts are small

One outbound connection, one resource per project, rules you can tighten, and a log that records what happened without recording what was in it

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

Behind NAT and firewalls

Outbound HTTPS is the only requirement. Home routers, corporate proxies and cloud VMs with no public address all work unconfigured

A token per project

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

Nothing is queued

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

Paths stay in the project

Every path is resolved through realpath before anything touches disk. A `..` or a symlink pointing outward is rejected rather than followed

Modes and command rules

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

Confirm before it runs

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

An audit log you can show someone

Which tool ran, how it ended, how long it took, and which client asked for it. Never the arguments, never the output

Revoke and it stops

Revoking a machine closes its live socket immediately. It stops serving that instant, not whenever a token happens to expire

Idle costs nothing

The relay uses the WebSocket hibernation API, so a machine that stays connected all day is not billed as compute all day

Bring your own client

Streamable HTTP with OAuth 2.1, PKCE, dynamic client registration and RFC 9728 metadata. No plugin to install, no fork, no lock-in

Tools

Ten tools, one project directory

The same contract is compiled into the gateway and the CLI, so what the agent is promised and what runs cannot drift apart

read_filereads

Read 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_filesreads

List a directory, one level or recursive, optionally filtered by a glob. Recursive walks respect .gitignore and always skip .git and node_modules

grepreads

Search file contents with a regular expression. Returns paths with 1-based line numbers, under the same .gitignore rules

edit_filewrites

Replace 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_filewrites

Write a file in full, creating parent directories. Overwrites entirely, which is why edit_file is the better tool for an existing file

run_commandwrites

Run 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_commandwrites

Start 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_outputreads

Read 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_inputwrites

Write to a running process's input, for one waiting on an answer

kill_commandwrites

Stop a running process and everything it started. Stopping one that already exited is reported, not treated as a failure

Compare

Neither a tunnel nor a sandbox

A tunnel exposes a port you then have to defend. A sandbox gives an agent a copy of your project rather than the project

Where your code lives

Exeora
The machine you ran it on
ngrok, Cloudflare Tunnel
The machine you ran it on
Cloud sandbox
A copy on their infrastructure

Inbound port

Exeora
None
ngrok, Cloudflare Tunnel
None, but the tunnel publishes a public URL
Cloud sandbox
None

What is reachable

Exeora
Ten tools, one project directory
ngrok, Cloudflare Tunnel
Whatever is listening on that port
Cloud sandbox
A full shell in the copy

Per-project isolation

Exeora
A separate OAuth resource and token
ngrok, Cloudflare Tunnel
You build it
Cloud sandbox
One sandbox per project

Authentication

Exeora
OAuth 2.1, built in
ngrok, Cloudflare Tunnel
Whatever your service does, often nothing
Cloud sandbox
The vendor's account

Your real toolchain and state

Exeora
Yes
ngrok, Cloudflare Tunnel
Yes
Cloud sandbox
Reinstalled, and never quite the same

Setup

Exeora
Install, log in, add a project
ngrok, Cloudflare Tunnel
Run the tunnel, then secure it yourself
Cloud sandbox
Push your code

What you are agreeing to

An agent you connect can run anything inside that project

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

The questions worth asking first

Mostly about what Exeora can see, what it cannot stop, and how to make it stop

Can you see my code?

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.

What happens when the machine goes away?

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.

Can I limit which commands run?

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.

Does this work behind a corporate firewall?

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.

What does the audit log actually contain?

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.

How do I revoke access?

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.

Can I connect more than one machine?

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.

Which clients does it work with?

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

What comes next

Named here because they are not in this release, and it is better to say so than to let a demo imply otherwise

Sign in with Google

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

Processes that outlive the connection

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

Billing and plans

There are none. Nothing is metered, nothing is charged, and no limit exists beyond the rate limiting that stops a caller hammering the gateway

Point an agent at a machine

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