mcp-server-enterprise-tools
Click on "Deploy 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., "@mcp-server-enterprise-toolsLook up customer 360 profile for C-01234567"
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.
mcp-server-enterprise-tools
An opinionated tool gateway for LLM-driven backends, designed around the MCP tool model but shipped with its own JSON transports. It focuses on the governance layer: per-tool RBAC from a declarative YAML policy, a structured audit row for every invocation, PII redaction on arguments before persistence, and a typed error envelope so clients can branch on codes instead of string-matching messages.
The transport is a small HTTPS API (POST /mcp/call) plus a Prometheus
/metrics endpoint. The stdio path that would let a full MCP host
discover and call these tools is out of scope in this repo.
The problem
Enterprise backends that want to expose internal APIs to LLM-driven callers hit three gaps that are not addressed at the protocol layer:
caller identity is not first-class and needs to be resolved out-of-band
tool arguments and results can carry PII (SSNs, PANs, account numbers) and those cannot land in cleartext in logs or audit tables
error handling needs to be machine-readable so internal callers can branch on codes without string-matching messages
This repo is an opinionated take on filling those gaps while keeping the tool implementations small and readable.
Related MCP server: MCP Enterprise Tool Gateway
What is exposed
Three bank tools (four operations):
Tool | Verb | Purpose |
| read | profile, primary account summary, risk flags |
| read | full-text with date and amount filters |
| mutating | open a dispute against a transaction |
| read | dispute state by id |
Each has a JSON input schema. Adding a fourth is a single file under
src/mcp_server/tools/ plus a line in app.build_registry.
Architecture
+--------------------+ +------------------+
| Internal caller | | Internal agent |
| (any HTTP client) | | (http) |
+---------+----------+ +---------+--------+
| |
| X-Bank-Identity |
v v
+---+-------------------------------+---+
| Tool gateway (this repo) |
| transport -> registry.call -> handler |
| | |
| rbac.check + audit.write |
+----+-----------------+----------+------+
| | |
v v v
+------------------+ +---------+ +------------------+
| internal APIs | | Postgres| | Prometheus |
| (customer, | | audit | | metrics scraped |
| statements, | | log | | at /metrics |
| disputes) | +---------+ +------------------+
+------------------+Longer version with request flow: docs/architecture.md.
Quick start (runs offline, no keys)
No cloud creds, no api keys, no database to stand up. The audit log defaults
to a local sqlite file, and the three bank tools default to in-repo synthetic
upstreams (MCP_UPSTREAM_MODE=fake). Point AUDIT_DB_URL at postgres and set
MCP_UPSTREAM_MODE=http when you have the real services.
pip install -r requirements.txt
python -m examples.smoke # in-process server + client, exits 0
PYTHONPATH=src pytest -q # 31 passedpython -m examples.smoke starts the FastAPI gateway in-process, drives it
through the full governance path with the http client, and reads the audit
table back. Real output (trimmed):
1. client lists tools
- customer_360.lookup: Look up a customer 360 view: profile, primary account...
- statement_search.query: Search a customer's statements. Supports date range...
- dispute_resolution.open: Open a dispute against a specific transaction...
- dispute_resolution.status: Get the current status of an open dispute by id.
2. customer_360.lookup (allowed for svc-analyst-01)
{
"result": {
"profile": {
"name": "Jane A. Doe",
"email": "[REDACTED]<email>",
"ssn": "[REDACTED]<ssn>",
"notes": "primary card [REDACTED]<pan>on file; backup acct [REDACTED]<acct>"
},
...
}
}
5. dispute_resolution.open (DENIED for svc-analyst-01 by RBAC)
{
"error": {
"code": "forbidden",
"message": "identity 'svc-analyst-01' is not permitted to call 'dispute_resolution.open'",
...
}
}
6. audit log rows (read back from sqlite; args redacted)
[ok ] identity=svc-analyst-01 tool=customer_360.lookup error=-
args_redacted={"customer_id": "C-[REDACTED]<acct>"}
[ok ] identity=svc-dispute-agent-07 tool=dispute_resolution.open error=-
args_redacted={... "notes": "caller gave card [REDACTED]<pan>and ssn [REDACTED]<ssn>"}
[deny ] identity=svc-analyst-01 tool=dispute_resolution.open error=forbidden
4 audit rows written, no raw PAN/SSN present.
SMOKE OKAnd pytest:
31 passed in 1.21sQuick start (production shape)
Local (http + postgres via compose):
docker compose up --build
# server on :8080, prometheus on :9090, postgres on :5432
curl -s -X POST http://localhost:8080/mcp/call \
-H "X-Bank-Identity: svc-analyst-01" \
-H "Content-Type: application/json" \
-d '{"tool":"customer_360.lookup","args":{"customer_id":"C-01234567"}}'Bare local run against the http transport:
pip install -e '.[dev]'
export AUDIT_DB_URL=sqlite:///./audit.db # or a postgres url
make run-http # serves on :8080RBAC model
Deny by default. Policies in configs/rbac.yaml map identities to allowed
tool names, with a trailing .* wildcard for grouping. Every call, allowed
or denied, writes an audit row. Full spec in
docs/rbac_model.md.
Audit log design
One row per tool call. It defaults to a local sqlite file so the server runs
offline, and swaps to Postgres for a real deploy by setting AUDIT_DB_URL
(the store is plain SQLAlchemy, so nothing else changes). Columns:
request_id, identity, tool, outcome, args_redacted, error_code, created_at.
Arguments are passed through Redactor before persistence: SSNs, PANs
(Luhn-checked), email addresses, and 8-17 digit account-shaped numbers
are replaced with marked tokens. The two read tools also apply the same
redactor to their upstream response as defense-in-depth. Details in
src/mcp_server/redaction.py and the tests.
Structured errors
Every failure comes back as an ErrorEnvelope:
{
"error": {
"code": "forbidden",
"message": "identity 'svc-analyst-01' is not permitted to call 'dispute_resolution.open'",
"request_id": "0d3f4a...",
"tool": "dispute_resolution.open",
"retryable": false,
"details": {}
}
}Codes: unauthenticated, forbidden, not_found, invalid_argument,
upstream_unavailable, rate_limited, internal. Clients can branch on
code without string-matching messages.
Deploy
Terraform under terraform/ is a sketch of an internal ALB, ECS Fargate
service, and RDS Postgres for the audit log. It has not been applied
against a live account; treat it as a reference layout.
Prod checklist for a real rollout:
Populate a real
configs/rbac.yaml. Prefer many narrow identities over a few broad ones.Wire the
X-Bank-Identityheader to be set by a trusted upstream (mTLS terminator, OIDC proxy). The server does not authenticate; it only reads the resolved identity.Ship the audit table to your SIEM nightly. The table is the source of truth.
Rotate the break-glass credential regularly and alert on every use.
Repo layout
src/
mcp_server/ server, registry, rbac, audit, redaction, tools/
mcp_client/ http client used for testing and examples
configs/ default.yaml, rbac.yaml, prometheus.yml
terraform/ aws vpc + ecs + rds reference layout
tests/ rbac, audit, redaction, tools, registry
examples/ request/response transcripts
docs/ architecture, rbac modelLicense
MIT. See LICENSE.
This server cannot be deployed
Maintenance
Related MCP Connectors
MCP server for mandates, delegation, policy-gated execution, credential grants, and audit.
MCP server for Modern Treasury — payment orders, transactions, counterparties and ledgers.
A paid remote MCP for CLI tool MCP, built to return verdicts, receipts, usage logs, and audit-ready
Guarded MCP server for agent-readable business truth, provenance, readiness, and discovery.
Related MCP Servers
- FlicenseNot gradedqualityCmaintenanceA production-grade MCP server for a fictional digital bank, exposing tools for an AI copilot to service customers across the full risk spectrum from read-only lookups to money movement and destructive admin actions, with OAuth 2.1 security and a realistic dataset.13 npm1-
- AlicenseNot gradedqualityCmaintenanceGoverned MCP server for bank-grade agent tool access with RBAC, PII redaction, rate limiting, and audit logging.MIT
- AlicenseNot gradedqualityCmaintenanceA universal MCP server for registering internal, external, and OpenAPI-based APIs as MCP tools. It exposes them to MCP clients via Streamable HTTP and provides admin portal, RBAC/session auth, credential injection, and audit logging.Academic Free v1.1
- AlicenseNot gradedqualityCmaintenanceAn enterprise MCP server scaffold that provides secure, governed access to internal tools through RBAC, audit logging, rate limiting, and prompt-injection boundaries, with a FastAPI control plane and OpenTelemetry observability.MIT