openapi-mcp-gateway 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- openapi_mcp_gateway-0.1.0/.github/release.yml +24 -0
- openapi_mcp_gateway-0.1.0/.github/workflows/ci.yml +62 -0
- openapi_mcp_gateway-0.1.0/.github/workflows/release.yml +83 -0
- openapi_mcp_gateway-0.1.0/.gitignore +26 -0
- openapi_mcp_gateway-0.1.0/LICENSE +21 -0
- openapi_mcp_gateway-0.1.0/PKG-INFO +295 -0
- openapi_mcp_gateway-0.1.0/README.md +255 -0
- openapi_mcp_gateway-0.1.0/examples/asana.yml +28 -0
- openapi_mcp_gateway-0.1.0/examples/github.yml +19 -0
- openapi_mcp_gateway-0.1.0/examples/multi-server.yml +56 -0
- openapi_mcp_gateway-0.1.0/examples/petstore.yml +10 -0
- openapi_mcp_gateway-0.1.0/pyproject.toml +125 -0
- openapi_mcp_gateway-0.1.0/src/openapi_mcp_gateway/__init__.py +15 -0
- openapi_mcp_gateway-0.1.0/src/openapi_mcp_gateway/auth/__init__.py +15 -0
- openapi_mcp_gateway-0.1.0/src/openapi_mcp_gateway/auth/detector.py +64 -0
- openapi_mcp_gateway-0.1.0/src/openapi_mcp_gateway/auth/provider.py +412 -0
- openapi_mcp_gateway-0.1.0/src/openapi_mcp_gateway/auth/resolver.py +51 -0
- openapi_mcp_gateway-0.1.0/src/openapi_mcp_gateway/cli.py +289 -0
- openapi_mcp_gateway-0.1.0/src/openapi_mcp_gateway/client.py +98 -0
- openapi_mcp_gateway-0.1.0/src/openapi_mcp_gateway/gateway.py +477 -0
- openapi_mcp_gateway-0.1.0/src/openapi_mcp_gateway/generator.py +206 -0
- openapi_mcp_gateway-0.1.0/src/openapi_mcp_gateway/logger.py +111 -0
- openapi_mcp_gateway-0.1.0/src/openapi_mcp_gateway/openapi.py +260 -0
- openapi_mcp_gateway-0.1.0/src/openapi_mcp_gateway/policy.py +51 -0
- openapi_mcp_gateway-0.1.0/src/openapi_mcp_gateway/settings.py +193 -0
- openapi_mcp_gateway-0.1.0/src/openapi_mcp_gateway/stores/__init__.py +28 -0
- openapi_mcp_gateway-0.1.0/src/openapi_mcp_gateway/stores/base.py +58 -0
- openapi_mcp_gateway-0.1.0/src/openapi_mcp_gateway/stores/memory.py +56 -0
- openapi_mcp_gateway-0.1.0/src/openapi_mcp_gateway/stores/redis.py +62 -0
- openapi_mcp_gateway-0.1.0/tests/__init__.py +0 -0
- openapi_mcp_gateway-0.1.0/tests/conftest.py +46 -0
- openapi_mcp_gateway-0.1.0/tests/fixtures/petstore.json +256 -0
- openapi_mcp_gateway-0.1.0/tests/fixtures/petstore.yml +152 -0
- openapi_mcp_gateway-0.1.0/tests/integration/__init__.py +0 -0
- openapi_mcp_gateway-0.1.0/tests/integration/test_gateway.py +145 -0
- openapi_mcp_gateway-0.1.0/tests/integration/test_oauth_flow.py +183 -0
- openapi_mcp_gateway-0.1.0/tests/unit/__init__.py +0 -0
- openapi_mcp_gateway-0.1.0/tests/unit/test_cli.py +85 -0
- openapi_mcp_gateway-0.1.0/tests/unit/test_client.py +72 -0
- openapi_mcp_gateway-0.1.0/tests/unit/test_generator.py +137 -0
- openapi_mcp_gateway-0.1.0/tests/unit/test_logger.py +112 -0
- openapi_mcp_gateway-0.1.0/tests/unit/test_openapi.py +244 -0
- openapi_mcp_gateway-0.1.0/tests/unit/test_policy.py +93 -0
- openapi_mcp_gateway-0.1.0/tests/unit/test_resolver.py +51 -0
- openapi_mcp_gateway-0.1.0/tests/unit/test_settings.py +155 -0
- openapi_mcp_gateway-0.1.0/tests/unit/test_stores.py +120 -0
- openapi_mcp_gateway-0.1.0/uv.lock +1268 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
changelog:
|
|
2
|
+
exclude:
|
|
3
|
+
labels:
|
|
4
|
+
- ignore-for-release
|
|
5
|
+
authors:
|
|
6
|
+
- dependabot
|
|
7
|
+
categories:
|
|
8
|
+
- title: Breaking Changes
|
|
9
|
+
labels:
|
|
10
|
+
- breaking
|
|
11
|
+
- title: Features
|
|
12
|
+
labels:
|
|
13
|
+
- feature
|
|
14
|
+
- enhancement
|
|
15
|
+
- title: Bug Fixes
|
|
16
|
+
labels:
|
|
17
|
+
- bug
|
|
18
|
+
- fix
|
|
19
|
+
- title: Documentation
|
|
20
|
+
labels:
|
|
21
|
+
- documentation
|
|
22
|
+
- title: Other Changes
|
|
23
|
+
labels:
|
|
24
|
+
- "*"
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: ['**']
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [master]
|
|
8
|
+
workflow_dispatch:
|
|
9
|
+
workflow_call:
|
|
10
|
+
|
|
11
|
+
concurrency:
|
|
12
|
+
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
|
|
13
|
+
cancel-in-progress: true
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
lint:
|
|
17
|
+
name: Lint & Format
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/checkout@v4
|
|
21
|
+
- uses: astral-sh/setup-uv@v6
|
|
22
|
+
with:
|
|
23
|
+
enable-cache: true
|
|
24
|
+
- run: uv sync --extra dev --extra redis
|
|
25
|
+
- run: uv run ruff check src/ tests/
|
|
26
|
+
- run: uv run ruff format --check src/ tests/
|
|
27
|
+
|
|
28
|
+
typecheck:
|
|
29
|
+
name: Type Check
|
|
30
|
+
runs-on: ubuntu-latest
|
|
31
|
+
steps:
|
|
32
|
+
- uses: actions/checkout@v4
|
|
33
|
+
- uses: astral-sh/setup-uv@v6
|
|
34
|
+
with:
|
|
35
|
+
enable-cache: true
|
|
36
|
+
- run: uv sync --extra dev --extra redis
|
|
37
|
+
- run: uv run basedpyright src/ tests/
|
|
38
|
+
|
|
39
|
+
test:
|
|
40
|
+
name: Test (Python ${{ matrix.python-version }})
|
|
41
|
+
runs-on: ubuntu-latest
|
|
42
|
+
strategy:
|
|
43
|
+
fail-fast: false
|
|
44
|
+
matrix:
|
|
45
|
+
python-version: ["3.11", "3.12", "3.13"]
|
|
46
|
+
steps:
|
|
47
|
+
- uses: actions/checkout@v4
|
|
48
|
+
- uses: astral-sh/setup-uv@v6
|
|
49
|
+
with:
|
|
50
|
+
python-version: ${{ matrix.python-version }}
|
|
51
|
+
enable-cache: true
|
|
52
|
+
- run: uv sync --extra dev --extra redis
|
|
53
|
+
- run: uv run pytest tests/ -v --tb=short
|
|
54
|
+
|
|
55
|
+
build:
|
|
56
|
+
name: Build
|
|
57
|
+
runs-on: ubuntu-latest
|
|
58
|
+
needs: [lint, typecheck, test]
|
|
59
|
+
steps:
|
|
60
|
+
- uses: actions/checkout@v4
|
|
61
|
+
- uses: astral-sh/setup-uv@v6
|
|
62
|
+
- run: uv build
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*'
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
build:
|
|
13
|
+
name: Build
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
|
|
18
|
+
- name: Verify tag matches pyproject.toml version
|
|
19
|
+
run: |
|
|
20
|
+
TAG="${GITHUB_REF_NAME#v}"
|
|
21
|
+
VERSION=$(python3 -c "import tomllib; print(tomllib.load(open('pyproject.toml','rb'))['project']['version'])")
|
|
22
|
+
if [ "$TAG" != "$VERSION" ]; then
|
|
23
|
+
echo "::error::Tag v$TAG does not match pyproject.toml version $VERSION"
|
|
24
|
+
exit 1
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
- uses: astral-sh/setup-uv@v6
|
|
28
|
+
with:
|
|
29
|
+
enable-cache: true
|
|
30
|
+
|
|
31
|
+
- run: uv build
|
|
32
|
+
|
|
33
|
+
- uses: actions/upload-artifact@v4
|
|
34
|
+
with:
|
|
35
|
+
name: dist
|
|
36
|
+
path: dist/
|
|
37
|
+
|
|
38
|
+
publish-pypi:
|
|
39
|
+
name: Publish
|
|
40
|
+
needs: build
|
|
41
|
+
runs-on: ubuntu-latest
|
|
42
|
+
environment:
|
|
43
|
+
name: pypi
|
|
44
|
+
url: https://pypi.org/p/openapi-mcp-gateway
|
|
45
|
+
permissions:
|
|
46
|
+
id-token: write
|
|
47
|
+
attestations: write
|
|
48
|
+
contents: read
|
|
49
|
+
steps:
|
|
50
|
+
- uses: actions/download-artifact@v4
|
|
51
|
+
with:
|
|
52
|
+
name: dist
|
|
53
|
+
path: dist/
|
|
54
|
+
|
|
55
|
+
- uses: actions/attest-build-provenance@v2
|
|
56
|
+
with:
|
|
57
|
+
subject-path: 'dist/*'
|
|
58
|
+
|
|
59
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
60
|
+
|
|
61
|
+
github-release:
|
|
62
|
+
name: GitHub Release
|
|
63
|
+
needs: publish-pypi
|
|
64
|
+
runs-on: ubuntu-latest
|
|
65
|
+
permissions:
|
|
66
|
+
contents: write
|
|
67
|
+
steps:
|
|
68
|
+
- uses: actions/checkout@v4
|
|
69
|
+
|
|
70
|
+
- uses: actions/download-artifact@v4
|
|
71
|
+
with:
|
|
72
|
+
name: dist
|
|
73
|
+
path: dist/
|
|
74
|
+
|
|
75
|
+
- name: Create GitHub Release
|
|
76
|
+
env:
|
|
77
|
+
GH_TOKEN: ${{ github.token }}
|
|
78
|
+
run: |
|
|
79
|
+
gh release create "${GITHUB_REF_NAME}" \
|
|
80
|
+
--repo "${GITHUB_REPOSITORY}" \
|
|
81
|
+
--title "${GITHUB_REF_NAME}" \
|
|
82
|
+
--generate-notes \
|
|
83
|
+
dist/*
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# Distribution / packaging
|
|
7
|
+
*.egg
|
|
8
|
+
*.egg-info/
|
|
9
|
+
build/
|
|
10
|
+
dist/
|
|
11
|
+
|
|
12
|
+
# Virtual environments
|
|
13
|
+
.venv/
|
|
14
|
+
venv/
|
|
15
|
+
|
|
16
|
+
# Caches
|
|
17
|
+
.mypy_cache/
|
|
18
|
+
.pytest_cache/
|
|
19
|
+
.ruff_cache/
|
|
20
|
+
|
|
21
|
+
# Local secrets / state
|
|
22
|
+
.env
|
|
23
|
+
*.tokens.json
|
|
24
|
+
|
|
25
|
+
# Internal docs (drafts, not ready for publish)
|
|
26
|
+
docs/
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 mroops0111
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: openapi-mcp-gateway
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Turn any OpenAPI specification into a Model Context Protocol (MCP) server with a single command.
|
|
5
|
+
Project-URL: Homepage, https://github.com/mroops0111/openapi-mcp-gateway
|
|
6
|
+
Project-URL: Repository, https://github.com/mroops0111/openapi-mcp-gateway
|
|
7
|
+
Project-URL: Issues, https://github.com/mroops0111/openapi-mcp-gateway/issues
|
|
8
|
+
Author: YunTai Yang
|
|
9
|
+
License: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: ai,gateway,llm,mcp,openapi
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
20
|
+
Requires-Python: >=3.11
|
|
21
|
+
Requires-Dist: click>=8.0.0
|
|
22
|
+
Requires-Dist: fastapi>=0.115.0
|
|
23
|
+
Requires-Dist: httpx>=0.28.0
|
|
24
|
+
Requires-Dist: inflection>=0.5.1
|
|
25
|
+
Requires-Dist: mcp[cli]>=1.25.0
|
|
26
|
+
Requires-Dist: pydantic-settings>=2.0.0
|
|
27
|
+
Requires-Dist: pydantic>=2.0.0
|
|
28
|
+
Requires-Dist: pyyaml>=6.0.0
|
|
29
|
+
Requires-Dist: uvicorn[standard]>=0.32.0
|
|
30
|
+
Provides-Extra: dev
|
|
31
|
+
Requires-Dist: basedpyright>=1.20.0; extra == 'dev'
|
|
32
|
+
Requires-Dist: fakeredis>=2.26.0; extra == 'dev'
|
|
33
|
+
Requires-Dist: httpx>=0.28.0; extra == 'dev'
|
|
34
|
+
Requires-Dist: pytest-asyncio>=1.0.0; extra == 'dev'
|
|
35
|
+
Requires-Dist: pytest>=8.0.0; extra == 'dev'
|
|
36
|
+
Requires-Dist: ruff>=0.8.0; extra == 'dev'
|
|
37
|
+
Provides-Extra: redis
|
|
38
|
+
Requires-Dist: redis>=6.2.0; extra == 'redis'
|
|
39
|
+
Description-Content-Type: text/markdown
|
|
40
|
+
|
|
41
|
+
# OpenAPI MCP Gateway
|
|
42
|
+
|
|
43
|
+
[](https://github.com/mroops0111/openapi-mcp-gateway/actions/workflows/ci.yml)
|
|
44
|
+
[](https://pypi.org/project/openapi-mcp-gateway/)
|
|
45
|
+
[](https://pypi.org/project/openapi-mcp-gateway/)
|
|
46
|
+
[](LICENSE)
|
|
47
|
+
|
|
48
|
+
Turn any OpenAPI specification into a [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server with a single command.
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
openapi-mcp-gateway --spec https://petstore3.swagger.io/api/v3/openapi.json
|
|
52
|
+
# Server live at http://127.0.0.1:8000/api/mcp
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
- **No code generation.** Point it at a spec and every operation becomes an MCP tool.
|
|
56
|
+
- **Multi-API.** Run several OpenAPI services in one process, each on its own mount path.
|
|
57
|
+
- **Auth built in.** Bearer, API Key, and OAuth2 (with per-user delegation).
|
|
58
|
+
- **Flexible transport.** Streamable HTTP, SSE, or stdio.
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Table of Contents
|
|
63
|
+
|
|
64
|
+
- [Installation](#installation)
|
|
65
|
+
- [Quick Start](#quick-start)
|
|
66
|
+
- [Authentication](#authentication)
|
|
67
|
+
- [Configuration](#configuration)
|
|
68
|
+
- [Python API](#python-api)
|
|
69
|
+
- [License](#license)
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## Installation
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
pip install openapi-mcp-gateway
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Or with [uv](https://docs.astral.sh/uv/):
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
uv add openapi-mcp-gateway
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Optional extras:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
pip install "openapi-mcp-gateway[redis]" # Redis token store
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Requires Python 3.11+.
|
|
92
|
+
|
|
93
|
+
## Quick Start
|
|
94
|
+
|
|
95
|
+
### 1. Public API, No Auth
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
openapi-mcp-gateway --spec https://petstore3.swagger.io/api/v3/openapi.json --name petstore
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Connect an MCP client to `http://127.0.0.1:8000/petstore/mcp`.
|
|
102
|
+
|
|
103
|
+
### 2. Bearer Token
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
export GITHUB_TOKEN="ghp_..."
|
|
107
|
+
openapi-mcp-gateway \
|
|
108
|
+
--spec https://raw.githubusercontent.com/github/rest-api-description/main/descriptions/api.github.com/api.github.com.json \
|
|
109
|
+
--name github \
|
|
110
|
+
--auth-type bearer \
|
|
111
|
+
--auth-token '${GITHUB_TOKEN}'
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### 3. OAuth2 (Auto-Detected from Spec)
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
export ASANA_CLIENT_ID="..." ASANA_CLIENT_SECRET="..."
|
|
118
|
+
openapi-mcp-gateway \
|
|
119
|
+
--spec https://raw.githubusercontent.com/Asana/openapi/master/defs/asana_oas.yaml \
|
|
120
|
+
--name asana \
|
|
121
|
+
--auth-type oauth2 \
|
|
122
|
+
--auth-client-id '${ASANA_CLIENT_ID}' \
|
|
123
|
+
--auth-client-secret '${ASANA_CLIENT_SECRET}' \
|
|
124
|
+
--auth-scopes "openid,email,profile,users:read,workspaces:read"
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### 4. Multiple APIs at Once
|
|
128
|
+
|
|
129
|
+
```yaml
|
|
130
|
+
# servers.yml
|
|
131
|
+
host: "0.0.0.0"
|
|
132
|
+
port: 8000
|
|
133
|
+
|
|
134
|
+
servers:
|
|
135
|
+
- name: petstore
|
|
136
|
+
spec: https://petstore3.swagger.io/api/v3/openapi.json
|
|
137
|
+
|
|
138
|
+
- name: github
|
|
139
|
+
spec: ./openapi/github.json
|
|
140
|
+
auth:
|
|
141
|
+
type: bearer
|
|
142
|
+
token: ${GITHUB_TOKEN}
|
|
143
|
+
policy:
|
|
144
|
+
allow: ["GET /repos/*", "GET /users/*"]
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
openapi-mcp-gateway --config servers.yml
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Runnable examples live in [`examples/`](examples/). Each YAML lists its prerequisites at the top.
|
|
152
|
+
|
|
153
|
+
### 5. Local Desktop Client (stdio)
|
|
154
|
+
|
|
155
|
+
For Claude Desktop, IDE integrations, or any MCP client that prefers stdio:
|
|
156
|
+
|
|
157
|
+
```json
|
|
158
|
+
{
|
|
159
|
+
"mcpServers": {
|
|
160
|
+
"petstore": {
|
|
161
|
+
"command": "openapi-mcp-gateway",
|
|
162
|
+
"args": ["--spec", "/abs/path/to/openapi.json", "--transport", "stdio"]
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
## Authentication
|
|
169
|
+
|
|
170
|
+
| Type | Use Case | Required Fields |
|
|
171
|
+
|------|----------|-----------------|
|
|
172
|
+
| `none` | Public APIs | |
|
|
173
|
+
| `bearer` | Personal access tokens, API tokens | `token` |
|
|
174
|
+
| `api_key` | API key in `X-API-Key` header (override with `auth.api_key_header`) | `token` |
|
|
175
|
+
| `oauth2` | Per-user delegated access | `client_id`, `client_secret` |
|
|
176
|
+
|
|
177
|
+
All string fields support `${ENV_VAR}` and `${ENV_VAR:-default}` interpolation, resolved at request time:
|
|
178
|
+
|
|
179
|
+
```yaml
|
|
180
|
+
auth:
|
|
181
|
+
type: bearer
|
|
182
|
+
token: ${GITHUB_TOKEN}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### OAuth2 Details
|
|
186
|
+
|
|
187
|
+
`authorizationUrl`, `tokenUrl`, and `scopes` are read from the spec's `securitySchemes`. Override `auth.authorization_url`, `auth.token_url`, or `auth.scopes` when the spec is incomplete.
|
|
188
|
+
|
|
189
|
+
## Configuration
|
|
190
|
+
|
|
191
|
+
Run `openapi-mcp-gateway --help` for the CLI reference. For YAML config, the [Quick Start](#quick-start) examples cover most setups; the full field reference:
|
|
192
|
+
|
|
193
|
+
<details>
|
|
194
|
+
<summary><b>Top-Level Fields</b></summary>
|
|
195
|
+
|
|
196
|
+
| Field | Type | Default | Description |
|
|
197
|
+
|---|---|---|---|
|
|
198
|
+
| `host` | string | `0.0.0.0` | Bind address (`0.0.0.0` = all interfaces). Clients on the same machine usually open `http://localhost:{port}` or `http://127.0.0.1:{port}`. |
|
|
199
|
+
| `port` | int | `8000` | Bind port |
|
|
200
|
+
| `url` | string | *(empty)* | Public base URL for OAuth redirects and discovery. When unset: `http://localhost:{port}` if `host` is `0.0.0.0`, otherwise `http://{host}:{port}`. Override when your registered redirect URI uses another host (tunnel, reverse proxy, etc.). |
|
|
201
|
+
| `transport` | string | `streamable-http` | `sse`, `streamable-http`, or `stdio` |
|
|
202
|
+
| `store.type` | string | `memory` | `memory` or `redis` |
|
|
203
|
+
| `store.redis_url` | string | `redis://localhost:6379` | Redis URL when `store.type: redis` |
|
|
204
|
+
| `logging.level` | string | `INFO` | `DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL` |
|
|
205
|
+
| `logging.format` | string | `text` | `text` or `json` |
|
|
206
|
+
| `logging.file` | string | | Mirror logs to this file |
|
|
207
|
+
| `servers` | list | required | List of per-server config entries |
|
|
208
|
+
|
|
209
|
+
</details>
|
|
210
|
+
|
|
211
|
+
<details>
|
|
212
|
+
<summary><b>Per-Server Fields</b></summary>
|
|
213
|
+
|
|
214
|
+
| Field | Type | Default | Description |
|
|
215
|
+
|---|---|---|---|
|
|
216
|
+
| `name` | string | required | Unique identifier; mount path defaults to `/{name}` |
|
|
217
|
+
| `spec` | string | required | Path or URL to OpenAPI document (JSON or YAML) |
|
|
218
|
+
| `base_url` | string | from spec | Override the upstream base URL |
|
|
219
|
+
| `auth.*` | | | See [Authentication](#authentication) |
|
|
220
|
+
| `policy.allow` | list | | Only expose matching operations |
|
|
221
|
+
| `policy.deny` | list | | Exclude matching operations |
|
|
222
|
+
| `timeout` | float | `90` | HTTP timeout in seconds |
|
|
223
|
+
|
|
224
|
+
</details>
|
|
225
|
+
|
|
226
|
+
### Filtering Operations
|
|
227
|
+
|
|
228
|
+
Use `policy.allow` and `policy.deny` with `fnmatch` syntax against operation IDs (`getUsers`, `create*`) or method + path (`GET /users/*`):
|
|
229
|
+
|
|
230
|
+
```yaml
|
|
231
|
+
policy:
|
|
232
|
+
allow: ["GET /repos/*"]
|
|
233
|
+
deny: ["GET /repos/*/actions/secrets*"]
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
Or mark operations directly in the spec and enable `marked_only`:
|
|
237
|
+
|
|
238
|
+
```yaml
|
|
239
|
+
# openapi.yml
|
|
240
|
+
paths:
|
|
241
|
+
/users:
|
|
242
|
+
get:
|
|
243
|
+
operationId: listUsers
|
|
244
|
+
x-mcp-integration:
|
|
245
|
+
expose:
|
|
246
|
+
tool: {}
|
|
247
|
+
```
|
|
248
|
+
```yaml
|
|
249
|
+
# servers.yml
|
|
250
|
+
policy:
|
|
251
|
+
marked_only: true
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
Filters apply in order: `marked_only`, then `allow`, then `deny`.
|
|
255
|
+
|
|
256
|
+
### Logging
|
|
257
|
+
|
|
258
|
+
Configure via the `logging.*` YAML keys or via CLI flags. `-v` and `-q` are shortcuts for `DEBUG` and `WARNING`.
|
|
259
|
+
|
|
260
|
+
## Python API
|
|
261
|
+
|
|
262
|
+
Use the gateway as a library inside your own Python application:
|
|
263
|
+
|
|
264
|
+
```python
|
|
265
|
+
from openapi_mcp_gateway import Gateway
|
|
266
|
+
|
|
267
|
+
gateway = Gateway()
|
|
268
|
+
gateway.add_server(
|
|
269
|
+
name="petstore",
|
|
270
|
+
spec="https://petstore3.swagger.io/api/v3/openapi.json",
|
|
271
|
+
)
|
|
272
|
+
gateway.add_server(
|
|
273
|
+
name="github",
|
|
274
|
+
spec="./github-openapi.json",
|
|
275
|
+
auth={"type": "bearer", "token": "${GITHUB_TOKEN}"},
|
|
276
|
+
policy={"allow": ["GET /repos/*"]},
|
|
277
|
+
)
|
|
278
|
+
gateway.run(port=8000)
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
Or mount into an existing FastAPI app:
|
|
282
|
+
|
|
283
|
+
```python
|
|
284
|
+
from fastapi import FastAPI
|
|
285
|
+
from openapi_mcp_gateway import Gateway
|
|
286
|
+
|
|
287
|
+
app = FastAPI()
|
|
288
|
+
gateway = Gateway()
|
|
289
|
+
gateway.add_server(name="petstore", spec="petstore.json")
|
|
290
|
+
gateway.mount(app)
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
## License
|
|
294
|
+
|
|
295
|
+
[MIT](LICENSE)
|