GoldenGate MCP Server
A production-grade Model Context Protocol server that exposes real-time banking data — replicated via Oracle GoldenGate CDC — as structured tools for AI agents and LLM clients.
The core banking system is treated as a black box. The server connects only to the downstream Oracle replica and optionally to Kafka topics, never to the source transactional system.
---
Tool Catalog
Read tools (read tier)
| Tool | Description | |------|-------------| | get_entity | Fetch any entity (customer, account, transaction, alert) by type and ID | | get_transaction_history | Paginated transaction history for an account (up to 365-day range) | | get_realtime_events | Recent CDC change events from Kafka, with automatic Oracle fallback | | get_gl_position | GL balance for a given account, currency, and value date | | get_open_alerts | Query the alert queue by type and/or status |
Score tools (score tier)
| Tool | Description | |------|-------------| | score_event | LLM risk score (0–100) for any event — 180 ms hard timeout, never blocks | | classify_alert | Fetch an alert and classify it as genuine or false positive | | generate_report_draft | Draft a SAR / CTR / compliance summary — always includes human-review gate |
Write tools (write tier)
| Tool | Description | |------|-------------| | flag_entity | Flag, block, or unblock an entity via the configured write-back endpoint | | post_adjustment | Post a GL correction, hold release, or workflow approval/rejection |
Note: Write tools (
flag_entity,post_adjustment) requireWRITEBACK_BASE_URLto be configured. They are always registered but return a configuration error if called without it.
---
Architecture
AI Agent / LLM Client
│ MCP protocol (stdio or HTTP)
▼
┌─────────────────────────────────────────┐
│ GoldenGate MCP Server │
│ │
│ read_tools.py score_tools.py │
│ write_tools.py │
│ │ │ │
│ OracleClient AnthropicClient │
│ KafkaConsumer WritebackClient │
│ SchemaMapper CircuitBreaker │
│ AuditLog │
└─────────────────────────────────────────┘
│ │
▼ ▼
Oracle GoldenGate Kafka Topics
replica (read-only) (CDC events)
Key invariants:
- Schema mapping via
schema_map.yaml— zero hardcoded column/table names in code - All SQL in
db/queries.py— zero inline SQL in tool logic - Pydantic validation on every input before any DB or HTTP call
- Every tool call produces an immutable SHA-256-hashed audit log entry
- Every error message includes a suggested next step for the agent
- Prompt injection protection: user-controlled fields are always in separate structured content blocks, never interpolated into system prompts
---
Quick Start
1. Clone and install
git clone https://github.com/your-org/goldengate-mcp.git
cd goldengate-mcp
pip install -e ".[dev]"
Note:
python-oracledbmay not be on your corporate PyPI mirror. Install it separately: ``bash pip install python-oracledb``
2. Configure
Copy the example env file and fill in your values:
cp .env.example .env
Minimum required for read tools (real replica):
ORACLE_DSN=your-host:1521/ORCL
ORACLE_USER=mcp_reader
ORACLE_PASSWORD=your-password
Local testing without Oracle: leave ORACLE_PASSWORD empty (or omit it). The server starts and MCP tools still register; read/score tools that hit the database will error until you configure a working Oracle connection.
3. Run
# Streamable HTTP on http://127.0.0.1:8000/mcp (default when using Python directly — MCP Inspector)
python -m src.server
# stdio transport (Claude Desktop compatible) — requires fastmcp CLI on PATH
fastmcp run src/server.py
# Same HTTP as `python -m src.server` but via CLI (optional)
fastmcp run src/server.py --transport streamable-http --host 127.0.0.1 --port 8000
Direct python -m src.server uses Streamable HTTP bound to 127.0.0.1:8000. Connect the MCP Inspector to http://127.0.0.1:8000/mcp (transport: Streamable HTTP).
4. Docker
docker build -t goldengate-mcp .
docker run --env-file .env goldengate-mcp
---
Configuration Reference
All settings are loaded from environment variables (or .env file).
| Variable | Default | Description | |----------|---------|-------------| | ORACLE_DSN | localhost:1521/ORCL | Oracle connection string | | ORACLE_USER | mcp_reader | Oracle username | | ORACLE_PASSWORD | (empty) | Non-empty = open replica pool at startup; empty = skip Oracle (local MCP testing) | | ORACLE_POOL_MIN | 2 | Minimum pool connections | | ORACLE_POOL_MAX | 10 | Maximum pool connections | | ORACLE_QUERY_RETRY_ATTEMPTS | 2 | Retries on transient Oracle errors (0 = no retry) | | ANTHROPIC_API_KEY | (optional) | Required for score tools | | KAFKA_BROKERS | (optional) | Comma-separated brokers; leave empty to disable Kafka | | KAFKA_CONSUMER_GROUP | goldengate-mcp | Kafka consumer group ID | | WRITEBACK_BASE_URL | (optional) | REST endpoint for write tools; leave empty to disable | | WRITEBACK_API_KEY | (optional) | Bearer token for write-back endpoint | | WRITEBACK_TIMEOUT_SECONDS | 10.0 | HTTP timeout for write-back calls | | CIRCUIT_BREAKER_WRITE_LIMIT | 100 | Max writes per minute before circuit trips | | CIRCUIT_BREAKER_RESET_SECONDS | 60 | Circuit breaker window duration | | RBAC_READ_ROLES | analyst,auditor,agent-read | Comma-separated roles for read tier | | RBAC_SCORE_ROLES | analyst,agent-score | Comma-separated roles for score tier | | RBAC_WRITE_ROLES | compliance-officer,agent-write | Comma-separated roles for write tier | | RBAC_STRICT | false | Reject calls with no auth context | | AUDIT_LOG_MODE | file | file or oracle — see docs/oracle_setup.sql for required DDL | | AUDIT_LOG_FILE_PATH | audit.log | Path for file-mode audit log | | SCHEMA_MAP_PATH | src/schema/schema_map.yaml | Path to schema mapping YAML |
---
Schema Mapping
Physical Oracle table and column names live only in src/schema/schema_map.yaml. The server exposes logical names to agents.
Example — adding a new entity requires only a YAML edit:
entities:
my_entity:
table: BANKING.MY_TABLE
columns:
id: MY_PK_COL
status: STATUS_CODE
amount: TXN_AMOUNT
get_entity("my_entity", "123") works immediately — no code changes needed.
---
RBAC
Tools enforce role-based access via the MCP context metadata. Set the caller's role when configuring your MCP client:
{
"mcpServers": {
"goldengate": {
"command": "fastmcp",
"args": ["run", "/path/to/src/server.py"],
"env": {
"ORACLE_DSN": "host:1521/ORCL",
"ORACLE_PASSWORD": "secret"
}
}
}
}
| Tier | Roles (default) | Tools | |------|----------------|-------| | read | analyst, auditor, agent-read | All read tools | | score | analyst, agent-score | All score tools | | write | compliance-officer, agent-write | All write tools |
Roles are configured via RBAC_*_ROLES env vars — no code changes needed to add roles.
---
Worked Example
Fraud triage loop — five tool calls to go from raw event to SAR draft:
1. get_realtime_events(topic="banking.transactions", lookback_minutes=5)
→ list of recent CDC events from Kafka (or Oracle fallback)
2. score_event(event=<event>, scoring_context={"account_type": "retail"})
→ { score: 87, decision: "review", reasoning: "...", confidence: 0.91 }
3. classify_alert(alert_id="A001", alert_type="fraud")
→ { is_false_positive: false, recommended_action: "escalate_to_compliance" }
4. flag_entity(entity_type="transaction", entity_id="T001",
action="flag", reason="score 87/100, AML pattern match")
→ { status: "flagged", reference: "REF-2024-001" }
5. generate_report_draft(report_type="SAR", subject_id="C001",
evidence_ids=["A001", "T001"])
→ { draft_narrative: "...", HUMAN_REVIEW_REQUIRED: true }
---
Development
# Run tests (no Oracle, Kafka, or Anthropic account needed)
pytest
# Run with coverage
pytest --cov=src --cov-report=term-missing
# Lint
ruff check src tests
All 140 tests run against in-memory mocks — zero external dependencies required for development.
---
Supported Entities
| Logical name | Oracle table | Used by | |---|---|---| | customer | BANKING.CUSTOMER_MASTER | get_entity, flag_entity | | account | BANKING.ACCOUNT_MASTER | get_entity, get_transaction_history | | transaction | BANKING.TRANSACTION_LOG | get_transaction_history, get_realtime_events | | gl_entry | BANKING.GL_BALANCE | get_gl_position | | alert | BANKING.ALERT_QUEUE | get_open_alerts, classify_alert |
---
License
MIT











