Skip to main content
Glama
Randika97

MCP Integration Bridge

by Randika97

MCP Integration Bridge

An MCP server that connects any two systems so an agent can explore both, map between them, and run real data transfers — then shows its working in a run folder you can audit afterwards.

Nothing in the codebase names a product. Which systems the bridge talks to is decided by a .env file (addresses and credentials) and a profile (the shape of each system: its endpoints, entities, queries, and documentation tree). Pointing the bridge at a different pair of systems is a configuration change.

flowchart LR
  MCP["MCP client<br/>(Cursor, Claude Desktop)"] -- stdio --> B
  UI["Browser UI"] -- HTTP --> B
  B["Integration bridge"] <--> SRC["SOURCE system<br/>records read from"]
  B <--> TGT["TARGET system<br/>records written to"]
  B <--> HUB["HUB (optional)<br/>orchestration API"]
  ENV[".env"] --> B
  PROF["profiles/&lt;id&gt;/"] --> B

See docs/ARCHITECTURE.md for the full design.


What it gives an agent

Capability

How

Explore live APIs

Authenticated tools for each system: REST/OData reads, GraphQL queries, introspection

Explore the docs

Offline keyword search across each system's source or specification tree

Read named entities

source_query_data / target_query_data over operations the profile declares

Transfer records

execute_workflow runs forward, reverse, or a full round trip

Self-bootstrap

A missing workflow is built from a template, a codegen pipeline, or generated modules

Audit everything

Every tool call, payload, and skipped field lands in a timestamped run folder


Related MCP server: GAIIA Expert Proxy (MCP Server)

Quickstart

python -m venv .venv
.venv/Scripts/pip install -r requirements.txt   # Linux/macOS: .venv/bin/pip

cp .env.example .env      # then fill in the SOURCE_* and TARGET_* values
python scripts/selfcheck.py

selfcheck.py validates the profile, catalog, workflow and ingest wiring without contacting either system, so it works before you have credentials.

As an MCP server (stdio) — copy mcp.json.example into your MCP client config and adjust the paths:

.venv/Scripts/python server.py

As an HTTP API for a browser UI:

.venv/Scripts/python http_server.py     # http://127.0.0.1:8765

Start with bridge_info — it reports the active profile, both roles, and exactly which environment variables are still missing.


Configuration

Every connected system is a role, and all roles are configured the same way: <ROLE>_<OPTION>, where the role is SOURCE, TARGET, or HUB. Environment variables override the profile's defaults, so a profile ships the shape of a system and .env supplies the instance.

Minimum viable .env

ACTIVE_PROFILE=erp-to-tms

SOURCE_BASE_URL=https://your-tenant.example.com
SOURCE_TOKEN_URL=https://your-tenant.example.com/auth/realms/main/protocol/openid-connect/token
SOURCE_CLIENT_ID=your-client-id
SOURCE_CLIENT_SECRET=your-client-secret
SOURCE_DOCS_PATH=c:/Repositories/your-erp/workspace

TARGET_BASE_URL=https://your-platform.example.com
TARGET_USERNAME=you@example.com
TARGET_PASSWORD=your-password
TARGET_DOCS_PATH=c:/Repositories/your-platform

.env.example documents the full surface, including connector selection, path prefixes, login form field names, bootstrap behaviour, and the HTTP bridge.

Connectors

A role picks its protocol with <ROLE>_CONNECTOR:

Value

Authentication

Suits

oauth2_rest

OAuth2 client credentials → bearer

REST / OData service catalogues

session_graphql

CSRF-protected form login → cookie

GraphQL web applications

token_api

Credentials → JWT bearer

JSON APIs that issue a token from a login

Searching documentation

Each role's offline search is described entirely by settings, so it works against a source checkout, a specification bundle, or a folder of docs:

SOURCE_DOCS_PATH=c:/Repositories/your-erp/workspace
SOURCE_DOCS_GLOBS=*/model/**/*.projection,*/model/**/*.entity
SOURCE_DOCS_INDEX_GLOB=*/model/**/*.projection

TARGET_DOCS_PATH=c:/Repositories/your-platform
TARGET_DOCS_GLOBS=**/graphql/*.py,**/schema.py
TARGET_DOCS_INDEX_FILE=your_app/schema.py
TARGET_DOCS_INDEX_REGEX=(\w+Query)

DOCS_GLOBS selects what is searchable; the index settings produce the list of named API surfaces that *_search_docs returns alongside raw matches.


MCP tools

Bridge and runs

Tool

Purpose

bridge_info

Active profile, both roles, paths, and what is still unconfigured

run_new

Start a new run folder

run_info

Active run id, folder, and counters

Workflows

Tool

Purpose

list_workflows

Registered workflows and whether each is ready

workflow_bootstrap_hints

Search hints and a starter manifest for a missing workflow

register_workflow

Register a manifest plus forward.py and optional reverse.py

bootstrap_workflow

Build a workflow automatically

execute_workflow

Run forward, reverse, or round_trip

Source rolesource_connection_info, source_search_docs, source_http, source_service_query, source_service_metadata, source_query_data

Target roletarget_connection_info, target_search_docs, target_graphql, target_introspect, target_query_data

Hub rolehub_connection_info, hub_login, hub_trigger_run, hub_poll_run, hub_answer_run, hub_graphql, hub_http

Example agent flow

bridge_info                                        → confirm both roles are configured
source_search_docs("Shipment")                     → find the source API surface
target_introspect()                                → see what the target accepts
source_query_data("shipments", limit=5)            → sample real records
execute_workflow(workflow_id="booking", source_id="12345")
run_info                                           → the folder holding the evidence

Profiles

A profile describes one concrete pair of systems. profiles/erp-to-tms/ ships as a worked reference — copy it, edit it, and set ACTIVE_PROFILE.

profiles/<id>/
  profile.json     role defaults (connector, path prefixes, docs globs) + workflow manifests
  catalog.json     named read operations behind source_query_data / target_query_data
  ingest.json      write operations that generated mappings call
  reconcile.json   entities to compare across both systems
  smoke.json       the end-to-end pipeline and its pass criteria
  discovery.json   discovery step labels and the outcome catalogue
  templates/       bundled forward.py / reverse.py for bootstrap

Only profile.json is required.

Adding a readable entity

"source": { "operations": {
  "purchase_orders": {
    "description": "Purchase order headers.",
    "service": "PurchaseOrderHandling",
    "entity_set": "PurchaseOrderSet",
    "filter_template": "OrderNo eq '{identifier}'",
    "search_field": "Description"
  }
}}

source_query_data("purchase_orders", identifier="PO-1") works immediately, with no code change.

Adding a write operation

Generated mappings call methods that no Python file defines — the adapter resolves the name against ingest.json at call time:

"operations": {
  "create_order": {
    "document": "mutation CreateOrder($input: OrderInput!) { createOrder(input: $input) { order { id state } } }",
    "wrap_positional": "input",
    "variables": { "input": "{input}" },
    "root": "createOrder.order",
    "required": true,
    "flatten": { "id": "id", "state": "state" }
  }
}

Mapping logic too complex to express declaratively belongs in the workflow's forward.py / reverse.py, which is ordinary Python. That is the intended boundary: profiles describe what the systems offer; workflows describe how this business mapping works.


Workflows and runs

A workflow is a manifest (how to fetch from the source, what the target entity is called, whether a reverse callback exists) plus a forward.py and optional reverse.py. Asking for one that does not exist is not an error — the bridge tries a bundled template, then a codegen pipeline, then modules already generated under CODEGEN_ROOT, and only then returns needs_bootstrap with search hints and a starter manifest.

Every tool call runs inside a run folder:

runs/2026-08-11/143022-booking-12345/
  run.json  tool_calls.jsonl  transfer_log.jsonl  skips.jsonl
  inputs/   outputs/   mappings/

HTTP bridge

For browser UIs that cannot speak MCP stdio. Routes are role-shaped:

Method

Path

Purpose

GET

/api/health, /api/info

Liveness and active configuration

GET

/api/workflows, /api/runs

Registry and run history

POST

/api/sessions

Create a session

POST

/api/sessions/{id}/configure

Supply credentials

POST

/api/sessions/{id}/configure-env

Use the server's .env

GET

/api/sessions/{id}/source/test, /target/test

Prove each connection

GET

/api/sessions/{id}/source/services, /target/types

Discovered API surfaces

POST

/api/sessions/{id}/discovery/start

Walk both systems

POST

/api/sessions/{id}/reconcile/run, /reconcile/lookup

Master-data comparison

POST

/api/sessions/{id}/smoke/run

End-to-end proof

POST

/api/sessions/{id}/agent/*

Agent-planned discovery and builds


Repository layout

server.py                MCP entry point (stdio)
http_server.py           HTTP bridge entry point
integration_mcp/
  config/                .env loading, profiles, per-role settings
  connectors/            oauth2_rest, session_graphql, token_api, graphql_ingest
  catalog.py             profile-declared read operations
  search/                offline documentation and source-tree search
  transfer/              workflow execution
  workflows/             registry, manifests, bootstrap strategies
  runs/                  run folders, tool-call logging, spec snapshots
  http/                  sessions, discovery, reconcile, smoke, agent
profiles/                per-integration configuration
workflows/               registered forward/reverse modules (gitignored)
runs/                    run artefacts (gitignored)
scripts/                 selfcheck.py
docs/ARCHITECTURE.md     design, diagrams, extension points

Security notes

  • Each connector may only reach the hosts it was configured with. Add more with <ROLE>_ALLOWED_HOSTS, which keeps an authenticated connector from becoming an SSRF primitive.

  • Credentials are read from the environment only; .env and .env.* are gitignored. Cached cookies and tokens live under STATE_DIR.

  • *_connection_info tools report whether a credential is present, never its value.

  • Writing back to the source system is off by default; it requires post_callback=true or TRANSFER_POST_CALLBACK=1.

F
license - not found
-
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • Self-hosted MCP gateway: turn any API, database or MCP server into AI connectors — no code.

  • MCP server connecting AI agents to non-custodial staking data across 130+ networks.

  • A paid remote MCP for hosted MCP server, built to return verdicts, receipts, usage logs, and audit-r

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Randika97/mcp-integration-bridge'

If you have feedback or need assistance with the MCP directory API, please join our Discord server