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.
Files changed (47) hide show
  1. openapi_mcp_gateway-0.1.0/.github/release.yml +24 -0
  2. openapi_mcp_gateway-0.1.0/.github/workflows/ci.yml +62 -0
  3. openapi_mcp_gateway-0.1.0/.github/workflows/release.yml +83 -0
  4. openapi_mcp_gateway-0.1.0/.gitignore +26 -0
  5. openapi_mcp_gateway-0.1.0/LICENSE +21 -0
  6. openapi_mcp_gateway-0.1.0/PKG-INFO +295 -0
  7. openapi_mcp_gateway-0.1.0/README.md +255 -0
  8. openapi_mcp_gateway-0.1.0/examples/asana.yml +28 -0
  9. openapi_mcp_gateway-0.1.0/examples/github.yml +19 -0
  10. openapi_mcp_gateway-0.1.0/examples/multi-server.yml +56 -0
  11. openapi_mcp_gateway-0.1.0/examples/petstore.yml +10 -0
  12. openapi_mcp_gateway-0.1.0/pyproject.toml +125 -0
  13. openapi_mcp_gateway-0.1.0/src/openapi_mcp_gateway/__init__.py +15 -0
  14. openapi_mcp_gateway-0.1.0/src/openapi_mcp_gateway/auth/__init__.py +15 -0
  15. openapi_mcp_gateway-0.1.0/src/openapi_mcp_gateway/auth/detector.py +64 -0
  16. openapi_mcp_gateway-0.1.0/src/openapi_mcp_gateway/auth/provider.py +412 -0
  17. openapi_mcp_gateway-0.1.0/src/openapi_mcp_gateway/auth/resolver.py +51 -0
  18. openapi_mcp_gateway-0.1.0/src/openapi_mcp_gateway/cli.py +289 -0
  19. openapi_mcp_gateway-0.1.0/src/openapi_mcp_gateway/client.py +98 -0
  20. openapi_mcp_gateway-0.1.0/src/openapi_mcp_gateway/gateway.py +477 -0
  21. openapi_mcp_gateway-0.1.0/src/openapi_mcp_gateway/generator.py +206 -0
  22. openapi_mcp_gateway-0.1.0/src/openapi_mcp_gateway/logger.py +111 -0
  23. openapi_mcp_gateway-0.1.0/src/openapi_mcp_gateway/openapi.py +260 -0
  24. openapi_mcp_gateway-0.1.0/src/openapi_mcp_gateway/policy.py +51 -0
  25. openapi_mcp_gateway-0.1.0/src/openapi_mcp_gateway/settings.py +193 -0
  26. openapi_mcp_gateway-0.1.0/src/openapi_mcp_gateway/stores/__init__.py +28 -0
  27. openapi_mcp_gateway-0.1.0/src/openapi_mcp_gateway/stores/base.py +58 -0
  28. openapi_mcp_gateway-0.1.0/src/openapi_mcp_gateway/stores/memory.py +56 -0
  29. openapi_mcp_gateway-0.1.0/src/openapi_mcp_gateway/stores/redis.py +62 -0
  30. openapi_mcp_gateway-0.1.0/tests/__init__.py +0 -0
  31. openapi_mcp_gateway-0.1.0/tests/conftest.py +46 -0
  32. openapi_mcp_gateway-0.1.0/tests/fixtures/petstore.json +256 -0
  33. openapi_mcp_gateway-0.1.0/tests/fixtures/petstore.yml +152 -0
  34. openapi_mcp_gateway-0.1.0/tests/integration/__init__.py +0 -0
  35. openapi_mcp_gateway-0.1.0/tests/integration/test_gateway.py +145 -0
  36. openapi_mcp_gateway-0.1.0/tests/integration/test_oauth_flow.py +183 -0
  37. openapi_mcp_gateway-0.1.0/tests/unit/__init__.py +0 -0
  38. openapi_mcp_gateway-0.1.0/tests/unit/test_cli.py +85 -0
  39. openapi_mcp_gateway-0.1.0/tests/unit/test_client.py +72 -0
  40. openapi_mcp_gateway-0.1.0/tests/unit/test_generator.py +137 -0
  41. openapi_mcp_gateway-0.1.0/tests/unit/test_logger.py +112 -0
  42. openapi_mcp_gateway-0.1.0/tests/unit/test_openapi.py +244 -0
  43. openapi_mcp_gateway-0.1.0/tests/unit/test_policy.py +93 -0
  44. openapi_mcp_gateway-0.1.0/tests/unit/test_resolver.py +51 -0
  45. openapi_mcp_gateway-0.1.0/tests/unit/test_settings.py +155 -0
  46. openapi_mcp_gateway-0.1.0/tests/unit/test_stores.py +120 -0
  47. 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
+ [![CI](https://github.com/mroops0111/openapi-mcp-gateway/actions/workflows/ci.yml/badge.svg)](https://github.com/mroops0111/openapi-mcp-gateway/actions/workflows/ci.yml)
44
+ [![PyPI version](https://img.shields.io/pypi/v/openapi-mcp-gateway.svg)](https://pypi.org/project/openapi-mcp-gateway/)
45
+ [![Python Version](https://img.shields.io/pypi/pyversions/openapi-mcp-gateway.svg)](https://pypi.org/project/openapi-mcp-gateway/)
46
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](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)