elsewhere
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., "@elsewhereOpen a session from Singapore to fetch the region-restricted page."
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.
elsewhere
When your agent can't reach something, it moves instead of stopping.
Give a coding agent its own network location — somewhere else to work from, for one request at a time, without touching your machine's connection.
Without elsewhere
agent: I can't reach that endpoint from here. Could you connect to a VPN and re-run?
→ task stops, waits for you
With elsewhere
agent: not reachable from here — opening a session and retrying
session 4f2a91c3 · egress 203.0.113.44 (Singapore) · verified
→ HTTP 200 · continuingAn MCP server plus a CLI. Works with Claude Code, Cursor, and any MCP client.
What it solves is where you are, not whether you're allowed. It won't defeat a login, a rate limit, bot detection or a paywall, and it doesn't try. If a service publishes something to the public but only answers requests from inside a country, your agent can now read it. That's the whole claim.
The one design rule
It routes the request, not the process.
There is no host route change, no exported HTTPS_PROXY, no system VPN state. A session is a proxy URL and the resources behind it. Traffic goes through it only when something is deliberately pointed at it.
For agents this is the whole ballgame. Put the process behind a tunnel and the agent's own control-plane traffic goes too — model API calls, telemetry, package installs. That is slow, it trips abuse heuristics, and it makes every failure impossible to attribute. elsewhere moves one request at a time and leaves everything else alone.
It also means the agent can hold sessions in several places at once, and reach each one independently, without any of them interfering.
Related MCP server: Agent SSH MCP
Why not just change your VPN
Because a VPN client is a global switch, and an agent needs a local one:
VPN client |
| |
Scope | Whole machine | One request |
Your IP | Moves | Unchanged |
Concurrent locations | One | Many |
Agent's API traffic | Through the tunnel | Untouched |
Unattended | No | Yes |
Verified | You hope | Checked, fails closed |
What your agent gains
Without | With |
Stops and asks you to change your VPN | Opens a session and carries on |
One location at a time, whole machine | Several at once, per request |
"I couldn't reach it" | "Unreachable from here, reachable from Singapore" |
Believes whatever a proxy returns | Refuses a session it can't verify |
Leaves a tunnel up when it forgets | Sessions expire on their own |
What makes a session trustworthy
An agent will believe whatever the tool tells it, and act on it for the rest of the task. So a session is verified before you're allowed to use it, and re-verified while you hold it:
Egress is observed, not assumed. The session reports the IP and country traffic actually came out of, over HTTPS only — a plaintext check could be forged by the very party carrying the traffic.
Leak detection fails closed. If a session's egress IP equals your host's, the tunnel isn't carrying traffic — you get an error, not a session. A silently-failed proxy is otherwise indistinguishable from a working one, and the agent records a confident conclusion drawn from the wrong place.
Location assertion. Set
expectCountryand a provider that quietly lands you somewhere adjacent is caught rather than trusted.Re-verified in use. Tunnels reconnect on their own, sometimes elsewhere. A session that moved is closed with a warning that earlier results may be misattributed — not silently relabelled.
Stale URLs fail loudly. Every session carries its own credentials, so a proxy URL an agent cached from an earlier session cannot quietly start exiting somewhere else.
Everything expires. Sessions self-destruct on a TTL. Agents forget to clean up, and a tunnel that outlives its task is both a cost leak and a correctness hazard.
A block page is not a response. Firewalls routinely refuse a request with
HTTP 200and a short "Request Rejected" body. Those are detected and labelled as blocks, and — because they embed a random incident id — every refusal from one appliance compares equal, so two identical rejections can never be reported as a regional difference.
elsewhere identifies itself honestly (elsewhere/0.1 (+repo url)) rather than impersonating a browser. That is a corrected decision: a Chrome user-agent arriving with a non-browser TLS fingerprint is more likely to be refused, because the firewall checks the two for consistency. An honest agent string got served the full page where a spoofed one was rejected.
Bring your own exit
elsewhere is a router, not a VPN. It has no network of its own and never will. It drives whatever you already have:
Adapter | Backend | Needs |
| Any gluetun-supported VPN provider | Docker + your subscription |
| Any box you own, via | An SSH host. No VPN, no Docker, no root. |
| Datacenter/residential proxies, corporate proxies | A proxy URL |
Provider-agnostic is the point. A VPN vendor's own tooling drives that vendor and flips your entire machine. This drives all of them, scoped, and verifies the result.
Install
npm install && npm run build
cp .env.example .env # credentials
cp elsewhere.config.example.json elsewhere.config.json # regionsRequires Node ≥22.19. Edit .env with your provider's credentials, then define the regions you want in elsewhere.config.json. Config references secrets as ${VAR} so it stays committable — .env and elsewhere.config.json are both gitignored.
Then refresh your provider's server catalogue before your first session:
node dist/cli.js update-servers <provider> # takes a few minutes, once
node dist/cli.js check # confirms it workedThis is not optional housekeeping. Providers rotate their fleets, and the catalogue baked into the gluetun image goes stale — the failure it causes is a tunnel that starts, binds its proxy, and then hangs against addresses that were retired months ago. Nothing about that points at the server list, so it is worth five minutes up front.
Use it from an agent
Add to your MCP client (.mcp.json, Claude Code, Cursor, …):
{
"mcpServers": {
"elsewhere": {
"command": "node",
"args": ["/absolute/path/to/elsewhere/dist/mcp.js"]
}
}
}Seven tools: elsewhere_regions, elsewhere_open, elsewhere_fetch, elsewhere_compare, elsewhere_status, elsewhere_close, elsewhere_host_egress.
A typical agent flow is: discover regions → open one → fetch → close. Or skip straight to elsewhere_fetch with a region id and it handles the session for you.
Note that elsewhere open on the CLI blocks by design — it holds the tunnel until interrupted. For one-shot requests use fetch; for scripted use, background it. fetch prints the response body to stdout so it can be piped.
Anything that speaks HTTP proxy can use a session directly:
curl -x "$PROXY_URL" https://example.comawait chromium.launch({ proxy: { server: proxyUrl } });CLI
elsewhere check # what does this machine look like right now?
elsewhere regions # what's configured?
elsewhere fetch <region> <url> # open, fetch, tear down
elsewhere open <region> # hold a session (blocks until Ctrl-C)
elsewhere compare <url> # fetch from every region and diff the results
# --save-bodies <dir> to inspect what differed
elsewhere servers <provider> <term> # exact location names a provider offers
elsewhere update-servers <provider> # refresh the provider server catalogue
elsewhere reap # clean up containers left by a crashcompare — one request, every location, diffed
$ elsewhere compare https://example.com/pricing
host HTTP 200 14204B 291ms
sg HTTP 200 14891B 843ms 203.0.113.44 (Singapore)
br UNREACHABLE (connect timeout) 0B 30001ms
de HTTP 200 14204B 412ms 198.51.100.9 (Frankfurt)
3 distinct responses:
· reachability — host+sg+de: HTTP 200 | br: failed (connect timeout)
· currencies — host+de: EUR | sg: SGDTwo details that make it useful rather than noisy:
Your untunnelled connection is a control row. Without one you cannot tell "blocked from there" from "broken for everyone" — the most common misdiagnosis in this kind of work.
Bodies are normalised before hashing (nonces, UUIDs, timestamps stripped). Without that, no two responses from a modern site ever compare equal and every report says "everything differs".
Troubleshooting
If a tunnel hangs, refresh the server list first:
elsewhere update-servers <provider>Providers rotate their fleets, and the catalogue baked into the gluetun image goes stale. The resulting failure is genuinely misleading: the tunnel starts, the proxy binds, and connections then hang against addresses the provider retired months ago. Nothing in that sequence points at the server list.
Related: location names must match the provider's catalogue exactly. An unrecognised value is a silent fallback, not an error — you end up in a perfectly working tunnel in the wrong place. elsewhere servers <provider> <term> prints the exact strings.
Security
Every session's proxy carries its own random credentials, embedded in the URL it hands you. That is not primarily about keeping local processes out — it is so a stale proxy URL fails loudly. Ports get reused, so a URL captured from an earlier session, cached by an agent or written into a config, would otherwise keep working while exiting somewhere else entirely, with nothing reporting an error. Now it gets a 401/407.
The proxy is still not a hard authorisation boundary — the credential lives in a URL the agent and your terminal can both see. Treat it as you would any local development proxy.
Private, loopback, link-local and cloud-metadata destinations are denied by default and re-checked on every redirect hop. Assume the agent driving this will be prompt-injected by a page it fetches; a tunnel grants reachability it did not otherwise have, and with the ssh adapter that includes the exit host's entire internal network. Override deliberately with ELSEWHERE_ALLOW_PRIVATE=1.
To report a vulnerability, see SECURITY.md.
Scope and intent
This exists so that developers and their agents can reach things they are entitled to reach, and check how their own applications behave for users elsewhere.
It is deliberately not a circumvention product: it ships no proxy network, no bundled exit nodes, and no evasion features. You supply your own egress, and you are responsible for your provider's terms and the terms of the services you access. Automated traffic over consumer VPN subscriptions breaches some providers' terms — check yours. Residential proxy networks raise real consent questions about whose connections you are borrowing.
CONTRIBUTING.md lists what is out of scope, as settled decisions rather than open questions.
Status
Early, but proven end-to-end. The origin case was an agent that could not reach a service gated to one country: an agent opened a session over MCP, fetched the record, and tore the session down — with the host connection unchanged throughout.
Working: session lifecycle, all three adapters, leak and location verification, re-verification in use, destination policy, compare, server-list refresh, CLI, MCP server.
The codebase has been through two independent adversarial audits and a live fault-injection pass — credential exposure, traffic leaks, lifecycle, concurrency. Findings are fixed; the git history describes each one and why it mattered. The ssh adapter is covered by tests but has not yet been run against a real SSH host.
Contributing
Provider recipes are the most valuable contribution — every user brings a different exit, and that is where nearly all the friction lives. Please read CONTRIBUTING.md first.
Licence
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
- FlicenseNot gradedqualityCmaintenanceA local MCP server that provides controlled repository access with policy-based file filtering, secret redaction, and audit logging for AI coding agents.
- AlicenseNot gradedqualityBmaintenanceMCP server for persistent SSH sessions with tmux integration, port forwarding, and SFTP file writes, built for AI agent workflows.MIT
- AlicenseAqualityCmaintenanceStateful outbound TCP/UDP MCP server enabling LLMs to perform multi-step network protocols like HTTP/1.x, SMTP, Redis, and DNS.10MIT
- AlicenseAqualityAmaintenanceMCP server that enables a coordinator AI agent to spawn, control, and supervise local coding agents with interactive gating for high-risk operations.10241MIT
Related MCP Connectors
MCP server for AI agents to plan, verify, and deploy Cloudflare-native apps.
An MCP server for Arcjet - the runtime security platform that ships with your AI code.
MCP server for secureFlows: token-free URL builders and integration-linting tools for AI agents.
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/noelbraganza/elsewhere'
If you have feedback or need assistance with the MCP directory API, please join our Discord server