mcp-openapi-proxy 0.3.0__tar.gz → 0.3.2__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.
- {mcp_openapi_proxy-0.3.0 → mcp_openapi_proxy-0.3.2}/PKG-INFO +24 -19
- {mcp_openapi_proxy-0.3.0 → mcp_openapi_proxy-0.3.2}/README.md +23 -18
- {mcp_openapi_proxy-0.3.0 → mcp_openapi_proxy-0.3.2}/mcp_openapi_proxy/server_fastmcp.py +51 -1
- {mcp_openapi_proxy-0.3.0 → mcp_openapi_proxy-0.3.2}/mcp_openapi_proxy.egg-info/PKG-INFO +24 -19
- {mcp_openapi_proxy-0.3.0 → mcp_openapi_proxy-0.3.2}/pyproject.toml +1 -1
- {mcp_openapi_proxy-0.3.0 → mcp_openapi_proxy-0.3.2}/LICENSE +0 -0
- {mcp_openapi_proxy-0.3.0 → mcp_openapi_proxy-0.3.2}/mcp_openapi_proxy/__init__.py +0 -0
- {mcp_openapi_proxy-0.3.0 → mcp_openapi_proxy-0.3.2}/mcp_openapi_proxy/handlers.py +0 -0
- {mcp_openapi_proxy-0.3.0 → mcp_openapi_proxy-0.3.2}/mcp_openapi_proxy/logging_setup.py +0 -0
- {mcp_openapi_proxy-0.3.0 → mcp_openapi_proxy-0.3.2}/mcp_openapi_proxy/openapi.py +0 -0
- {mcp_openapi_proxy-0.3.0 → mcp_openapi_proxy-0.3.2}/mcp_openapi_proxy/server_lowlevel.py +0 -0
- {mcp_openapi_proxy-0.3.0 → mcp_openapi_proxy-0.3.2}/mcp_openapi_proxy/types.py +0 -0
- {mcp_openapi_proxy-0.3.0 → mcp_openapi_proxy-0.3.2}/mcp_openapi_proxy/utils.py +0 -0
- {mcp_openapi_proxy-0.3.0 → mcp_openapi_proxy-0.3.2}/mcp_openapi_proxy.egg-info/SOURCES.txt +0 -0
- {mcp_openapi_proxy-0.3.0 → mcp_openapi_proxy-0.3.2}/mcp_openapi_proxy.egg-info/dependency_links.txt +0 -0
- {mcp_openapi_proxy-0.3.0 → mcp_openapi_proxy-0.3.2}/mcp_openapi_proxy.egg-info/entry_points.txt +0 -0
- {mcp_openapi_proxy-0.3.0 → mcp_openapi_proxy-0.3.2}/mcp_openapi_proxy.egg-info/requires.txt +0 -0
- {mcp_openapi_proxy-0.3.0 → mcp_openapi_proxy-0.3.2}/mcp_openapi_proxy.egg-info/top_level.txt +0 -0
- {mcp_openapi_proxy-0.3.0 → mcp_openapi_proxy-0.3.2}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mcp-openapi-proxy
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.2
|
|
4
4
|
Summary: MCP server for exposing OpenAPI specifications as MCP tools.
|
|
5
5
|
Author-email: Matthew Hand <11550632+matthewhand@users.noreply.github.com>
|
|
6
6
|
Requires-Python: >=3.10
|
|
@@ -175,27 +175,32 @@ The example configurations below were exercised against the live APIs, and the p
|
|
|
175
175
|
|
|
176
176
|
| Agent CLI | Model used (live test) | MCP attach mechanism | Tool calls | Prompts/Resources surfaced to model? |
|
|
177
177
|
|---|---|---|---|---|
|
|
178
|
-
|
|
|
179
|
-
|
|
|
180
|
-
|
|
|
181
|
-
|
|
|
182
|
-
|
|
|
183
|
-
| Vibe | `mistral-medium-3.5` | `~/.vibe/config.toml` `[[mcp_servers]]` | ✅ discovery + reads
|
|
178
|
+
| **opencode** | (CLI default) | `~/.config/opencode/opencode.json` `mcp` | ✅ native | **prompts: ✅ (slash) · resources: ✅** — most complete ‖ |
|
|
179
|
+
| Codex | `gpt-5-codex` (OpenAI API) | `codex exec -c mcp_servers.*` | ✅ native | prompts: ❌ (no prompt meta-tools) · resources: ✅ (`read_mcp_resource`) ‖ |
|
|
180
|
+
| Kilocode | `kilo-auto/free` | global `settings/mcp_settings.json` | ✅ native | prompts: ❌ (no prompt mechanism) · resources: ✅ (`access_mcp_resource`) ‖ |
|
|
181
|
+
| Qwen | `agent` group via local LiteLLM gateway | project `.qwen/settings.json` | ✅ native (live invoke auth-blocked) | prompts: ✅ (slash `/summarize_spec`) · resources: ❌ (no client support) ‖ |
|
|
182
|
+
| Gemini | Google OAuth free tier (CLI default model) | project `.gemini/settings.json` `mcpServers` | ✅ native | prompts: interactive slash only · resources: interactive `@` only (neither reaches the model headless) ‖ |
|
|
183
|
+
| Vibe | `mistral-medium-3.5` | `~/.vibe/config.toml` `[[mcp_servers]]` | ✅ discovery + reads | prompts: ❌ · resources: ❌ (tools-only client) ‖ |
|
|
184
184
|
| agy | — | — | ❌ headless cannot enable MCP | n/a |
|
|
185
|
-
| letta cloud | Letta Cloud
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
>
|
|
189
|
-
>
|
|
190
|
-
> were set — they defaulted OFF.** Per the MCP spec a client won't call
|
|
191
|
-
> `prompts/list`/`resources/list` unless the capability is advertised, so those early
|
|
192
|
-
> results measured the *server's* default, not the clients. **All prior prompt/resource
|
|
193
|
-
> findings are therefore voided.** This release defaults advertising **on**.
|
|
185
|
+
| letta (cloud / self-hosted) | Letta Cloud / `PUT /v1/tools/mcp/servers` | streamable-HTTP / stdio | ✅ (per prior sweep) | unknown — needs a running Letta server to test ‡ |
|
|
186
|
+
|
|
187
|
+
> **How to read the prompts/resources column.** MCP has three surfaces — tools, prompts,
|
|
188
|
+
> resources. **mcp-openapi-proxy serves all three, advertised by default since 0.3.0.**
|
|
189
|
+
> Whether they reach the model is up to the *client*, and that varies:
|
|
194
190
|
>
|
|
195
|
-
> -
|
|
196
|
-
>
|
|
191
|
+
> - **‖ re-verified 2026-06-14 against the published 0.3.0 release** with **no** flags set
|
|
192
|
+
> (validating the default-on advertising), driving each **real client binary**.
|
|
193
|
+
> - **Tools** work on every client tested. **Prompts→model**: opencode & Qwen (slash
|
|
194
|
+
> commands); Gemini interactive-only. **Resources→model**: opencode, Codex, Kilocode.
|
|
195
|
+
> **opencode is the only client that surfaces all three.** Vibe is tools-only.
|
|
196
|
+
> - **‡ unknown** — Letta can't be exercised without standing up a Letta server + model;
|
|
197
|
+
> left untested rather than guessed.
|
|
198
|
+
> - Every cell on the proxy side was confirmed via a raw stdio handshake (`initialize`
|
|
199
|
+
> advertises tools+prompts+resources; `prompts/get` and `resources/read` return content).
|
|
200
|
+
> The remaining ❌ are **client-side** gaps, not proxy limitations.
|
|
197
201
|
>
|
|
198
|
-
>
|
|
202
|
+
> *(All pre-0.3.0 prompt/resource findings were voided — they were measured while
|
|
203
|
+
> advertising defaulted off, so they reflected the server default, not the clients.)*
|
|
199
204
|
|
|
200
205
|
Minimal sanitized configs per client (the no-auth Glama spec is used as the smallest working example; substitute your own spec URL and `$YOUR_KEY` as needed):
|
|
201
206
|
|
|
@@ -153,27 +153,32 @@ The example configurations below were exercised against the live APIs, and the p
|
|
|
153
153
|
|
|
154
154
|
| Agent CLI | Model used (live test) | MCP attach mechanism | Tool calls | Prompts/Resources surfaced to model? |
|
|
155
155
|
|---|---|---|---|---|
|
|
156
|
-
|
|
|
157
|
-
|
|
|
158
|
-
|
|
|
159
|
-
|
|
|
160
|
-
|
|
|
161
|
-
| Vibe | `mistral-medium-3.5` | `~/.vibe/config.toml` `[[mcp_servers]]` | ✅ discovery + reads
|
|
156
|
+
| **opencode** | (CLI default) | `~/.config/opencode/opencode.json` `mcp` | ✅ native | **prompts: ✅ (slash) · resources: ✅** — most complete ‖ |
|
|
157
|
+
| Codex | `gpt-5-codex` (OpenAI API) | `codex exec -c mcp_servers.*` | ✅ native | prompts: ❌ (no prompt meta-tools) · resources: ✅ (`read_mcp_resource`) ‖ |
|
|
158
|
+
| Kilocode | `kilo-auto/free` | global `settings/mcp_settings.json` | ✅ native | prompts: ❌ (no prompt mechanism) · resources: ✅ (`access_mcp_resource`) ‖ |
|
|
159
|
+
| Qwen | `agent` group via local LiteLLM gateway | project `.qwen/settings.json` | ✅ native (live invoke auth-blocked) | prompts: ✅ (slash `/summarize_spec`) · resources: ❌ (no client support) ‖ |
|
|
160
|
+
| Gemini | Google OAuth free tier (CLI default model) | project `.gemini/settings.json` `mcpServers` | ✅ native | prompts: interactive slash only · resources: interactive `@` only (neither reaches the model headless) ‖ |
|
|
161
|
+
| Vibe | `mistral-medium-3.5` | `~/.vibe/config.toml` `[[mcp_servers]]` | ✅ discovery + reads | prompts: ❌ · resources: ❌ (tools-only client) ‖ |
|
|
162
162
|
| agy | — | — | ❌ headless cannot enable MCP | n/a |
|
|
163
|
-
| letta cloud | Letta Cloud
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
>
|
|
167
|
-
>
|
|
168
|
-
> were set — they defaulted OFF.** Per the MCP spec a client won't call
|
|
169
|
-
> `prompts/list`/`resources/list` unless the capability is advertised, so those early
|
|
170
|
-
> results measured the *server's* default, not the clients. **All prior prompt/resource
|
|
171
|
-
> findings are therefore voided.** This release defaults advertising **on**.
|
|
163
|
+
| letta (cloud / self-hosted) | Letta Cloud / `PUT /v1/tools/mcp/servers` | streamable-HTTP / stdio | ✅ (per prior sweep) | unknown — needs a running Letta server to test ‡ |
|
|
164
|
+
|
|
165
|
+
> **How to read the prompts/resources column.** MCP has three surfaces — tools, prompts,
|
|
166
|
+
> resources. **mcp-openapi-proxy serves all three, advertised by default since 0.3.0.**
|
|
167
|
+
> Whether they reach the model is up to the *client*, and that varies:
|
|
172
168
|
>
|
|
173
|
-
> -
|
|
174
|
-
>
|
|
169
|
+
> - **‖ re-verified 2026-06-14 against the published 0.3.0 release** with **no** flags set
|
|
170
|
+
> (validating the default-on advertising), driving each **real client binary**.
|
|
171
|
+
> - **Tools** work on every client tested. **Prompts→model**: opencode & Qwen (slash
|
|
172
|
+
> commands); Gemini interactive-only. **Resources→model**: opencode, Codex, Kilocode.
|
|
173
|
+
> **opencode is the only client that surfaces all three.** Vibe is tools-only.
|
|
174
|
+
> - **‡ unknown** — Letta can't be exercised without standing up a Letta server + model;
|
|
175
|
+
> left untested rather than guessed.
|
|
176
|
+
> - Every cell on the proxy side was confirmed via a raw stdio handshake (`initialize`
|
|
177
|
+
> advertises tools+prompts+resources; `prompts/get` and `resources/read` return content).
|
|
178
|
+
> The remaining ❌ are **client-side** gaps, not proxy limitations.
|
|
175
179
|
>
|
|
176
|
-
>
|
|
180
|
+
> *(All pre-0.3.0 prompt/resource findings were voided — they were measured while
|
|
181
|
+
> advertising defaulted off, so they reflected the server default, not the clients.)*
|
|
177
182
|
|
|
178
183
|
Minimal sanitized configs per client (the no-auth Glama spec is used as the smallest working example; substitute your own spec URL and `$YOUR_KEY` as needed):
|
|
179
184
|
|
|
@@ -36,6 +36,55 @@ spec = None # Global spec for resources
|
|
|
36
36
|
# callable via call_function.
|
|
37
37
|
_FUNCTION_OPERATIONS: Dict[str, Dict] = {}
|
|
38
38
|
|
|
39
|
+
|
|
40
|
+
# --- Native MCP prompts & resources for FastMCP/simple mode ---
|
|
41
|
+
# Previously simple mode advertised the prompts/resources capabilities (FastMCP
|
|
42
|
+
# does so automatically) but registered none, so prompts/list & resources/list
|
|
43
|
+
# came back EMPTY. Register them natively here for parity with the low-level
|
|
44
|
+
# server (same names/content): prompts summarize_spec + whimsical_blog, and the
|
|
45
|
+
# spec_file resource.
|
|
46
|
+
|
|
47
|
+
def _spec_as_json() -> str:
|
|
48
|
+
"""Serialize the OpenAPI spec for the spec_file resource.
|
|
49
|
+
|
|
50
|
+
Serves the in-memory spec that run_simple_server preloads once; only
|
|
51
|
+
fetches as a lazy fallback. This avoids a live network re-fetch on every
|
|
52
|
+
resources/read, respecting the live-first-once spec lifecycle (#28).
|
|
53
|
+
Uses default=str so YAML datetime example values don't crash serialization.
|
|
54
|
+
"""
|
|
55
|
+
global spec
|
|
56
|
+
if spec is None:
|
|
57
|
+
spec_url = os.environ.get("OPENAPI_SPEC_URL")
|
|
58
|
+
if not spec_url:
|
|
59
|
+
return json.dumps({"error": "OPENAPI_SPEC_URL is not configured"})
|
|
60
|
+
spec = fetch_openapi_spec(spec_url)
|
|
61
|
+
if not spec:
|
|
62
|
+
return json.dumps({"error": "Failed to fetch OpenAPI spec"})
|
|
63
|
+
if isinstance(spec, str):
|
|
64
|
+
return spec
|
|
65
|
+
return json.dumps(spec, indent=2, default=str)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
@mcp.resource("file:///openapi_spec.json", name="spec_file",
|
|
69
|
+
description="The raw OpenAPI specification JSON", mime_type="application/json")
|
|
70
|
+
def _spec_file_resource() -> str:
|
|
71
|
+
"""Serve the configured OpenAPI spec as a native MCP resource."""
|
|
72
|
+
return _spec_as_json()
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
@mcp.prompt(name="summarize_spec", description="Summarizes the OpenAPI specification")
|
|
76
|
+
def _summarize_spec_prompt() -> str:
|
|
77
|
+
return ("This OpenAPI spec defines endpoints, parameters, and responses—a "
|
|
78
|
+
"blueprint for developers to integrate effectively.")
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
@mcp.prompt(name="whimsical_blog", description="A whimsical WordPress blog-post starter inspired by this API")
|
|
82
|
+
def _whimsical_blog_prompt() -> str:
|
|
83
|
+
return ("Once upon a JSON, in a land of tilde keys and sticky semicolons, a pet AI "
|
|
84
|
+
"chatbot discovered it could whisper to WordPress through a magic OpenAPI proxy. "
|
|
85
|
+
"✨ Write the next whimsical chapter.")
|
|
86
|
+
|
|
87
|
+
|
|
39
88
|
@mcp.tool()
|
|
40
89
|
def list_functions(*, env_key: str = "OPENAPI_SPEC_URL") -> str:
|
|
41
90
|
"""Lists available functions derived from the OpenAPI specification."""
|
|
@@ -243,7 +292,8 @@ def call_function(*, function_name: str, parameters: Optional[Dict] = None, env_
|
|
|
243
292
|
spec_local = json.loads(spec_local)
|
|
244
293
|
if spec_local is None:
|
|
245
294
|
return json.dumps({"error": "Failed to fetch OpenAPI spec"})
|
|
246
|
-
|
|
295
|
+
# default=str: YAML datetime example values aren't JSON-serializable
|
|
296
|
+
return json.dumps(spec_local, indent=2, default=str)
|
|
247
297
|
if function_name == "list_prompts":
|
|
248
298
|
return json.dumps([{"name": "summarize_spec", "description": "Summarizes the purpose of the OpenAPI specification", "arguments": []}])
|
|
249
299
|
if function_name == "get_prompt":
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mcp-openapi-proxy
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.2
|
|
4
4
|
Summary: MCP server for exposing OpenAPI specifications as MCP tools.
|
|
5
5
|
Author-email: Matthew Hand <11550632+matthewhand@users.noreply.github.com>
|
|
6
6
|
Requires-Python: >=3.10
|
|
@@ -175,27 +175,32 @@ The example configurations below were exercised against the live APIs, and the p
|
|
|
175
175
|
|
|
176
176
|
| Agent CLI | Model used (live test) | MCP attach mechanism | Tool calls | Prompts/Resources surfaced to model? |
|
|
177
177
|
|---|---|---|---|---|
|
|
178
|
-
|
|
|
179
|
-
|
|
|
180
|
-
|
|
|
181
|
-
|
|
|
182
|
-
|
|
|
183
|
-
| Vibe | `mistral-medium-3.5` | `~/.vibe/config.toml` `[[mcp_servers]]` | ✅ discovery + reads
|
|
178
|
+
| **opencode** | (CLI default) | `~/.config/opencode/opencode.json` `mcp` | ✅ native | **prompts: ✅ (slash) · resources: ✅** — most complete ‖ |
|
|
179
|
+
| Codex | `gpt-5-codex` (OpenAI API) | `codex exec -c mcp_servers.*` | ✅ native | prompts: ❌ (no prompt meta-tools) · resources: ✅ (`read_mcp_resource`) ‖ |
|
|
180
|
+
| Kilocode | `kilo-auto/free` | global `settings/mcp_settings.json` | ✅ native | prompts: ❌ (no prompt mechanism) · resources: ✅ (`access_mcp_resource`) ‖ |
|
|
181
|
+
| Qwen | `agent` group via local LiteLLM gateway | project `.qwen/settings.json` | ✅ native (live invoke auth-blocked) | prompts: ✅ (slash `/summarize_spec`) · resources: ❌ (no client support) ‖ |
|
|
182
|
+
| Gemini | Google OAuth free tier (CLI default model) | project `.gemini/settings.json` `mcpServers` | ✅ native | prompts: interactive slash only · resources: interactive `@` only (neither reaches the model headless) ‖ |
|
|
183
|
+
| Vibe | `mistral-medium-3.5` | `~/.vibe/config.toml` `[[mcp_servers]]` | ✅ discovery + reads | prompts: ❌ · resources: ❌ (tools-only client) ‖ |
|
|
184
184
|
| agy | — | — | ❌ headless cannot enable MCP | n/a |
|
|
185
|
-
| letta cloud | Letta Cloud
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
>
|
|
189
|
-
>
|
|
190
|
-
> were set — they defaulted OFF.** Per the MCP spec a client won't call
|
|
191
|
-
> `prompts/list`/`resources/list` unless the capability is advertised, so those early
|
|
192
|
-
> results measured the *server's* default, not the clients. **All prior prompt/resource
|
|
193
|
-
> findings are therefore voided.** This release defaults advertising **on**.
|
|
185
|
+
| letta (cloud / self-hosted) | Letta Cloud / `PUT /v1/tools/mcp/servers` | streamable-HTTP / stdio | ✅ (per prior sweep) | unknown — needs a running Letta server to test ‡ |
|
|
186
|
+
|
|
187
|
+
> **How to read the prompts/resources column.** MCP has three surfaces — tools, prompts,
|
|
188
|
+
> resources. **mcp-openapi-proxy serves all three, advertised by default since 0.3.0.**
|
|
189
|
+
> Whether they reach the model is up to the *client*, and that varies:
|
|
194
190
|
>
|
|
195
|
-
> -
|
|
196
|
-
>
|
|
191
|
+
> - **‖ re-verified 2026-06-14 against the published 0.3.0 release** with **no** flags set
|
|
192
|
+
> (validating the default-on advertising), driving each **real client binary**.
|
|
193
|
+
> - **Tools** work on every client tested. **Prompts→model**: opencode & Qwen (slash
|
|
194
|
+
> commands); Gemini interactive-only. **Resources→model**: opencode, Codex, Kilocode.
|
|
195
|
+
> **opencode is the only client that surfaces all three.** Vibe is tools-only.
|
|
196
|
+
> - **‡ unknown** — Letta can't be exercised without standing up a Letta server + model;
|
|
197
|
+
> left untested rather than guessed.
|
|
198
|
+
> - Every cell on the proxy side was confirmed via a raw stdio handshake (`initialize`
|
|
199
|
+
> advertises tools+prompts+resources; `prompts/get` and `resources/read` return content).
|
|
200
|
+
> The remaining ❌ are **client-side** gaps, not proxy limitations.
|
|
197
201
|
>
|
|
198
|
-
>
|
|
202
|
+
> *(All pre-0.3.0 prompt/resource findings were voided — they were measured while
|
|
203
|
+
> advertising defaulted off, so they reflected the server default, not the clients.)*
|
|
199
204
|
|
|
200
205
|
Minimal sanitized configs per client (the no-auth Glama spec is used as the smallest working example; substitute your own spec URL and `$YOUR_KEY` as needed):
|
|
201
206
|
|
|
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "mcp-openapi-proxy"
|
|
7
7
|
requires-python = ">=3.10"
|
|
8
|
-
version = "0.3.
|
|
8
|
+
version = "0.3.2"
|
|
9
9
|
description = "MCP server for exposing OpenAPI specifications as MCP tools."
|
|
10
10
|
readme = "README.md"
|
|
11
11
|
authors = [
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mcp_openapi_proxy-0.3.0 → mcp_openapi_proxy-0.3.2}/mcp_openapi_proxy.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{mcp_openapi_proxy-0.3.0 → mcp_openapi_proxy-0.3.2}/mcp_openapi_proxy.egg-info/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|
{mcp_openapi_proxy-0.3.0 → mcp_openapi_proxy-0.3.2}/mcp_openapi_proxy.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|