Networks and proxies
You set your machine’s proxy and its trusted certificates once for each tool, through that tool’s standard mechanism. CORA honors what you set for the requests its own code makes. The other tools it runs, such as npm, git and Chrome, follow their own settings, as What CORA connects to shows.
Proxies
Section titled “Proxies”cora and cora-mcp reach the CORA service through the proxy the environment names, as most command-line tools do:
HTTPS_PROXYnames the proxy, as anhttp://orhttps://URL, such ashttp://proxy.example.com:8080.HTTP_PROXYnames it whenHTTPS_PROXYis unset.NO_PROXYlists the hosts to reach without the proxy, separated by commas or spaces.
The service is on HTTPS, so each request reaches it through the proxy’s CONNECT tunnel. Set the variable in the shell that runs cora:
export HTTPS_PROXY=http://proxy.example.com:8080npx cora auth login$env:HTTPS_PROXY = "http://proxy.example.com:8080"npx cora auth loginTo keep it for every shell, set it in your shell’s profile, or in your Windows user environment variables. The environment variable reference lists each variable under the network kind. These rules apply to all three:
- Each variable is also read in lower case, such as
https_proxy. Outside Windows, the lower-case one wins when both are set. On Windows, variable names ignore case, so the two are one variable. - An empty variable counts as unset.
- A
NO_PROXYentry covers its host and the host’s subdomains, with or without a leading.or*.. Sovispero.comcoverscora.vispero.com. - A
NO_PROXYentry with a port, such ascora.vispero.com:443, covers that port alone.NO_PROXY=*covers every host. - A proxy that asks for credentials takes them in its URL, percent-encoded, such as
http://user:p%40ss@proxy.example.com:8080.coraand cora-mcp replace the credentials in any URL they write withREDACTED. - A value that is not an
http://orhttps://URL without a path fails withconfig.invalid-environment, such asproxy.example.com:8080without its scheme. The error names the variable, never its value.
Request timeout
Section titled “Request timeout”Each request to the service, its answer included, must finish within service.requestTimeout. A request that takes longer fails with service.unreachable, and its message names the setting and its value.
On a network whose proxy or VPN is slow, raise it in your user config, in milliseconds:
{ "service": { "requestTimeout": 60000 } }For one run, set CORA_SERVICE_REQUEST_TIMEOUT instead. The setting’s reference entry gives its default.
Trusted certificates
Section titled “Trusted certificates”cora and cora-mcp trust the operating system’s certificate store, as well as Node.js’s own root certificates. That covers the common case of a TLS-inspecting proxy, such as Cloudflare WARP, Zscaler or Netskope. Such a proxy opens each HTTPS connection and signs it again with a root certificate your organization installs in the store. Once the root is there, requests to the service work with nothing to set.
They read the store where the operating system keeps it:
| Platform | Store |
|---|---|
| Windows | The trusted root certificates of the machine’s and your user’s certificate stores |
| macOS | The certificates the default and system keychains trust for SSL |
| Linux | OpenSSL’s certificate file and directory, such as /etc/ssl/certs, or those SSL_CERT_FILE and SSL_CERT_DIR name |
Where the root is not in the store, save it as a PEM file, and name the file in NODE_EXTRA_CA_CERTS. Node.js reads the variable as it starts, so set it before you start cora, or the coding agent that starts cora-mcp:
export NODE_EXTRA_CA_CERTS=/path/to/proxy-root.pemnpx cora auth login$env:NODE_EXTRA_CA_CERTS = "C:\path\to\proxy-root.pem"npx cora auth loginCoding agents
Section titled “Coding agents”A coding agent starts cora-mcp, and decides which of its environment variables cora-mcp gets. The two agents differ:
- Codex starts a server with only a few of its own variables, such as
PATHandHOME. It passes each other one only when the entry names it inenv_vars. - Claude Code sets the variables an entry’s
envnames. Its docs do not say whether a server also gets the rest of Claude Code’s environment. The project agent’s server does: it starts with the environment Claude Code runs in.
CORA’s plugin names these in both agents’ entries, each taken from the environment the agent runs in:
- the proxy variables, in upper and lower case;
NODE_EXTRA_CA_CERTS;NODE_TLS_REJECT_UNAUTHORIZED.
Set them where the agent starts, such as the shell you start claude or codex from.
The plugin’s entries do not name the following. Under Codex, they never reach the plugin’s cora-mcp. Under Claude Code, they reach it only if Claude Code passes its whole environment on.
SSL_CERT_FILEandSSL_CERT_DIR. Claude Code’s entry gives each variable it names an empty value when it is unset, and on Linux Node.js reads an empty one as a store with no roots. So where a root is only in a file they name, name that file inNODE_EXTRA_CA_CERTStoo, which reaches cora-mcp under both agents.CORA_SERVICE_REQUEST_TIMEOUT. Setservice.requestTimeoutin your user config, which every cora-mcp reads.
An entry you write yourself passes on what you name in it:
Set each variable in the entry’s env, so it reaches cora-mcp whether or not Claude Code passes its whole environment on. Give it only a variable you set: an empty SSL_CERT_FILE or SSL_CERT_DIR empties the store on Linux.
{ "mcpServers": { "cora": { "type": "stdio", "command": "npx", "args": [ "--yes", "--prefer-offline=false", "--fetch-retries=0", "--fetch-timeout=3000", "@vispero/cora-mcp@<version>" ], "env": { "NODE_EXTRA_CA_CERTS": "/path/to/proxy-root.pem" } } }}Codex starts a server with only a few of its own variables, such as PATH and HOME. Name each one cora-mcp needs in the entry’s env_vars, as Codex shows. On Linux, add SSL_CERT_FILE and SSL_CERT_DIR when you set them.
[mcp_servers.cora]command = "npx"args = [ "--yes", "--prefer-offline=false", "--fetch-retries=0", "--fetch-timeout=3000", "@vispero/cora-mcp@<version>"]env_vars = ["HTTPS_PROXY", "https_proxy", "NO_PROXY", "no_proxy", "NODE_EXTRA_CA_CERTS"]npm’s registry
Section titled “npm’s registry”Each start of cora-mcp from the plugin’s entry, or from an entry like it that runs npx, asks npm’s registry for the release and its dependencies, even where your npm config sets prefer-offline, so a release newer than the versions npm has cached still starts. When the registry refuses the connection, or sends nothing for 3 seconds once connected, npx starts the release from npm’s cache, so a release that ran before starts without the network. npm’s offline setting still applies: with it, npx asks no registry, and starts only a release npm has cached.
The first start of a release npm hasn’t cached, such as after the plugin updates, gives up after those 3 seconds too. A registry mirror that fetches a package it lacks before it answers can take longer, and the start then fails, with ETARGET when it is cora-mcp’s version list that took longer. To get past it, fetch the release with npm’s own wait, then restart the server from your agent:
npx --yes --prefer-offline=false @vispero/cora-mcp@<version> --versionFor a project’s first setup, cora init does this for the coding agents it sets up: its fetch waits 30 seconds for each answer, and leaves the project’s release cached for the agent’s start.
The connection counts as open once its TLS handshake completes and, through a proxy, once the proxy’s tunnel is open. Until then npm’s 3 seconds haven’t started, so a connection that never opens holds the start:
- A proxy or registry whose network drops the connection, such as a corporate proxy while you’re off its VPN, holds it until the operating system gives up: about 20 seconds on Windows, over a minute on macOS, and over two minutes on Linux.
- One that takes the connection and never completes the handshake or the tunnel holds it with no end.
Such a start can outlast your agent’s startup timeout, and the agent then shows CORA’s server as failed. A connection that is refused, or a host name your DNS server says doesn’t exist, falls back to the cache at once. For the registry, npm takes its proxy from its own https-proxy or proxy setting, or else from HTTPS_PROXY or https_proxy, so the variable you set for cora reaches it too.
cora mcp and cora init ask no registry for a release npm has cached, so on such a network only a release npm hasn’t cached holds them: cora mcp until the connection fails or your agent’s startup timeout passes, and cora init for up to 10 minutes, after which it goes on without it.
On such a network, turn on npm’s offline, so npx starts the release from its cache without asking the registry:
npm config set offline trueOnce you’re on a network that reaches the registry again, turn it off:
npm config delete offlineoffline is in your user .npmrc, so it applies to every npm command on the machine: while it’s on, an npm install that needs a package npm hasn’t cached fails, and npx starts only a release npm has cached. The first start of a release it hasn’t, such as after the plugin updates, fails within seconds: with ETARGET where npm’s list of cora-mcp’s versions predates the release, and otherwise with ENOTCACHED.
Where it’s a proxy that can’t be reached, you can instead remove it from npm’s settings, and remove HTTPS_PROXY and https_proxy from the agent’s environment.
Checking your setup
Section titled “Checking your setup”npx cora info shows what cora reads in the shell it runs in:
- Its Service section gives the service’s address and its request timeout, with their values.
- Its Environment section lists each variable on this page that is set, never with its value, then the names of those that are not, after
Unset:.
It reads its own shell, not what an agent passed to cora-mcp.
When a request fails, service.unreachable says what failed, with the network error’s code, such as the connection to 127.0.0.1:8080 was refused (`ECONNREFUSED`) for a proxy that is not running, or gives the timeout it reached. For a certificate the machine does not trust, its message says so and gives the TLS error’s code, and its hint names the fixes:
error[service.unreachable]: Could not reach https://cora.vispero.com: this machine does not trust the certificate it presented (`SELF_SIGNED_CERT_IN_CHAIN`)hint: A TLS-inspecting proxy may sign this network's connections: install its root certificate in the operating system's store, or name a PEM file that holds it in `NODE_EXTRA_CA_CERTS`, then run the command again.What CORA connects to
Section titled “What CORA connects to”CORA’s own requests go only to the CORA service. Each other host is reached by another tool, which reads its own settings:
- The CORA service,
https://cora.vispero.com, for signing in, renewing a signed-in token, and fetching the service’s current signing keys: see What CORA sends to the service. CORA’s settings apply, as this page sets them. - npm’s registry, when
npxstarts cora-mcp for a coding agent, and whencora init,cora mcpand cora-mcp’s version alignment fetch a cora-mcp release. npm reads its own settings for it, such ashttps-proxy,noproxyandcafile, and where they’re unset,HTTPS_PROXYandNO_PROXY, as npm’s registry says. - GitHub, when Claude Code and Codex clone CORA’s plugin marketplace,
Vispero/cora-plugins, with git. git’s settings apply, such ashttp.proxyandhttp.sslCAInfoin git config. - Your app, which Chrome loads for each page
cora scanscans or an agent opens in cora-mcp’s browser. Chrome’s own settings apply: CORA gives Chrome no proxy.
cora scan also asks the config’s server.url whether your app’s server is ready, through no proxy. cora auth login opens its sign-in page in your browser where it can, and the browser follows its own settings.