Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .github/assets/images/repo-header-a4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 15 additions & 0 deletions .github/assets/images/repo-header-a4.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
Image Description Sheet
-----------------------

File Name: repo-header-a4.png
Format: PNG
Dimensions: 830 x 173 pixels

Short Description:
A banner image featuring the word "Openapi" on the left, Various tech figures in the background,
and the Openapi logo on the right.

Purpose:
This image is intended to be used as a header/banner for documentation or repository README.
It visually associates linux tools with the Openapi MCP,
giving a professional and modern look to the project materials.
2 changes: 1 addition & 1 deletion .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## Quick context for AI coding agents

This repository implements the OpenAPI.com MCP gateway (FastAPI + FastMCP). The server acts as a proxy that forwards a client's Bearer token to downstream OpenAPI services and exposes MCP tools implemented under `src/openapi_mcp_sdk/apis/`.
This repository implements the Openapi.com MCP gateway (FastAPI + FastMCP). The server acts as a proxy that forwards a client's Bearer token to downstream Openapi services and exposes MCP tools implemented under `src/openapi_mcp_sdk/apis/`.

Key files
- `src/openapi_mcp_sdk/main.py` — application entry point. Mounts the MCP app and contains HTTP endpoints `/callbacks` and `/status/{request_id}`. Shows how token query params are converted into an Authorization header.
Expand Down
38 changes: 38 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@

name: build

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

jobs:
build:

runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.9", "3.10", "3.11"]

steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v3
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install flake8 pytest
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
- name: Lint with flake8
run: |
# stop the build if there are Python syntax errors or undefined names
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
- name: Test with pytest
run: |
pytest
23 changes: 23 additions & 0 deletions .github/workflows/pylint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: Pylint

on: [push]

jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.8", "3.9", "3.10"]
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v3
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install pylint
- name: Analysing the code with pylint
run: |
pylint $(git ls-files '*.py')
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ re-deploy.sh

# Local build artifacts
.install.stamp
.python-version

# Generated by integration tests (contains token)
.mcp.json
92 changes: 37 additions & 55 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,22 @@
# openapi-mcp-sdk
<div align="center">
<a href="https://openapi.com/">
<img alt="Openapi MCP" src=".github/assets/images/repo-header-a4.png" >
</a>

**`openapi-mcp-sdk`** is the official [openapi.com](https://openapi.com/) MCP SDK.
<h1>🔐 Openapi® MCP</h1>
<h4>The official Python MCP SDK and ready-to-run MCP server for <a href="https://openapi.com/">Openapi®</a></h4>

[![PyPI](https://img.shields.io/pypi/v/openapi-mcp-sdk.svg)](https://pypi.org/project/openapi-mcp-sdk/)
[![Python](https://img.shields.io/badge/python-3.13%2B-blue.svg)](https://www.python.org/)
[![License](https://img.shields.io/github/license/openapi/mcp-server)](LICENSE)
[![MCP](https://img.shields.io/badge/protocol-MCP-1f6feb.svg)](https://modelcontextprotocol.io/)
<br>
[![Linux Foundation Member](https://img.shields.io/badge/Linux%20Foundation-Silver%20Member-003778?logo=linux-foundation&logoColor=white)](https://www.linuxfoundation.org/about/members)
</div>

# Overview

Welcome to **`openapi-mcp-sdk`**, this is the official [openapi.com](https://openapi.com/) MCP SDK.
It ships as a Python package on [PyPI](https://pypi.org/project/openapi-mcp-sdk/) and
can be used in two ways:

Expand All @@ -10,22 +26,20 @@ can be used in two ways:
custom MCP server that wraps openapi.com APIs with your own logic, tools, or auth
layer on top.

---

## Environment variables

All configuration is done through environment variables. None are required to
start the server — defaults are suitable for local use.

### Core

| Variable | Default | Description |
|---|---|---|
| `MCP_PORT` | `8080` | HTTP port the server listens on |
| `MCP_ENV` | `production` | Runtime environment: `dev` \| `staging` \| `production` |
| `MCP_BASE_URL` | `https://mcp.openapi.com` | Public URL of this server (used to build callback and file download URLs) |
| `MCP_CALLBACK_URL` | `$MCP_BASE_URL/callbacks` | Explicit callback URL sent to async APIs |
| `MCP_OPENAPI_ENV` | _(empty)_ | OpenAPI environment: `dev`, `test`, `sandbox` (alias of `test`), or empty for production |
| Variable | Default | Description |
|---|---|------------------------------------------------------------------------------------------|
| `MCP_PORT` | `8080` | HTTP port the server listens on |
| `MCP_ENV` | `production` | Runtime environment: `dev` \| `staging` \| `production` |
| `MCP_BASE_URL` | `http://localhost:8080` | Public URL of this server (used to build callback and file download URLs) |
| `MCP_CALLBACK_URL` | `$MCP_BASE_URL/callbacks` | Explicit callback URL sent to async APIs |
| `MCP_OPENAPI_ENV` | _(empty)_ | Openapi environment: `dev`, `test`, `sandbox` (alias of `test`), or empty for production |

### Storage

Expand Down Expand Up @@ -53,17 +67,13 @@ Used to share async callback results across multiple server instances.
See [`docs/env/`](docs/env/) for per-environment configuration guides (local,
Docker, AWS, GCP, Kubernetes).

---

## Features

- **Secure proxy**: Pass-through of the Bearer Token provided by the client, without direct handling of sensitive credentials.
- **Extensible**: Easily add new tools/APIs by creating modules in [`/apis/`](src/openapi_mcp_sdk/apis/).
- **MCP-compatible**: Designed according to MCP protocol best practices.
- **Modular**: All API call logic and tool registration is centralized in [`mcp_core.py`](src/openapi_mcp_sdk/mcp_core.py).

---

## Quick Start — run from PyPI (recommended)

No cloning, no virtual environment. Start the server in one command:
Expand Down Expand Up @@ -98,34 +108,7 @@ Commands:
token Generate or inspect an openapi.com Bearer token [coming soon]
```

---

## Local launcher script

Copy the block below, paste it into your terminal, and press Enter. It will
create a `mcp-server.sh` file in the current directory and launch the server:

```bash
cat > mcp-server.sh << 'EOF'
#!/bin/bash
# ============================================================
# Openapi.com MCP Server — local launcher
# Edit the variables below, then run: bash mcp-server.sh
# ============================================================

export MCP_PORT="${MCP_PORT:-8080}"
uvx openapi-mcp-sdk server
EOF
bash mcp-server.sh
```

Next time, just run:

```bash
bash mcp-server.sh
```

---

## Running with Docker

Expand All @@ -144,7 +127,7 @@ docker compose logs -f mcp

The server will be accessible at `http://localhost:8080`.

---


## Debug and Development

Expand All @@ -162,13 +145,13 @@ server listens on `http://0.0.0.0:8080`.
To test endpoints manually:

```bash
curl -H "Authorization: Bearer YOUR_TOKEN" http://localhost:8080/mcp/
curl -H "Authorization: Bearer YOUR_TOKEN" http://localhost:8080
```

The server prints request headers and parameters to stdout — no extra
configuration needed.

---


### Remote debugging with VS Code and Docker (one click)

Expand Down Expand Up @@ -218,7 +201,7 @@ required. Just send a new request and the updated code runs.
| MCP server | `localhost:8080` | `0.0.0.0:8080` |
| debugpy listener | `localhost:5678` | `0.0.0.0:5678` |

---


## Authentication

Expand Down Expand Up @@ -248,7 +231,7 @@ before the request reaches the MCP layer, so the behaviour is identical.
> MCP playgrounds, and any client whose configuration only accepts a plain URL
> without a headers field.

---


## MCP Client Configuration (VS Code)

Expand Down Expand Up @@ -289,7 +272,7 @@ before the request reaches the MCP layer, so the behaviour is identical.
- Open the Copilot chat and type `@workspace`.
- Use the tools exposed by the MCP server.

---


## File storage

Expand Down Expand Up @@ -319,7 +302,7 @@ uvx openapi-mcp-sdk server

> The directory is created automatically on first use. For the download links to
> work correctly, `MCP_BASE_URL` must point to the public address of the server
> (default: `https://mcp.openapi.com`).
> (default: `http://localhost:8080`).

### Cloud storage backends

Expand All @@ -331,7 +314,7 @@ uvx openapi-mcp-sdk server

See [`docs/env/`](docs/env/) for full per-environment configuration guides.

---


## Deployment environments

Expand All @@ -343,7 +326,7 @@ See [`docs/env/`](docs/env/) for full per-environment configuration guides.
| Amazon Web Services | [`docs/env/aws.md`](docs/env/aws.md) |
| Kubernetes | [`docs/env/kubernetes.md`](docs/env/kubernetes.md) |

---


## Project Structure

Expand All @@ -357,7 +340,7 @@ See [`docs/env/`](docs/env/) for full per-environment configuration guides.
- [`.vscode/launch.json`](.vscode/launch.json): VS Code debug configuration (attach to debugpy).
- [`docs/`](docs/): Documentation and example configurations.

---


## Adding New Tools/APIs

Expand All @@ -374,23 +357,22 @@ See [`docs/env/`](docs/env/) for full per-environment configuration guides.
```
2. Restart the server to apply the changes.

---


## Security Notes

- **Never** hardcode credentials or tokens in the code.
- The server expects the Bearer Token to be provided by the client via HTTP headers.
- All API calls are proxied using the token provided by the client.

---


## Useful Resources

- [MCP Documentation](https://github.com/anthropics/model-context-protocol)
- [fastmcp](https://pypi.org/project/fastmcp/)
- [openapi.com](https://openapi.com/)

---

## Contributing

Expand Down
30 changes: 15 additions & 15 deletions docs/env/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,21 @@ cache backend, and any platform-specific notes.

## Quick reference — all environment variables

| Variable | Default | Description |
|---|---|---|
| `MCP_PORT` | `8080` | HTTP port the server listens on |
| `MCP_ENV` | `production` | Runtime environment: `dev` \| `staging` \| `production` |
| `MCP_BASE_URL` | `https://mcp.openapi.com` | Public URL of this server (used in callback URLs) |
| `MCP_CALLBACK_URL` | `$MCP_BASE_URL/callbacks` | Full callback URL sent to async APIs |
| `MCP_OPENAPI_ENV` | _(empty)_ | OpenAPI environment: `dev`, `test`, `sandbox` (alias of `test`), or empty for production |
| `MCP_STORAGE_BACKEND` | `local` | Storage backend: `local` \| `gcs` \| `s3` |
| `MCP_STORAGE_PATH` | `./openapi_storage` | Local filesystem path for `local` backend |
| `MCP_STORAGE_BUCKET` | _(required for cloud)_ | Bucket/container name for `gcs` or `s3` backend |
| `MCP_STORAGE_REGION` | _(required for s3)_ | AWS region for the S3 bucket |
| `MCP_CACHE_BACKEND` | `none` | Cache for async callbacks: `none` \| `memcached` \| `redis` |
| `MCP_CACHE_HOST` | _(none)_ | Memcached host (used when `MCP_CACHE_BACKEND=memcached`) |
| `MCP_CACHE_PORT` | `11211` | Memcached port |
| `MCP_CACHE_URL` | _(none)_ | Redis connection URL (used when `MCP_CACHE_BACKEND=redis`) |
| Variable | Default | Description |
|---|---|------------------------------------------------------------------------------------------|
| `MCP_PORT` | `8080` | HTTP port the server listens on |
| `MCP_ENV` | `production` | Runtime environment: `dev` \| `staging` \| `production` |
| `MCP_BASE_URL` | `http://localhost:8080` | Public URL of this server (used in callback URLs) |
| `MCP_CALLBACK_URL` | `$MCP_BASE_URL/callbacks` | Full callback URL sent to async APIs |
| `MCP_OPENAPI_ENV` | _(empty)_ | Openapi environment: `dev`, `test`, `sandbox` (alias of `test`), or empty for production |
| `MCP_STORAGE_BACKEND` | `local` | Storage backend: `local` \| `gcs` \| `s3` |
| `MCP_STORAGE_PATH` | `./openapi_storage` | Local filesystem path for `local` backend |
| `MCP_STORAGE_BUCKET` | _(required for cloud)_ | Bucket/container name for `gcs` or `s3` backend |
| `MCP_STORAGE_REGION` | _(required for s3)_ | AWS region for the S3 bucket |
| `MCP_CACHE_BACKEND` | `none` | Cache for async callbacks: `none` \| `memcached` \| `redis` |
| `MCP_CACHE_HOST` | _(none)_ | Memcached host (used when `MCP_CACHE_BACKEND=memcached`) |
| `MCP_CACHE_PORT` | `11211` | Memcached port |
| `MCP_CACHE_URL` | _(none)_ | Redis connection URL (used when `MCP_CACHE_BACKEND=redis`) |

### Legacy variables (GCP Cloud Run — deprecated)

Expand Down
6 changes: 3 additions & 3 deletions docs/env/gcp.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ Internet → Cloud Run (openapi-mcp-sdk server)
# Core
MCP_PORT=8080
MCP_ENV=production
MCP_BASE_URL=https://mcp.openapi.com
MCP_CALLBACK_URL=https://mcp.openapi.com/callbacks
MCP_BASE_URL=https://mcp.example.com
MCP_CALLBACK_URL=https://mcp.example.com/callbacks
MCP_OPENAPI_ENV= # dev, test, sandbox (alias of test), or empty for production

# Storage
Expand Down Expand Up @@ -81,7 +81,7 @@ spec:
- name: MCP_PORT
value: "8080"
- name: MCP_BASE_URL
value: "https://mcp.openapi.com"
value: "https://mcp.example.com"
- name: MCP_STORAGE_BACKEND
value: "gcs"
- name: MCP_STORAGE_BUCKET
Expand Down
4 changes: 2 additions & 2 deletions docs/env/local.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ Options:
export MCP_BASE_URL=https://abc123.ngrok.io
```

If `MCP_BASE_URL` is not set the server defaults to `https://mcp.openapi.com`, which
If `MCP_BASE_URL` is not set the server defaults to `http://localhost:8080`, which
will not work for local callbacks.

---
Expand Down Expand Up @@ -103,7 +103,7 @@ source local.env && openapi-mcp-sdk server
cat > mcp-server.sh << 'EOF'
#!/bin/bash
export MCP_PORT="${MCP_PORT:-8080}"
export MCP_BASE_URL="${MCP_BASE_URL:-https://mcp.openapi.com}"
export MCP_BASE_URL="${MCP_BASE_URL:-http://localhost:8080}"
export MCP_STORAGE_BACKEND="${MCP_STORAGE_BACKEND:-local}"
export MCP_STORAGE_PATH="${MCP_STORAGE_PATH:-./openapi_storage}"

Expand Down
Loading
Loading