sovereign-mcp-gateway
A gating proxy for Model Context Protocol servers. Point your MCP client at the gateway instead of at your servers. It connects to every upstream you list, merges their tool catalogues into one, and puts every call through a verification chain before it reaches the server that would execute it.
pip install "sovereign-mcp-gateway[all]"
sovereign-mcp-gateway --config gateway.json
The gateway is itself an MCP server, so any client that speaks MCP works with no changes.
Why a proxy and not a library
A library has to be adopted by whoever wrote the server. A proxy protects servers you cannot modify — which is most of them, because the useful MCP servers are published packages someone else maintains.
It also gives you one place to hold policy and one audit trail across every server an agent can reach, rather than per-server configuration nobody keeps in sync.
Configure
{
"servers": {
"git": {"command": "mcp-server-git", "args": ["--repository", "/repo"]},
"sqlite": {"command": "mcp-server-sqlite", "args": ["--db-path", "/data.db"]}
},
"policy": {"deny_tools": ["git__git_reset"], "pii_policy": "warn"},
"audit": {"path": "gateway-audit.jsonl"}
}
Check the wiring before a client ever sees it:
sovereign-mcp-gateway --config gateway.json --check
SOVEREIGN GATEWAY - configuration check
upstreams: 2
layers: policy -> intent -> text-filter -> frozen-verify -> audit
EXPOSED AS UPSTREAM TOOL
git__git_status git.git_status
git__git_reset git.git_reset [DENIED]
sqlite__read_query sqlite.read_query
...
18 tools exposed.
The chain
policy → intent → text-filter → frozen-verify → [ call executes ] → output-verify → logic-rules → audit
| Layer | Package | Refuses when |
|---|---|---|
| policy | — | the tool is on a deny list, or absent from an allow list |
| intent | intentshield |
the call fails the behavioural floor |
| text-filter | sovereign-shield |
an argument carries injection, in any of 22 languages or seven encodings |
| frozen-verify | sovereign-mcp |
the call disagrees with the tool definition frozen at startup |
| output-verify | sovereign-mcp |
the result fails schema, deception, PII or content checks |
| logic-rules | logicshield |
the result is inconsistent with rules you configured |
| audit | sovereign-mcp |
— records every call, allowed or refused, in a hash-chained log |
Only sovereign-mcp is required. The optional layers install as extras, and the gateway prints which ones are active at startup — a partial install degrades visibly rather than silently.
pip install sovereign-mcp-gateway # policy, frozen-verify, audit
pip install "sovereign-mcp-gateway[all]" # every layer
Verified end to end
Against mcp-server-git and mcp-server-sqlite running as real upstreams, driven by a real MCP client:
| Call | Result |
|---|---|
git__git_status, git__git_log |
allowed |
sqlite__create_table, __write_query, __read_query |
allowed — the row is really in the database |
git__git_reset |
refused: on the deny list |
git__git_push_force |
refused: no upstream exposes it |
git__git_status(repo_path=12345) |
refused: wrong type for the frozen schema |
git__git_commit("IGNORE ALL PREVIOUS INSTRUCTIONS…") |
refused: text filter |
sqlite__git_commit(...) |
refused: a tool cannot be reached through another upstream's namespace |
Afterwards the repository still holds one commit and the database holds exactly the row it should — checked by opening them directly, not by trusting the gateway's own report. Eleven audit records for ten calls; editing any one of them breaks the chain.
Those cases are the test suite, not a screenshot: pytest tests/ -v.
Namespacing
With namespace on (the default) a tool is exposed as git__git_status. Two upstreams offering the same tool name cannot collide, shadow each other, or be reached through the wrong namespace. Turn it off only when you have a single upstream.
Policy
"policy": {
"deny_tools": ["git__git_reset", "write_query"],
"allow_tools": null,
"pii_policy": "warn",
"fail_closed": true,
"rate_limit_interval": 0
}
deny_toolsmatches either the exposed name (git__git_reset) or the upstream tool name (git_reset, on every upstream that has it).allow_tools, when set, refuses everything not listed.pii_policydefaults towarn, notblock. Real tools return personal data as normal output — everygit logentry carries an author email — and blocking those makes the gateway unusable. Setblockwhen your tools should never emit PII.fail_closeddecides what happens when a layer itself errors. Default: refuse.rate_limit_intervalis0, which disables the behavioural floor's own inter-action delay. That delay is right for one agent taking deliberate steps and wrong for a proxy, where a burst of tool calls is ordinary traffic.
What this does not do
It verifies calls against frozen definitions and inspects arguments and results. It does not read your servers' source, so it cannot see a check that is present, is called, and silently does nothing. That still takes someone reading the implementation.
It also cannot protect against a compromised upstream returning correct-looking data — Layer C consensus in sovereign-mcp addresses that, and requires model providers you configure yourself.
Licence
Business Source License 1.1 — see LICENSE.
In short: the source is public, and you may read it, modify it, and use it for development, evaluation and any other non-production purpose at no cost. Production use requires a commercial licence, which you can obtain from the author. Each version converts to Apache 2.0 on its Change Date, four years after publication.
If you want to run this in production, get in touch.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sovereign_mcp_gateway-0.1.1.tar.gz.
File metadata
- Download URL: sovereign_mcp_gateway-0.1.1.tar.gz
- Upload date:
- Size: 20.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a2609d1cca29fef481c4d019ea376ccdbf1460e147e9e7602b3260064cb83317
|
|
| MD5 |
5d980f2c4135a8c0d698422bab4154a5
|
|
| BLAKE2b-256 |
d9131e979ee9faa0486a671df00dbae9a92d3b818187cd6337adb932a203b76a
|
File details
Details for the file sovereign_mcp_gateway-0.1.1-py3-none-any.whl.
File metadata
- Download URL: sovereign_mcp_gateway-0.1.1-py3-none-any.whl
- Upload date:
- Size: 14.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
92ac92038bf404ab936d37d754a17429669656b1982fe1e6d42263c0d848a81f
|
|
| MD5 |
aaf91e1e5376b13a76a9fcf8a207b4da
|
|
| BLAKE2b-256 |
01c91f45bfab5a7412bdaf68dec4d77cf5c9844a94e60975090a24d180b47e67
|