openapi-agent-ready 0.1.0__tar.gz → 0.2.1__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 (23) hide show
  1. {openapi_agent_ready-0.1.0 → openapi_agent_ready-0.2.1}/.github/workflows/ci.yml +22 -0
  2. openapi_agent_ready-0.2.1/.github/workflows/publish.yml +47 -0
  3. openapi_agent_ready-0.2.1/CHANGELOG.md +129 -0
  4. {openapi_agent_ready-0.1.0 → openapi_agent_ready-0.2.1}/PKG-INFO +32 -19
  5. {openapi_agent_ready-0.1.0 → openapi_agent_ready-0.2.1}/README.md +24 -18
  6. openapi_agent_ready-0.2.1/openapi.yaml +11890 -0
  7. {openapi_agent_ready-0.1.0 → openapi_agent_ready-0.2.1}/pyproject.toml +9 -2
  8. openapi_agent_ready-0.2.1/src/agent_ready/__init__.py +24 -0
  9. {openapi_agent_ready-0.1.0 → openapi_agent_ready-0.2.1}/src/agent_ready/auditor.py +12 -0
  10. {openapi_agent_ready-0.1.0 → openapi_agent_ready-0.2.1}/src/agent_ready/cli.py +4 -1
  11. openapi_agent_ready-0.2.1/src/agent_ready/mcp_generator.py +243 -0
  12. {openapi_agent_ready-0.1.0 → openapi_agent_ready-0.2.1}/tests/test_audit.py +59 -0
  13. openapi_agent_ready-0.2.1/tests/test_mcp_conformance.py +502 -0
  14. openapi_agent_ready-0.1.0/CHANGELOG.md +0 -38
  15. openapi_agent_ready-0.1.0/src/agent_ready/__init__.py +0 -16
  16. openapi_agent_ready-0.1.0/src/agent_ready/mcp_generator.py +0 -119
  17. {openapi_agent_ready-0.1.0 → openapi_agent_ready-0.2.1}/.gitignore +0 -0
  18. {openapi_agent_ready-0.1.0 → openapi_agent_ready-0.2.1}/CONTRIBUTING.md +0 -0
  19. {openapi_agent_ready-0.1.0 → openapi_agent_ready-0.2.1}/LICENSE +0 -0
  20. {openapi_agent_ready-0.1.0 → openapi_agent_ready-0.2.1}/examples/agent_ready_booking_api.yaml +0 -0
  21. {openapi_agent_ready-0.1.0 → openapi_agent_ready-0.2.1}/examples/sample_booking_api.yaml +0 -0
  22. {openapi_agent_ready-0.1.0 → openapi_agent_ready-0.2.1}/src/agent_ready/report_generator.py +0 -0
  23. {openapi_agent_ready-0.1.0 → openapi_agent_ready-0.2.1}/src/agent_ready/rubric.py +0 -0
@@ -33,6 +33,28 @@ jobs:
33
33
  - name: Test
34
34
  run: pytest --cov=agent_ready --cov-report=term-missing
35
35
 
36
+ - name: Verify generated MCP scaffold speaks the protocol
37
+ run: |
38
+ # Fail loudly if no usable MCP server class is present — otherwise the
39
+ # conformance tests skip silently and CI goes green on nothing.
40
+ # The class moved in mcp 2.0, so accept either generation.
41
+ python - <<'PY'
42
+ try:
43
+ from mcp.server import MCPServer as S
44
+ except ImportError:
45
+ from mcp.server.fastmcp import FastMCP as S
46
+ print("MCP server class available:", S.__name__)
47
+ PY
48
+ agent-ready examples/agent_ready_booking_api.yaml --generate-mcp /tmp/server.py --quiet
49
+ python /tmp/server.py < /dev/null || true
50
+ # Defence in depth: a skipped conformance suite is a silent pass, which
51
+ # is the exact failure this step exists to prevent.
52
+ pytest tests/test_mcp_conformance.py -v -rs | tee /tmp/conformance.log
53
+ if grep -q "SKIPPED" /tmp/conformance.log; then
54
+ echo "::error::Conformance tests were skipped, not run — treating as failure."
55
+ exit 1
56
+ fi
57
+
36
58
  - name: Smoke-test the CLI
37
59
  run: |
38
60
  agent-ready examples/sample_booking_api.yaml
@@ -0,0 +1,47 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ jobs:
8
+ publish:
9
+ runs-on: ubuntu-latest
10
+ permissions:
11
+ id-token: write # required for trusted publishing
12
+
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+
16
+ - uses: actions/setup-python@v5
17
+ with:
18
+ python-version: "3.12"
19
+
20
+ # Fail in seconds if the tag and the packaged version disagree, rather
21
+ # than after pulling a Docker image, signing artifacts, and being
22
+ # rejected by PyPI. A version number consumed by a failed upload is
23
+ # gone permanently, so this check is worth its five lines.
24
+ - name: Check tag matches package version
25
+ run: |
26
+ TAG="${GITHUB_REF_NAME#v}"
27
+ VERSION=$(python -c "import tomllib; print(tomllib.load(open('pyproject.toml','rb'))['project']['version'])")
28
+ echo "tag=$TAG pyproject=$VERSION"
29
+ if [ "$TAG" != "$VERSION" ]; then
30
+ echo "::error::Tag v$TAG does not match pyproject.toml version $VERSION. Move the tag to a commit with the correct version, then delete and recreate the release."
31
+ exit 1
32
+ fi
33
+
34
+ - name: Build
35
+ run: |
36
+ python -m pip install --upgrade pip build twine
37
+ python -m build
38
+
39
+ # Catches a README that won't render on PyPI and other metadata problems.
40
+ # Unfixable after upload without burning a version number.
41
+ - name: Check metadata
42
+ run: twine check dist/*
43
+
44
+ - name: Show what will be uploaded
45
+ run: ls -la dist/
46
+
47
+ - uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,129 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented here.
4
+ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
5
+
6
+ ## [Unreleased]
7
+
8
+ ## [0.2.1] - 2026-07-31
9
+
10
+ Found by running the published 0.2.0 against Asana's public spec.
11
+
12
+ ### Fixed
13
+ - **Generated scaffolds could contain duplicate arguments and fail to parse.**
14
+ OpenAPI identifies a parameter by name *and* location, and an operation-level
15
+ declaration overrides a path-level one. The extractor concatenated both lists
16
+ without deduplicating, so a spec declaring the same parameter at each level —
17
+ Asana's declares `project_gid` that way — produced a function with two
18
+ identically-named arguments, a Python `SyntaxError`. Parameters declared at
19
+ both levels are now deduplicated with operation-level winning; the same name
20
+ in a different location is still treated as distinct.
21
+ - **`--version` reported a stale hardcoded number.** The CLI printed `0.1.0`
22
+ from a published 0.2.0 install. The version is now read from installed package
23
+ metadata, so `pyproject.toml` is the single source of truth and cannot drift.
24
+
25
+ ## [0.1.0] - 2026-07-28
26
+
27
+ ### Added
28
+ - Seven-category AI-readiness rubric for OpenAPI specs
29
+ - CLI with text, markdown, and JSON output formats
30
+ - CI gate support via `--min-score` and `--max-fails` with documented exit codes
31
+ - Remote spec loading over http(s)
32
+ - Parameter `$ref` resolution and path-level shared parameter inheritance
33
+ - MCP server scaffold generation for endpoints that pass the audit
34
+ - Python API (`load_spec`, `run_audit`)
35
+
36
+ ### Fixed
37
+ - OpenAPI `default` responses now count as error documentation. Previously only
38
+ 4xx/5xx codes were recognised, which failed every endpoint in specs that use
39
+ `default` — including Stripe's entire public API. (Found by auditing Stripe.)
40
+ - Ambiguity findings are capped at the 25 most-similar pairs with a summary
41
+ line, so large catalogues produce a readable report.
42
+ - Usage-guidelines detection is now regex-based; literal matching missed
43
+ phrasings like "use this only when" and "use this only after".
44
+ - CLI exits cleanly when its output is piped to `head` or `less`.
45
+
46
+ ### Added (category 8)
47
+ - **Tool Surface & Schema Strictness** category, derived from OpenAI's
48
+ function-calling guidance: flags catalogues far above the ~20-tool ceiling,
49
+ request bodies incompatible with strict mode (`additionalProperties: false`,
50
+ all properties required), and parameters that imply a fixed value set but
51
+ accept free-form strings where an enum belongs.
52
+ - Findings now carry a `scope` ("endpoint" or "spec"). Spec-level findings are
53
+ weighted at 50% of their category so a single whole-API finding isn't averaged
54
+ away against hundreds of endpoint findings. Stripe's tool-surface score was
55
+ 99/100 before this fix and 49.6/100 after.
56
+
57
+ ### Added
58
+ - **MCP conformance test suite** (`tests/test_mcp_conformance.py`). Launches the
59
+ generated scaffold as a subprocess, completes a real MCP handshake over stdio
60
+ using the official client, and validates the advertised tool definitions:
61
+ name format, uniqueness, description presence, `inputSchema` validity as JSON
62
+ Schema, required-argument correctness, and side-effect disclosure. Previously
63
+ the only check on generated output was that the file compiled.
64
+
65
+ ### Fixed
66
+ - **Request body fields were silently dropped.** The generator read only
67
+ `parameters`, so a `POST` endpoint's payload properties never became tool
68
+ arguments — producing, for example, a create-booking tool with no way to say
69
+ what to book. Syntactically valid and completely uncallable, which is exactly
70
+ the class of bug a compile check cannot catch.
71
+ - **No arguments were marked required.** Every parameter was emitted with a
72
+ `= None` default, so the advertised `inputSchema` had an empty `required`
73
+ array. A model could call an endpoint with a `{path_param}` and omit it,
74
+ producing a malformed URL. Path parameters are now always required, and
75
+ `required: true` from the spec is honoured for query, header, and body fields.
76
+
77
+ ### Fixed
78
+ - **Generated scaffold failed on mcp 2.0.** FastMCP was replaced by `MCPServer`
79
+ in the 2.x SDK, so `from mcp.server.fastmcp import FastMCP` no longer resolved
80
+ and every generated server crashed on import. The scaffold now imports through
81
+ a compatibility shim supporting both generations, verified against mcp 1.28.1
82
+ and 2.0.0.
83
+
84
+ ### Added
85
+ - Generated tools now carry **`ToolAnnotations`** (`readOnlyHint`,
86
+ `destructiveHint`, `idempotentHint`, `openWorldHint`) derived from the HTTP
87
+ method. Prose in a description helps a model reason about side effects;
88
+ annotations let a client *enforce* — auto-approving reads while requiring
89
+ confirmation for writes. camelCase field names are used deliberately, as they
90
+ are accepted by both SDK generations.
91
+
92
+ ### Changed
93
+ - **Generated scaffolds are now self-documenting.** The file header states its
94
+ dependencies (`pip install mcp httpx`), how to run it, a ready-to-paste Claude
95
+ Desktop config block, and three things to fix before shipping — notably that
96
+ the scaffold sends no credentials, so calls against a real API will 401 until
97
+ auth is wired in. Previously someone receiving a generated file out of context
98
+ had no way to know what it needed.
99
+ - **Generated servers are named after their source API** (`spotify-web-api`
100
+ rather than the shared `generated-api-server` placeholder). Two generated
101
+ servers connected to the same client no longer present identical names.
102
+ - **The `[mcp]` extra is now also available as `[server]`,** which describes it
103
+ accurately: these are dependencies the *generated* server needs at runtime,
104
+ not dependencies of the auditor. `[mcp]` is retained as an alias.
105
+
106
+ ### Fixed
107
+ - **Conformance tests silently skipped under mcp 2.0.** The module-level guard
108
+ probed `mcp.server.fastmcp`, which does not exist in the 2.x SDK, so the entire
109
+ suite skipped against a current install — a green build that verified nothing.
110
+ The guard now probes for either server class, and CI fails explicitly if the
111
+ suite skips rather than runs.
112
+
113
+ ### Fixed
114
+ - **Conformance tests failed against mcp 2.0.** The 2.x SDK renamed result
115
+ fields from camelCase to snake_case (`serverInfo` -> `server_info`,
116
+ `inputSchema` -> `input_schema`, `readOnlyHint` -> `read_only_hint`), and the
117
+ tests were pinned to the 1.x spelling. Assertions now read fields through
118
+ version-agnostic accessors. The suite is verified against both mcp 1.28.1 and
119
+ 2.0.0.
120
+ - **Failures inside anyio task groups are now readable.** Exception groups are
121
+ flattened to their leaf causes and `BaseException` is caught rather than
122
+ `Exception`, so a `BaseExceptionGroup` no longer escapes the diagnostic
123
+ wrapper and leaves the real error truncated. This is what finally surfaced
124
+ the rename above.
125
+
126
+ ### Changed
127
+ - Tool listings are fetched once per generated file and cached rather than
128
+ spawning a server subprocess per test, cutting spawns from ~14 to 4 and
129
+ running roughly a third faster.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: openapi-agent-ready
3
- Version: 0.1.0
3
+ Version: 0.2.1
4
4
  Summary: Audit any OpenAPI spec for AI-agent and MCP readiness, and generate an MCP server scaffold.
5
5
  Project-URL: Homepage, https://github.com/sfaisal/agent-ready
6
6
  Project-URL: Issues, https://github.com/sfaisal/agent-ready/issues
@@ -38,12 +38,19 @@ Classifier: Topic :: Software Development :: Quality Assurance
38
38
  Requires-Python: >=3.10
39
39
  Requires-Dist: pyyaml>=6.0
40
40
  Provides-Extra: dev
41
+ Requires-Dist: httpx>=0.27; extra == 'dev'
42
+ Requires-Dist: jsonschema>=4.0; extra == 'dev'
43
+ Requires-Dist: mcp>=1.0; extra == 'dev'
44
+ Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
41
45
  Requires-Dist: pytest-cov>=4.0; extra == 'dev'
42
46
  Requires-Dist: pytest>=7.0; extra == 'dev'
43
47
  Requires-Dist: ruff>=0.4; extra == 'dev'
44
48
  Provides-Extra: mcp
45
49
  Requires-Dist: httpx>=0.27; extra == 'mcp'
46
50
  Requires-Dist: mcp>=1.0; extra == 'mcp'
51
+ Provides-Extra: server
52
+ Requires-Dist: httpx>=0.27; extra == 'server'
53
+ Requires-Dist: mcp>=1.0; extra == 'server'
47
54
  Description-Content-Type: text/markdown
48
55
 
49
56
  # agent-ready
@@ -62,23 +69,24 @@ agent-specific failure, tells you exactly which endpoints will cause trouble and
62
69
  why, and can gate a CI pipeline so specs don't regress.
63
70
 
64
71
  ```bash
65
- pip install agent-ready
72
+ pip install openapi-agent-ready
66
73
  agent-ready https://example.com/openapi.yaml
67
74
  ```
68
75
 
69
76
  ```
70
77
  Generic Booking Platform API (v1.0)
71
- AI-readiness score: 54.4/100
72
- Endpoints: 4 Fails: 6 Warnings: 12
78
+ AI-readiness score: 58.4/100
79
+ Endpoints: 4 Fails: 7 Warnings: 14
73
80
 
74
81
  Category scores:
75
- Description Clarity 37.5/100
76
- Side Effects 70.0/100
77
- Error Responses 62.5/100
78
- Auth Clarity 50.0/100
79
- Ambiguity 100.0/100
80
- Parameter Explanation 16.7/100
81
- Usage Guidelines 50.0/100
82
+ Description Clarity 37.5/100
83
+ Side Effects 70.0/100
84
+ Error Responses 62.5/100
85
+ Auth Clarity 50.0/100
86
+ Ambiguity 100.0/100
87
+ Parameter Explanation 10.0/100
88
+ Usage Guidelines 50.0/100
89
+ Tool Surface 100.0/100
82
90
  ```
83
91
 
84
92
  ## Why this exists
@@ -119,8 +127,8 @@ agent failures in production.
119
127
  ## Install
120
128
 
121
129
  ```bash
122
- pip install openapi-agent-ready # core
123
- pip install "openapi-agent-ready[mcp]" # + MCP scaffold generation
130
+ pip install openapi-agent-ready # core
131
+ pip install "openapi-agent-ready[server]" # + MCP scaffold generation
124
132
  ```
125
133
 
126
134
  From source:
@@ -158,7 +166,7 @@ regress when someone adds an endpoint:
158
166
  ```yaml
159
167
  - name: Check API is agent-ready
160
168
  run: |
161
- pip install agent-ready
169
+ pip install openapi-agent-ready
162
170
  agent-ready openapi.yaml --min-score 60 --max-fails 0
163
171
  ```
164
172
 
@@ -177,12 +185,16 @@ Exit codes:
177
185
 
178
186
  ## Real-world results
179
187
 
180
- Running it against Stripe's production spec (587 endpoints):
188
+ Running it against Stripe's production spec (587 endpoints), as of v0.1.0.
189
+ These figures move whenever the rubric changes — rerun the tool for current
190
+ numbers:
181
191
 
182
192
  ```
183
193
  Stripe API (v2026-06-24.dahlia)
184
- AI-readiness score: 62.9/100
194
+ AI-readiness score: 61.3/100
195
+ Endpoints: 587 Fails: 393 Warnings: 2133
185
196
 
197
+ Category scores:
186
198
  Description Clarity 68.3/100
187
199
  Side Effects 64.7/100
188
200
  Error Responses 100.0/100
@@ -190,6 +202,7 @@ AI-readiness score: 62.9/100
190
202
  Ambiguity 50.0/100
191
203
  Parameter Explanation 43.0/100
192
204
  Usage Guidelines 51.2/100
205
+ Tool Surface 49.6/100
193
206
  ```
194
207
 
195
208
  Two things worth drawing out.
@@ -198,11 +211,11 @@ Two things worth drawing out.
198
211
  in this tool, not in Stripe.** Stripe documents errors via OpenAPI's `default`
199
212
  response rather than enumerating explicit 4xx/5xx codes. Perfectly valid, and
200
213
  arguably cleaner. The check only looked for `4`/`5` prefixes, so it failed all
201
- 587 endpoints. Fixed, regression-tested, and the reason the README says to run
202
- this against a real spec before trusting it.
214
+ 587 endpoints. Fixed, regression-tested, and the reason this README says to run it against a
215
+ real spec before trusting it.
203
216
 
204
217
  **Stripe is widely and correctly regarded as agent-ready, yet its raw OpenAPI
205
- spec scores 62.9.** That isn't a contradiction — it's the whole point. Stripe's
218
+ spec scores 61.3.** That isn't a contradiction — it's the whole point. Stripe's
206
219
  agent-readiness comes from the *Agent Toolkit* layered on top: curated tool
207
220
  definitions, an MCP server, managed OAuth. The raw spec is the input to that
208
221
  layer, not the layer itself. Which is exactly why this tool ships with
@@ -14,23 +14,24 @@ agent-specific failure, tells you exactly which endpoints will cause trouble and
14
14
  why, and can gate a CI pipeline so specs don't regress.
15
15
 
16
16
  ```bash
17
- pip install agent-ready
17
+ pip install openapi-agent-ready
18
18
  agent-ready https://example.com/openapi.yaml
19
19
  ```
20
20
 
21
21
  ```
22
22
  Generic Booking Platform API (v1.0)
23
- AI-readiness score: 54.4/100
24
- Endpoints: 4 Fails: 6 Warnings: 12
23
+ AI-readiness score: 58.4/100
24
+ Endpoints: 4 Fails: 7 Warnings: 14
25
25
 
26
26
  Category scores:
27
- Description Clarity 37.5/100
28
- Side Effects 70.0/100
29
- Error Responses 62.5/100
30
- Auth Clarity 50.0/100
31
- Ambiguity 100.0/100
32
- Parameter Explanation 16.7/100
33
- Usage Guidelines 50.0/100
27
+ Description Clarity 37.5/100
28
+ Side Effects 70.0/100
29
+ Error Responses 62.5/100
30
+ Auth Clarity 50.0/100
31
+ Ambiguity 100.0/100
32
+ Parameter Explanation 10.0/100
33
+ Usage Guidelines 50.0/100
34
+ Tool Surface 100.0/100
34
35
  ```
35
36
 
36
37
  ## Why this exists
@@ -71,8 +72,8 @@ agent failures in production.
71
72
  ## Install
72
73
 
73
74
  ```bash
74
- pip install openapi-agent-ready # core
75
- pip install "openapi-agent-ready[mcp]" # + MCP scaffold generation
75
+ pip install openapi-agent-ready # core
76
+ pip install "openapi-agent-ready[server]" # + MCP scaffold generation
76
77
  ```
77
78
 
78
79
  From source:
@@ -110,7 +111,7 @@ regress when someone adds an endpoint:
110
111
  ```yaml
111
112
  - name: Check API is agent-ready
112
113
  run: |
113
- pip install agent-ready
114
+ pip install openapi-agent-ready
114
115
  agent-ready openapi.yaml --min-score 60 --max-fails 0
115
116
  ```
116
117
 
@@ -129,12 +130,16 @@ Exit codes:
129
130
 
130
131
  ## Real-world results
131
132
 
132
- Running it against Stripe's production spec (587 endpoints):
133
+ Running it against Stripe's production spec (587 endpoints), as of v0.1.0.
134
+ These figures move whenever the rubric changes — rerun the tool for current
135
+ numbers:
133
136
 
134
137
  ```
135
138
  Stripe API (v2026-06-24.dahlia)
136
- AI-readiness score: 62.9/100
139
+ AI-readiness score: 61.3/100
140
+ Endpoints: 587 Fails: 393 Warnings: 2133
137
141
 
142
+ Category scores:
138
143
  Description Clarity 68.3/100
139
144
  Side Effects 64.7/100
140
145
  Error Responses 100.0/100
@@ -142,6 +147,7 @@ AI-readiness score: 62.9/100
142
147
  Ambiguity 50.0/100
143
148
  Parameter Explanation 43.0/100
144
149
  Usage Guidelines 51.2/100
150
+ Tool Surface 49.6/100
145
151
  ```
146
152
 
147
153
  Two things worth drawing out.
@@ -150,11 +156,11 @@ Two things worth drawing out.
150
156
  in this tool, not in Stripe.** Stripe documents errors via OpenAPI's `default`
151
157
  response rather than enumerating explicit 4xx/5xx codes. Perfectly valid, and
152
158
  arguably cleaner. The check only looked for `4`/`5` prefixes, so it failed all
153
- 587 endpoints. Fixed, regression-tested, and the reason the README says to run
154
- this against a real spec before trusting it.
159
+ 587 endpoints. Fixed, regression-tested, and the reason this README says to run it against a
160
+ real spec before trusting it.
155
161
 
156
162
  **Stripe is widely and correctly regarded as agent-ready, yet its raw OpenAPI
157
- spec scores 62.9.** That isn't a contradiction — it's the whole point. Stripe's
163
+ spec scores 61.3.** That isn't a contradiction — it's the whole point. Stripe's
158
164
  agent-readiness comes from the *Agent Toolkit* layered on top: curated tool
159
165
  definitions, an MCP server, managed OAuth. The raw spec is the input to that
160
166
  layer, not the layer itself. Which is exactly why this tool ships with