Skip to main content
Glama

MCP Hub

Dynamic OpenAPI to MCP server generator. Upload OpenAPI specs and instantly expose them as MCP (Model Context Protocol) servers.

Features

  • Dynamic MCP Generation: Convert any OpenAPI 3.x spec to an MCP server on-the-fly

  • Control Plane API: REST API to manage specs (upload, enable, disable, delete)

  • Multi-spec Support: Run multiple MCP servers simultaneously under /mcp/{spec_name}/

  • Zero Configuration: Tools are automatically generated from OpenAPI operations

Quick Start

1. Install Dependencies

# Using pip
pip install -e .

# Or install dependencies directly
pip install fastapi uvicorn httpx pyyaml python-multipart pydantic fastmcp

2. Run the Server

uvicorn app.main:app --reload --port 8000

The server starts at http://localhost:8000.

3. Register an OpenAPI Spec

# Upload the HTTPBin example spec
curl -X POST "http://localhost:8000/specs/upload" \
  -F "name=httpbin" \
  -F "file=@examples/httpbin.yaml"

4. Enable MCP Exposure

curl -X POST "http://localhost:8000/specs/httpbin/enable"

5. Connect Your MCP Client

The MCP server is now available at http://localhost:8000/mcp/httpbin/

For MCP clients (e.g., Claude Desktop with HTTP transport):

http://localhost:8000/mcp/httpbin/mcp

API Reference

Control Plane Endpoints

Method

Endpoint

Description

POST

/specs/upload

Upload an OpenAPI spec (multipart form)

GET

/specs

List all registered specs

GET

/specs/{name}

Get spec details and tool names

POST

/specs/{name}/enable

Enable MCP exposure

POST

/specs/{name}/disable

Disable MCP exposure

DELETE

/specs/{name}

Delete a spec

GET

/health

Health check

Upload Parameters

  • name (required): Unique identifier for the spec

  • file (required): OpenAPI spec file (YAML or JSON)

  • base_url_override (optional): Override the upstream API base URL

MCP Data Plane

Once a spec is enabled, its MCP server is available at:

/mcp/{spec_name}/

Tool Generation

Tools are generated from OpenAPI operations with these rules:

Tool Naming

  • Uses operationId if present in the spec

  • Otherwise: METHOD__sanitized_path (e.g., GET__pets_petId)

Tool Inputs

  • Path parameters → required fields

  • Query parameters → optional fields (unless required: true)

  • JSON request body → body field (dict type)

Tool Outputs

  • JSON responses are returned as-is

  • Non-JSON responses return {"text": "...", "status_code": ..., "content_type": "..."}

Examples

Register and Enable Dog API

# Upload
curl -X POST "http://localhost:8000/specs/upload" \
  -F "name=dog" \
  -F "file=@examples/dog_api.yaml"

# Enable
curl -X POST "http://localhost:8000/specs/dog/enable"

# List tools
curl "http://localhost:8000/specs/dog"

Register and Enable DailyMed (Drug Labeling API)

Access FDA drug labeling information from the National Library of Medicine's DailyMed database:

# Upload
curl -X POST "http://localhost:8000/specs/upload" \
  -F "name=dailymed" \
  -F "file=@examples/dailymed.yaml"

# Enable
curl -X POST "http://localhost:8000/specs/dailymed/enable"

# List tools
curl "http://localhost:8000/specs/dailymed"

Available DailyMed Tools:

  • dailymed_listSpls - Search drug labeling documents by name, NDC, or RxCUI

  • dailymed_getSplBySetId - Get full details of a specific drug label

  • dailymed_getSplHistory - Get version history of a drug label

  • dailymed_getSplMedia - Get associated images and PDFs

  • dailymed_getSplNdcs - Get NDCs for a drug label

  • dailymed_getSplPackaging - Get packaging information

  • dailymed_listDrugNames - Search for drug names

  • dailymed_listNdcs - List National Drug Codes

  • dailymed_listRxcuis - List RxNorm identifiers

Example Tool Calls:

# Search for aspirin SPLs
dailymed_listSpls drug_name="aspirin" name_type="BOTH" pagesize=5

# Get details for a specific SPL
dailymed_getSplBySetId setid="b0aec776-3e30-4e59-8a07-0027e5fc4cb3"

# Search drug names
dailymed_listDrugNames drug_name="ibuprofen" pagesize=10

Register and Enable openFDA Drug Label API

Query FDA drug product labeling data including prescribing information, warnings, and drug interactions:

# Upload
curl -X POST "http://localhost:8000/specs/upload" \
  -F "name=openfda" \
  -F "file=@examples/openfda_drug_label.yaml"

# Enable
curl -X POST "http://localhost:8000/specs/openfda/enable"

Available Tool:

  • openfda_drug_label_query - Search FDA drug labeling with openFDA query syntax

Example Tool Calls:

# Search by brand name
openfda_drug_label_query search="openfda.brand_name:advil" limit=5

# Search drug interactions
openfda_drug_label_query search="drug_interactions:warfarin" limit=10

# Search by RxCUI
openfda_drug_label_query search="openfda.rxcui:198440"

# Count manufacturers
openfda_drug_label_query count="openfda.manufacturer_name.exact"

Register and Enable RxNorm API

Access NLM's RxNorm database for normalized drug names and identifiers:

# Upload
curl -X POST "http://localhost:8000/specs/upload" \
  -F "name=rxnorm" \
  -F "file=@examples/rxnorm.yaml"

# Enable
curl -X POST "http://localhost:8000/specs/rxnorm/enable"

Key RxNorm Tools:

  • rxnorm_findRxcui - Find RxCUI by drug name or external ID

  • rxnorm_getRxConceptProperties - Get concept properties

  • rxnorm_getRelatedByType - Find related concepts by TTY or RELA

  • rxnorm_getDrugs - Search drugs by name

  • rxnorm_getNdcs - Get NDCs for an RxCUI

  • rxnorm_getInteraction - Get drug-drug interactions

  • rxnorm_getInteractionList - Check interactions between multiple drugs

  • rxnorm_getApproximateMatch - Fuzzy match drug names

Example Tool Calls:

# Find RxCUI by drug name
rxnorm_findRxcui name="lipitor"

# Get concept properties
rxnorm_getRxConceptProperties rxcui="198440"

# Find related concepts (ingredients)
rxnorm_getRelatedByType rxcui="198440" tty="IN"

# Check drug interactions
rxnorm_getInteraction rxcui="198440"

# Check interactions between multiple drugs
rxnorm_getInteractionList rxcuis="198440,153165"

With Base URL Override

curl -X POST "http://localhost:8000/specs/upload" \
  -F "name=myapi" \
  -F "file=@myspec.yaml" \
  -F "base_url_override=https://api.example.com/v1"

Claude Desktop Configuration

Add to your Claude Desktop MCP config:

{
  "mcpServers": {
    "httpbin": {
      "url": "http://localhost:8000/mcp/httpbin/mcp"
    },
    "dog": {
      "url": "http://localhost:8000/mcp/dog/mcp"
    }
  }
}

Architecture

┌─────────────────────────────────────────────────────────────┐
│                        MCP Hub                               │
├─────────────────────────────────────────────────────────────┤
│  Control Plane (/specs/*)     │    Data Plane (/mcp/*)      │
│  ┌─────────────────────────┐  │  ┌─────────────────────────┐│
│  │ POST /specs/upload      │  │  │   MCPDispatcher         ││
│  │ GET  /specs             │  │  │   ┌─────────────────┐   ││
│  │ GET  /specs/{name}      │  │  │   │ /mcp/httpbin/   │───┼┼──► HTTPBin API
│  │ POST /specs/{name}/enable│ │  │   │ /mcp/dog/      │───┼┼──► Dog API
│  │ POST /specs/{name}/disable│ │ │   │ /mcp/{spec}/    │───┼┼──► Any API
│  │ DELETE /specs/{name}    │  │  │   └─────────────────┘   ││
│  └─────────────────────────┘  │  └─────────────────────────┘│
│              │                │              │               │
│              ▼                │              ▼               │
│  ┌─────────────────────────────────────────────────────────┐│
│  │                    SpecRegistry                          ││
│  │   - Stores spec metadata & parsed content               ││
│  │   - Manages enable/disable state                        ││
│  │   - Holds generated FastMCP http_app instances          ││
│  └─────────────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────────────┘

Limitations (MVP)

  • In-memory storage: Specs are lost on restart

  • No authentication: Auth headers are not forwarded to upstream APIs

  • JSON bodies only: Only application/json request bodies are supported

  • OpenAPI 3.x only: Swagger 2.0 specs are not supported

Project Structure

mcp_hub/
├── app/
│   ├── __init__.py
│   ├── main.py           # FastAPI app, routes, MCP mount
│   ├── models.py         # Pydantic models
│   ├── registry.py       # In-memory spec registry
│   ├── openapi_loader.py # YAML/JSON parsing & validation
│   ├── openapi_to_mcp.py # OpenAPI → FastMCP conversion
│   └── mcp_dispatcher.py # ASGI dispatcher for /mcp/*
├── examples/
│   ├── httpbin.yaml      # HTTPBin OpenAPI spec
│   ├── dog_api.yaml      # Dog API OpenAPI spec
│   ├── dailymed.yaml     # DailyMed drug labeling API spec
│   ├── openfda_drug_label.yaml  # openFDA drug label API spec
│   ├── rxnorm.yaml       # RxNorm drug identifiers API spec
│   └── demo.md           # Demo walkthrough
├── pyproject.toml
└── README.md

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/ArjunSWalia/dynamic-mcp-hub'

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