@strivio/mcp-gateway
v0.1.3
Published
Strivio MCP Gateway — inline enforcement point. Speaks MCP toward the client and toward registered downstream servers; the Strivio cloud remains authoritative for every security decision.
Readme
Strivio MCP Gateway
An inline enforcement point for MCP tool calls. Your MCP client talks to the gateway; the gateway talks to your registered downstream MCP servers. Every tool call is decided by Strivio before it runs, and every decision leaves a Decision ID in your Strivio evidence.
Supported scope for the pilot: npm distribution, Node 24.9 or later, stdio transport, one gateway installation per machine, macOS and Linux.
Prerequisites
- Node.js 22.23.2 or later on the 22 line, or 24.9+ (
node --version). Node 23 is not supported. An unsupported version is refused at startup withUNSUPPORTED_NODE. - A Strivio account and an enrollment intent id from your Strivio admin
- macOS or Linux. Windows is not supported: the private key is protected by POSIX file permissions, which Windows does not enforce.
Install and run
The gateway is launched by your MCP client. Pin the exact version — upgrades must be deliberate; an unpinned npx could pick up a newer release on restart.
npx -y @strivio/[email protected] <command> [--config ~/.strivio/gateway.json]1. Initialise the config
npx -y @strivio/[email protected] initWrites ~/.strivio/gateway.json (mode 0600). It will not overwrite an existing file.
2. Config structure
gateway.json is bootstrap only. It says how to reach Strivio and where your
key lives. Which servers run, which tools are allowed, and which agent and policy
apply are decided by your administrator in the Strivio dashboard and fetched by
the gateway — so the two can never disagree.
{
"schemaVersion": 1,
"strivio": { "baseUrl": "https://api.strivioai.ai" },
"installation": { "keyRef": "file:~/.strivio/keys/installation.pem" },
"localEnv": {},
"limits": { "maxResponseBytes": 262144, "decisionTimeoutMs": 10000 },
"stateDir": "~/.strivio/state"
}strivio.baseUrlmust behttps.installation.keyRefis afile:reference. The key itself is never placed in this file — the gateway refuses a config containingprivateKey,key,pem, orsecretunderinstallation.installation.idis written byenroll; leave it out until then.localEnvmaps environment-variable names your administrator allowlisted to values that stay on this machine. See section 3.- A
serverskey here is refused (CONFIG_SERVERS_NOT_LOCAL). Servers are registered in the dashboard. ~is expanded by the gateway itself, so the config works whether or not your MCP client launches through a shell.
3. Servers are registered by your administrator
Your administrator registers each downstream MCP server in the Strivio dashboard under MCP Gateways → Configure, giving:
serverId— the name for it; it becomes the tool-name prefix (files__read_file).commandandargs— an argument vector. No shell: pipes, redirects and$VARare rejected.- environment-variable names the server needs, such as
FILES_TOKEN.
Secret values never go to Strivio. The dashboard stores only the name. You
supply the value on this machine, either in localEnv:
"localEnv": { "FILES_TOKEN": "…" }or in the environment the gateway is launched with. A name with no local value is logged as a warning and the variable is simply not passed.
The gateway fetches the approved configuration at startup and re-checks about once a minute, so changes your administrator makes arrive without a restart.
4. Enroll
npx -y @strivio/[email protected] enroll --intent ein_...The gateway generates an ES256 key on this machine at ~/.strivio/keys/installation.pem (0600, directory 0700), sends only the public key to Strivio, and prints:
Pairing fingerprint: 9E158-1719F-C77CA
Pairing code: ...
Waiting for admin approval...5. Admin approval
Give the pairing code to your Strivio admin. They confirm the fingerprint matches what Strivio shows them and approve. The gateway then completes activation and writes installation.id into your config.
If the admin denies, or nothing happens within 15 minutes, enroll exits with ENROLL_DENIED or ENROLL_TIMEOUT.
6. Report tools for approval
npx -y @strivio/[email protected] toolsThis launches each registered server, records what it advertises, and reports it to Strivio. Nothing is approved by running it:
demo echo UNAPPROVED
demo shell_exec UNAPPROVED
reported 9 tool(s) to Strivio (config v2). 9 awaiting approval — approve them in
the Strivio dashboard under MCP Gateways; the gateway picks approvals up automatically.Your administrator then opens MCP Gateways → Configure, sees each reported tool with its fingerprint, and approves the ones you should have. You never paste a fingerprint anywhere.
The MCP server presented to your client exposes and calls only approved tools. An unapproved tool is not listed and cannot be called; if a tool's schema later changes, its fingerprint no longer matches and it is refused until re-approved — that is deliberate, and your administrator sees it as a drift event.
tools --json prints the same list as JSON.
7. Configure your MCP client
Claude Desktop, Cursor, and similar clients take a command and arguments:
{
"mcpServers": {
"strivio": {
"command": "npx",
"args": ["-y", "@strivio/[email protected]", "serve", "--config", "~/.strivio/gateway.json"]
}
}
}Tools appear in your client as <serverId>__<toolName>, e.g. files__read_file.
8. Serve
Your MCP client runs serve for you. It speaks MCP on stdout and logs structured JSON to stderr. You can also run it directly to see the log.
Everyday commands
| Command | What it does |
|---|---|
| validate | Checks the config, the server registry, and that the key loads with correct permissions |
| health | Loads the key and confirms Strivio is reachable |
| version | Prints the installed version |
| tools | Discovers downstream tools and their fingerprints |
Restart behaviour
Restarting the gateway — or your MCP client — needs nothing from you. The same key and installation id are reused. A Strivio backend restart does not require re-enrollment. The gateway fails closed while Strivio security services are unavailable and resumes when readiness recovers.
On every start, before serving any call, the gateway recovers from its state directory:
- Pending prepared outcomes are resent exactly as prepared — same identity, unchanged body. Strivio accepts a repeated delivery idempotently.
- A call interrupted by a crash after the gateway crossed the downstream execution boundary, but before a durable outcome existed, is reported to Strivio as unknown, with the reason
GATEWAY_RECOVERED_AFTER_BOUNDARY. It means execution certainty was lost: the tool may or may not have run. Unknown does not mean failed. - Recovery never executes a downstream tool again. It only reports what the durable record shows.
State directory
stateDir (default ~/.strivio/state) contains execution identifiers, lifecycle metadata, durable outcome metadata, and advisory progress state: <attempt>.json durable records and <attempt>.progress.json progress files. It does not persist raw tool arguments or raw tool responses.
- Do not edit these files by hand.
- Run one gateway process per state directory.
- A lock left behind by a crashed gateway is reclaimed automatically by the next gateway process that writes to the state directory.
Performance
For an executed tool call, the protected path includes a Strivio decision before execution and response-safety inspection before release; outcome delivery continues in the background after durable local preparation. In the current pilot environment, single-caller measurements were approximately 330 ms p50 / 567 ms p95 of gateway end-to-end latency. At 10 concurrent calls through one gateway on the current Flex-backed environment, measured throughput was approximately 7.3 calls/s with about 1.3 s p50.
These are measured pilot results, not service-level commitments. Actual latency varies with network, Strivio infrastructure, downstream tool behaviour, and concurrency.
Key location and security
| | |
|---|---|
| Location | ~/.strivio/keys/installation.pem |
| Permissions | file 0600, directory 0700 — the gateway refuses to load a key readable by others |
| Leaves the machine? | Never. Only the public key is sent, once, during enrollment |
| Logged? | Never. Enrollment output contains the fingerprint, not the key |
| Lost key | Re-enroll with a new intent. The old installation should be revoked by your admin |
This protects the key from other users on the same host. It does not protect against a compromised account, a root user, or an unencrypted disk.
Troubleshooting
| Error | Meaning | Fix |
|---|---|---|
| CONFIG_SCHEMA_VERSION | config is not schemaVersion: 1 | set it to 1 |
| CONFIG_BASE_URL_INSECURE | baseUrl is plain http to a remote host | use https |
| CONFIG_KEY_INLINE | a key was pasted into the config | remove it; use keyRef |
| KEY_NOT_FOUND | not yet enrolled | run enroll --intent |
| KEY_PERMISSIONS | key file is readable by others | chmod 600 ~/.strivio/keys/installation.pem |
| KEY_PLATFORM_UNSUPPORTED | Windows | not supported in the pilot |
| NOT_ENROLLED | serve/health before enroll | run enroll --intent |
| ENROLL_EXPIRED | this enrollment attempt is no longer valid | ask your admin for a fresh intent |
| CONFIG_INVALID (seen by your admin) | a registered command or args entry contains shell syntax | your admin re-enters it as a plain argument vector — no pipes, redirects or $VAR |
| SERVER_COMMAND_UNSAFE | the gateway refused a synced command containing shell syntax | your admin corrects it in the dashboard |
| SERVER_COMMAND_REQUIRED | a registered server has no command | your admin sets one |
| Tool not listed in the client | fingerprint not approved | run tools, approve it |
| Tool blocked by Strivio policy | a decision refused it | check the Decision ID in your Strivio evidence |
| CLOUD_SECURITY_STATE_UNAVAILABLE | Strivio's security state is unavailable | the gateway fails closed; retry shortly |
| CONFIG_SERVERS_NOT_LOCAL | a servers key is in gateway.json | remove it; servers are registered in the dashboard |
| CONFIG_SYNC_FAILED … GATEWAY_CAPABILITY_INSUFFICIENT | this installation predates configuration sync | ask your admin for a new intent and re-enroll |
| CONFIG_SYNC_FAILED … GATEWAY_TOKEN_DENIED | Strivio refused a token for this installation | it was revoked, or the key no longer matches — ask your admin, who can see the exact reason |
| CONFIG_SYNC_FAILED (other) | the approved configuration could not be fetched | the gateway serves nothing rather than use stale local config; check health |
| KEY_EXISTS | a key already exists on this machine — from a completed enrollment, or placed manually. A failed enroll removes the key it created, so a failure does not leave one behind | this machine may already be enrolled: check health. To re-enroll, revoke the old installation in the dashboard, remove ~/.strivio/keys/installation.pem, then run enroll with a new intent |
| No tools listed, tools reports 0 | no server is registered for this installation | your admin registers it in the dashboard first |
| A tool disappeared from your client | its approval was revoked, or its schema changed | ask your admin; both are visible to them |
| Client shows "Executed · Response withheld: it did not pass Strivio response-safety inspection." | The downstream tool may already have executed. Strivio withheld only the returned content, because it contained instructions aimed at the AI model | check the downstream server's output; your admin sees a RESPONSE_WITHHELD event naming the category |
| Client shows "Executed · Response withheld — inspection unavailable" | the tool executed, but Strivio could not inspect its response, so it was not released | fails closed; retry shortly — execution is still recorded |
| Client shows "Executed · Response withheld by Strivio."; gateway log says outcome could not be durably prepared | the gateway could not write its state directory, so it will not return a result without durable evidence | check free disk space and permissions on stateDir |
| COORDINATION_WRITER_LOCKED | another gateway process is using the same state directory | run one gateway per state directory; a lock left by a crashed process is reclaimed automatically |
| CONFIG_NOT_FOUND | no gateway config exists at the path shown — usually init has not been run on this machine | run the init command printed with the error, then retry |
| UNSUPPORTED_NODE | this Node.js version is outside the supported range | install Node 22.23.2+ on the 22 line, or 24.9+ (Node 24 LTS recommended). Under Claude Desktop the Node that counts is the first one on its PATH (an nvm default of 20 triggers this); the gateway exits rather than run on it, and Claude Desktop retries with its built-in Node when "Use built-in Node.js for MCP" is enabled. The refusal is recorded in ~/Library/Logs/Claude/mcp-server-<name>.log. |
When something upstream fails
| What fails | What the gateway does |
|---|---|
| Strivio backend unreachable | Every tool call is refused. No call reaches your downstream server. |
| Strivio security state unavailable | Same — refused, fail closed, resumes automatically when it recovers |
| Strivio slow or wedged | A call is refused after the decision timeout rather than hanging |
| A downstream server won't start | Only that server's tools are unavailable; others are unaffected |
| A downstream server crashes mid-call | The call fails; the gateway reports the outcome to Strivio and continues |
| The gateway itself crashes after starting a tool call | On the next start the attempt is reported to Strivio as unknown (GATEWAY_RECOVERED_AFTER_BOUNDARY). The tool is never re-executed |
| Strivio cannot inspect a tool's response | The response is withheld; the tool is still recorded as executed |
| Configuration sync fails while running | The last approved configuration stays in force. Strivio still authorizes every call, so a stale gateway can expose a tool but never get it approved |
The gateway never "fails open". If it cannot get a decision, the call does not happen.
Upgrading
npx -y @strivio/mcp-gateway@<new-version> serve --config ~/.strivio/gateway.jsonYour MCP client config pins a version deliberately, so upgrades are a decision you make. Update the version there and restart your client. Your key, installation and approved configuration are unaffected — no re-enrollment, no re-approval.
One exception: an installation enrolled before configuration sync existed does not
hold the mcp:config-sync capability and will refuse to start after upgrading. The
error says so. Ask your administrator for a new intent and re-enroll.
If your installation is revoked
Your administrator can revoke an installation at any time. When they do:
- the gateway can no longer obtain a token, so no tool call succeeds;
healthreports the failure rather than claiming the local key is fine;- nothing on your machine is deleted — the key stays where it is, unusable.
To come back, ask for a new enrollment intent. Remove the old key first
(rm ~/.strivio/keys/installation.pem), since the gateway refuses to overwrite it.
Deferred (not in the pilot)
Docker image, standalone binary, automatic upgrades, key rotation, multiple installations per config, remote (non-stdio) MCP transports, Windows.
License
Source-available under the PolyForm Shield License 1.0.0 — see LICENSE.
In plain terms: you may use, modify and redistribute this gateway for any purpose except providing a product that competes with it or with the Strivio products it connects to. Ordinary use — installing it, running it, changing it for your own needs, even redistributing it — is permitted. Building a competing AI-agent security product on it is not.
This is not an OSI open-source license, and it is not a closed proprietary one either. The source ships in the package and you are free to read it.
