Install
$ agentstack add mcp-camelop-mcp-x ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
MCP-X
MCP-X is a single-file multi-client MCP gateway with per-tool access control. The entire implementation lives in mcp_x.py.
Each client authenticates with a Bearer token and can bring a list of their own MCP servers, then share specific tools from those servers with other clients. Clients talk MCP at /mcp; the middleware filters which tools each client can see/call based on config.toml policies. Server owners always have full access to their own tools.
MCP-X (:9000)
┌─────────────────┐
┌───────┐ auth │ FastAPI REST │
│ alice ├──token──> │ /register_* │
└───┬───┘ │ /update_* │
│ │ /get_* │
│ MCP ├─────────────────┤ ┌──────────┐
└──protocol──> │ FastMCP │──proxy──>│ server_a │ │ │ middleware │ │──proxy──>│ server_b │ static auth token
[clients.alice]
auth_token = "123"
[clients.bob]
auth_token = "456"
# 2. MCP servers: name -> upstream URL + which client registered it
[mcp_servers.server_a]
url = "http://localhost:9001"
from_client = "alice" # alice owns server_a
[mcp_servers.server_b]
url = "http://localhost:9002"
from_client = "bob"
# 3. Access control: server_name -> { client -> [tool_patterns] }
# Patterns use fnmatch syntax: * ? [seq] [!seq]
[allow.server_a]
bob = ["*"] # bob can use all tools on server_a
charlie = ["tool_0", "tool_1*", "*_2"] # charlie gets specific tools
[allow.server_b]
alice = ["b-*a*"] # alice gets matching tools on server_b
Server owners (the from_client field) always have full access to their own server's tools -- no [allow] entry needed.
Note on duplicate tool names: If a client has access to multiple servers that expose a tool with the same name, only one will be used (from whichever server is matched first). Tools from owned servers are always checked before shared ones.
Live Reload
config.toml is checked for changes on every request (throttled to once per second). Edit it while the server is running and changes take effect immediately -- no restart needed.
The file is also written to by the server when clients register via the REST API (POST /register_client, /register_mcp_server, /update_access_control). Manually-configured client tokens in the file are preserved across these writes.
REST API
All endpoints (except /register_client) require a Bearer token in the Authorization header.
| Method | Endpoint | Description | |--------|----------|-------------| | POST | /register_client | Create a new client. Returns a client_id and a JWT auth_token (1h expiry). | | POST | /register_mcp_server | Register an upstream MCP server URL. The calling client becomes the owner. | | POST | /update_access_control | Grant or revoke another client's access to tools on your servers. Accepts client_id and server_access: {server_name: [tool_patterns]}. | | GET | /get_access_control | View current access policies for all servers you own. |
The MCP endpoint is at /mcp (stateless HTTP). Clients use standard MCP protocol to list and call tools.
How It Works
- Server name hashing -- server names are stored internally as SHA-256 hashes. This avoids collisions when FastMCP concatenates server and tool names with underscores (e.g. a server named
foowith toolbar_bazvs serverfoo_barwith toolbaz).
- Tool name rewriting -- the middleware strips the internal server-hash prefix before returning tools to clients, so clients see clean tool names. On
call_tool, the middleware re-adds the correct prefix and tries each allowed server until one succeeds.
- JWT --
POST /register_clientissues a JWT (1h expiry). The signing secret is auto-generated and saved tojwt_secreton first run.
Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: camelop
- Source: camelop/mcp-x
- License: Apache-2.0
- Homepage: https://mcp-x.org
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.