openapi-agent-ready 0.1.0__py3-none-any.whl
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.
- agent_ready/__init__.py +16 -0
- agent_ready/auditor.py +208 -0
- agent_ready/cli.py +175 -0
- agent_ready/mcp_generator.py +119 -0
- agent_ready/report_generator.py +93 -0
- agent_ready/rubric.py +511 -0
- openapi_agent_ready-0.1.0.dist-info/METADATA +326 -0
- openapi_agent_ready-0.1.0.dist-info/RECORD +11 -0
- openapi_agent_ready-0.1.0.dist-info/WHEEL +4 -0
- openapi_agent_ready-0.1.0.dist-info/entry_points.txt +2 -0
- openapi_agent_ready-0.1.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: openapi-agent-ready
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Audit any OpenAPI spec for AI-agent and MCP readiness, and generate an MCP server scaffold.
|
|
5
|
+
Project-URL: Homepage, https://github.com/sfaisal/agent-ready
|
|
6
|
+
Project-URL: Issues, https://github.com/sfaisal/agent-ready/issues
|
|
7
|
+
Author: Shah Faisal Darwaish
|
|
8
|
+
License: MIT License
|
|
9
|
+
|
|
10
|
+
Copyright (c) 2026 Shah Faisal Darwaish
|
|
11
|
+
|
|
12
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
13
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
14
|
+
in the Software without restriction, including without limitation the rights
|
|
15
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
16
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
17
|
+
furnished to do so, subject to the following conditions:
|
|
18
|
+
|
|
19
|
+
The above copyright notice and this permission notice shall be included in all
|
|
20
|
+
copies or substantial portions of the Software.
|
|
21
|
+
|
|
22
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
23
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
24
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
25
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
26
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
27
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
28
|
+
SOFTWARE.
|
|
29
|
+
License-File: LICENSE
|
|
30
|
+
Keywords: ai-agents,api-design,llm,mcp,model-context-protocol,openapi
|
|
31
|
+
Classifier: Development Status :: 3 - Alpha
|
|
32
|
+
Classifier: Intended Audience :: Developers
|
|
33
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
34
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
35
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
36
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
37
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
38
|
+
Requires-Python: >=3.10
|
|
39
|
+
Requires-Dist: pyyaml>=6.0
|
|
40
|
+
Provides-Extra: dev
|
|
41
|
+
Requires-Dist: pytest-cov>=4.0; extra == 'dev'
|
|
42
|
+
Requires-Dist: pytest>=7.0; extra == 'dev'
|
|
43
|
+
Requires-Dist: ruff>=0.4; extra == 'dev'
|
|
44
|
+
Provides-Extra: mcp
|
|
45
|
+
Requires-Dist: httpx>=0.27; extra == 'mcp'
|
|
46
|
+
Requires-Dist: mcp>=1.0; extra == 'mcp'
|
|
47
|
+
Description-Content-Type: text/markdown
|
|
48
|
+
|
|
49
|
+
# agent-ready
|
|
50
|
+
|
|
51
|
+
> The practical implementation of [*The Silent Revolution: How AI Agents Are Rewriting the Rules of API Growth*](https://medium.com/@shahfaisaldarwaish/the-silent-revolution-how-ai-agents-are-rewriting-the-rules-of-api-growth-1bef8e3e0e80) — turning "audit your agent readiness" from advice into a command you can run.
|
|
52
|
+
|
|
53
|
+
[](https://github.com/sfaisal/agent-ready/actions/workflows/ci.yml)
|
|
54
|
+
[](https://www.python.org/downloads/)
|
|
55
|
+
[](LICENSE)
|
|
56
|
+
|
|
57
|
+
**Audit any OpenAPI spec for AI-agent readiness — then generate an MCP server scaffold for the endpoints that pass.**
|
|
58
|
+
|
|
59
|
+
Your API works fine for human developers. That doesn't mean an AI agent can use
|
|
60
|
+
it reliably. `agent-ready` scores a spec against seven categories of
|
|
61
|
+
agent-specific failure, tells you exactly which endpoints will cause trouble and
|
|
62
|
+
why, and can gate a CI pipeline so specs don't regress.
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
pip install agent-ready
|
|
66
|
+
agent-ready https://example.com/openapi.yaml
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
Generic Booking Platform API (v1.0)
|
|
71
|
+
AI-readiness score: 54.4/100
|
|
72
|
+
Endpoints: 4 Fails: 6 Warnings: 12
|
|
73
|
+
|
|
74
|
+
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
|
+
```
|
|
83
|
+
|
|
84
|
+
## Why this exists
|
|
85
|
+
|
|
86
|
+
A human developer who hits a vague `404` shrugs and checks the docs. An agent
|
|
87
|
+
dead-ends. A human who sees two similar endpoints picks the right one from
|
|
88
|
+
context. An agent picks whichever description sounds closer.
|
|
89
|
+
|
|
90
|
+
This tool is the practical implementation of an argument I made in
|
|
91
|
+
[**The Silent Revolution: How AI Agents Are Rewriting the Rules of API
|
|
92
|
+
Growth**](https://medium.com/@shahfaisaldarwaish/the-silent-revolution-how-ai-agents-are-rewriting-the-rules-of-api-growth-1bef8e3e0e80).
|
|
93
|
+
That article's first recommendation was to *audit your agent readiness — check
|
|
94
|
+
OpenAPI spec completeness, authentication friction, and error message
|
|
95
|
+
machine-readability, and score yourself honestly.* This is that audit, made
|
|
96
|
+
runnable.
|
|
97
|
+
|
|
98
|
+
The three characteristics of an agent-ready API identified in the article map
|
|
99
|
+
directly onto the rubric:
|
|
100
|
+
|
|
101
|
+
| Article | Rubric categories |
|
|
102
|
+
|---|---|
|
|
103
|
+
| **Machine-readable schemas** | 1 (description clarity), 6 (parameters), 7 (usage guidelines) |
|
|
104
|
+
| **Frictionless authentication** | 4 (auth/scope clarity) |
|
|
105
|
+
| **Structured error handling** | 3 (actionable errors) |
|
|
106
|
+
|
|
107
|
+
Categories 2 (side effects) and 5 (ambiguity) were added during implementation
|
|
108
|
+
— they turned out to matter as much as the original three, which is the usual
|
|
109
|
+
reward for actually building the thing you wrote about.
|
|
110
|
+
|
|
111
|
+
The gap is measurable, and enormous. A 2026 study of 856 tools across 103 MCP
|
|
112
|
+
servers found that **97.1% of tool descriptions contained at least one quality
|
|
113
|
+
defect**, and **56% failed to state their purpose clearly** — with no
|
|
114
|
+
significant difference between official and community-maintained servers.
|
|
115
|
+
|
|
116
|
+
`agent-ready` catches those defects at the spec level, before they become
|
|
117
|
+
agent failures in production.
|
|
118
|
+
|
|
119
|
+
## Install
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
pip install openapi-agent-ready # core
|
|
123
|
+
pip install "openapi-agent-ready[mcp]" # + MCP scaffold generation
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
From source:
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
git clone https://github.com/sfaisal/agent-ready
|
|
130
|
+
cd agent-ready
|
|
131
|
+
pip install -e ".[dev]"
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Usage
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
# Audit a local spec
|
|
138
|
+
agent-ready openapi.yaml
|
|
139
|
+
|
|
140
|
+
# Audit a remote spec
|
|
141
|
+
agent-ready https://api.example.com/openapi.json
|
|
142
|
+
|
|
143
|
+
# Full markdown report
|
|
144
|
+
agent-ready openapi.yaml --format markdown --out report.md
|
|
145
|
+
|
|
146
|
+
# Machine-readable output
|
|
147
|
+
agent-ready openapi.yaml --format json
|
|
148
|
+
|
|
149
|
+
# Generate an MCP server for the endpoints that pass
|
|
150
|
+
agent-ready openapi.yaml --generate-mcp server.py
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Use it as a CI gate
|
|
154
|
+
|
|
155
|
+
This is the point. Add it to your pipeline so agent-readiness can't silently
|
|
156
|
+
regress when someone adds an endpoint:
|
|
157
|
+
|
|
158
|
+
```yaml
|
|
159
|
+
- name: Check API is agent-ready
|
|
160
|
+
run: |
|
|
161
|
+
pip install agent-ready
|
|
162
|
+
agent-ready openapi.yaml --min-score 60 --max-fails 0
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
`60` is a reasonable starting threshold — below it, an API is likely to lose
|
|
166
|
+
agent-driven integrations to a better-documented competitor. Raise it as you
|
|
167
|
+
close gaps; a spec that scores 60 has real problems, it just doesn't have
|
|
168
|
+
catastrophic ones.
|
|
169
|
+
|
|
170
|
+
Exit codes:
|
|
171
|
+
|
|
172
|
+
| Code | Meaning |
|
|
173
|
+
|---|---|
|
|
174
|
+
| `0` | All configured gates passed |
|
|
175
|
+
| `1` | A gate failed (`--min-score` / `--max-fails`) |
|
|
176
|
+
| `2` | The spec could not be loaded or parsed |
|
|
177
|
+
|
|
178
|
+
## Real-world results
|
|
179
|
+
|
|
180
|
+
Running it against Stripe's production spec (587 endpoints):
|
|
181
|
+
|
|
182
|
+
```
|
|
183
|
+
Stripe API (v2026-06-24.dahlia)
|
|
184
|
+
AI-readiness score: 62.9/100
|
|
185
|
+
|
|
186
|
+
Description Clarity 68.3/100
|
|
187
|
+
Side Effects 64.7/100
|
|
188
|
+
Error Responses 100.0/100
|
|
189
|
+
Auth Clarity 50.0/100
|
|
190
|
+
Ambiguity 50.0/100
|
|
191
|
+
Parameter Explanation 43.0/100
|
|
192
|
+
Usage Guidelines 51.2/100
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
Two things worth drawing out.
|
|
196
|
+
|
|
197
|
+
**The first run scored 47.9 with error handling at 0/100 — and that was a bug
|
|
198
|
+
in this tool, not in Stripe.** Stripe documents errors via OpenAPI's `default`
|
|
199
|
+
response rather than enumerating explicit 4xx/5xx codes. Perfectly valid, and
|
|
200
|
+
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.
|
|
203
|
+
|
|
204
|
+
**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
|
|
206
|
+
agent-readiness comes from the *Agent Toolkit* layered on top: curated tool
|
|
207
|
+
definitions, an MCP server, managed OAuth. The raw spec is the input to that
|
|
208
|
+
layer, not the layer itself. Which is exactly why this tool ships with
|
|
209
|
+
`--generate-mcp`: the audit tells you what to fix, and the scaffold is where the
|
|
210
|
+
curation happens.
|
|
211
|
+
|
|
212
|
+
Genuine findings that survived scrutiny: `GET /v1/account` and
|
|
213
|
+
`GET /v1/accounts/{account}` have **100% identical descriptions**, and the spec
|
|
214
|
+
uses bearer/basic API keys rather than scoped OAuth2, so there's no way to
|
|
215
|
+
express "this agent may only read."
|
|
216
|
+
|
|
217
|
+
### Python API
|
|
218
|
+
|
|
219
|
+
```python
|
|
220
|
+
from agent_ready import load_spec, run_audit
|
|
221
|
+
|
|
222
|
+
spec = load_spec("openapi.yaml")
|
|
223
|
+
result = run_audit(spec)
|
|
224
|
+
|
|
225
|
+
print(result["overall_score"])
|
|
226
|
+
for finding in result["gaps"]:
|
|
227
|
+
print(finding.severity, finding.endpoint, finding.message)
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
## The eight categories
|
|
231
|
+
|
|
232
|
+
| # | Category | What it catches | Published anchor |
|
|
233
|
+
|---|---|---|---|
|
|
234
|
+
| 1 | **Description clarity** | Endpoints a model can't decide whether to call | "Unclear Purpose" smell — 56% prevalence |
|
|
235
|
+
| 2 | **Side-effect signaling** | Write endpoints that don't say they're writes; missing idempotency | MCP tool annotations (destructive / open-world) |
|
|
236
|
+
| 3 | **Actionable errors** | Failures an agent can't recover from | Adjacent to "Limitations" — 89.8% prevalence |
|
|
237
|
+
| 4 | **Auth/scope clarity** | No way to tell delegated from autonomous agent access | *Not covered by existing rubrics* |
|
|
238
|
+
| 5 | **Endpoint ambiguity** | Two endpoints a model could confuse | 73% of servers had repeated tool names |
|
|
239
|
+
| 6 | **Parameter explanation** | Undocumented or format-ambiguous parameters | "Opaque Parameters" — 84.3% prevalence |
|
|
240
|
+
| 7 | **Usage guidelines** | States what it does, but not *when to call it* | "Missing Usage Guidelines" — 89.3% prevalence |
|
|
241
|
+
| 8 | **Tool surface & schema strictness** | Too many tools to select from; schemas incompatible with strict mode | OpenAI function-calling guidance |
|
|
242
|
+
|
|
243
|
+
### A worked example of why category 6 matters
|
|
244
|
+
|
|
245
|
+
From the Hasan et al. paper: a Yahoo Finance MCP tool referred to "start" and
|
|
246
|
+
"end" without naming them as explicit parameters or specifying a date format.
|
|
247
|
+
The model couldn't construct a bounded range, so it fell back to a broad
|
|
248
|
+
`period` parameter and pulled multi-year windows to answer narrow questions —
|
|
249
|
+
inflating payload size, latency, and token cost. As the authors put it, that is
|
|
250
|
+
a specification problem in the description, not a model bug.
|
|
251
|
+
|
|
252
|
+
`agent-ready` flags exactly this: a date-like parameter with no `format`,
|
|
253
|
+
`pattern`, `enum`, or format hint in its description.
|
|
254
|
+
|
|
255
|
+
## Provenance
|
|
256
|
+
|
|
257
|
+
Categories **1–5** were derived independently, from how MCP tool selection
|
|
258
|
+
works plus standard API design principles reframed for a non-human caller.
|
|
259
|
+
Categories **6–7** were added *after* validating the rubric against published
|
|
260
|
+
empirical research:
|
|
261
|
+
|
|
262
|
+
- Hasan, Li, Rajbahadur, Adams & Hassan (Queen's University), *"Model Context
|
|
263
|
+
Protocol (MCP) Tool Descriptions Are Smelly! Towards Improving AI Agent
|
|
264
|
+
Efficiency with Augmented MCP Tool Descriptions"* —
|
|
265
|
+
[arXiv:2602.14878](https://arxiv.org/abs/2602.14878)
|
|
266
|
+
- Wang et al., *"From Docs to Descriptions: Smell-Aware Evaluation of MCP
|
|
267
|
+
Server Descriptions"* — [arXiv:2602.18914](https://arxiv.org/abs/2602.18914)
|
|
268
|
+
- Anthropic, [*Writing effective tools for agents*](https://www.anthropic.com/engineering/writing-tools-for-agents)
|
|
269
|
+
- [OpenAI's function-calling guidance](https://developers.openai.com/api/docs/guides/function-calling)
|
|
270
|
+
— source for category 8. OpenAI recommends keeping the initially-available
|
|
271
|
+
tool count small (they suggest under 20) and notes that function definitions
|
|
272
|
+
count against the model's context limit and are billed as input tokens.
|
|
273
|
+
|
|
274
|
+
## The score is a diagnostic, not a target
|
|
275
|
+
|
|
276
|
+
Hasan et al. also found that enriching *all* description components improved
|
|
277
|
+
task success by a median **5.85 percentage points** — but increased execution
|
|
278
|
+
steps by **67.46%** and *regressed* performance in **16.67%** of cases, because
|
|
279
|
+
richer descriptions consume context window and raise cost. Their ablation study
|
|
280
|
+
found that shorter, targeted descriptions often performed equivalently.
|
|
281
|
+
|
|
282
|
+
**Fix the fails. Don't gold-plate the passes.** The right operating point
|
|
283
|
+
depends on your domain and your model, and choosing it is a product decision
|
|
284
|
+
rather than an engineering one.
|
|
285
|
+
|
|
286
|
+
## Known limitations
|
|
287
|
+
|
|
288
|
+
Named up front, because a tool that hides its weaknesses is worse than one that
|
|
289
|
+
doesn't:
|
|
290
|
+
|
|
291
|
+
- **The ambiguity check uses string similarity**, so it misses endpoints that
|
|
292
|
+
are semantically similar but differently worded. Embedding-based similarity
|
|
293
|
+
would be stronger. ([#1](https://github.com/sfaisal/agent-ready/issues))
|
|
294
|
+
- **Category weights are judgement calls, not measured effect sizes.**
|
|
295
|
+
Description clarity is weighted highest on the prior that wrong tool selection
|
|
296
|
+
is the costliest failure — that prior is untested here.
|
|
297
|
+
- **Static analysis can't catch descriptions that are fluent but wrong.** Only
|
|
298
|
+
running a real agent against the real API catches semantic inaccuracy.
|
|
299
|
+
- **OpenAPI 3.x only.** Swagger 2.0 and AsyncAPI aren't supported yet.
|
|
300
|
+
|
|
301
|
+
## Related writing
|
|
302
|
+
|
|
303
|
+
- [The Silent Revolution: How AI Agents Are Rewriting the Rules of API Growth](https://medium.com/@shahfaisaldarwaish/the-silent-revolution-how-ai-agents-are-rewriting-the-rules-of-api-growth-1bef8e3e0e80)
|
|
304
|
+
— the argument this tool implements: why agent discoverability is displacing
|
|
305
|
+
documentation quality as the competitive moat for API platforms, and what to
|
|
306
|
+
measure instead of DAU and NPS.
|
|
307
|
+
|
|
308
|
+
## Roadmap
|
|
309
|
+
|
|
310
|
+
- [ ] Embedding-based ambiguity detection
|
|
311
|
+
- [ ] Swagger 2.0 support
|
|
312
|
+
- [ ] Pagination and rate-limit documentation checks
|
|
313
|
+
- [ ] LLM-assisted rewriting of flagged descriptions (`--fix`)
|
|
314
|
+
- [ ] Live tool-selection testing against a generated MCP server
|
|
315
|
+
- [ ] GitHub Action wrapper
|
|
316
|
+
- [ ] Baseline mode (`--baseline`) so CI only fails on *new* regressions
|
|
317
|
+
|
|
318
|
+
## Contributing
|
|
319
|
+
|
|
320
|
+
Contributions welcome — see [CONTRIBUTING.md](CONTRIBUTING.md). New rubric
|
|
321
|
+
categories should come with a rationale for why the gap causes agent-specific
|
|
322
|
+
failure, ideally with a citation or a reproducible example.
|
|
323
|
+
|
|
324
|
+
## License
|
|
325
|
+
|
|
326
|
+
MIT — see [LICENSE](LICENSE).
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
agent_ready/__init__.py,sha256=CqmpijvyUn7dqntWHtxHrAgJK2hXsOc38notHMZUPB4,385
|
|
2
|
+
agent_ready/auditor.py,sha256=O97tfZKHdhlRlNMT021mGR_n2Rnpq1B2vzwuxJn_16k,7435
|
|
3
|
+
agent_ready/cli.py,sha256=W7sM0Zh6gX5LoccxokGQu1uUKAO-sgU5yksOsxQwFXg,5437
|
|
4
|
+
agent_ready/mcp_generator.py,sha256=AUB1euo1Sn1p66D_NA_HEiPhXGanr0MwCZHZ7xQUFtQ,4633
|
|
5
|
+
agent_ready/report_generator.py,sha256=cAMMuKBS8JT2-E8qwe6PeiprAgGx2ORbgzHow1lIqjU,4075
|
|
6
|
+
agent_ready/rubric.py,sha256=T9Yub81L9nqM9Uh7RL46b70QqdKbclIJZwQv5QU0DI4,21549
|
|
7
|
+
openapi_agent_ready-0.1.0.dist-info/METADATA,sha256=dXjiTwJzY3q_dGmF0rJQvh4tE5JjCaQGmE665-1iTcg,14329
|
|
8
|
+
openapi_agent_ready-0.1.0.dist-info/WHEEL,sha256=lCkmxWfQsSc9CfIClYeavTdQeEX2toPqufh9gI35EQA,87
|
|
9
|
+
openapi_agent_ready-0.1.0.dist-info/entry_points.txt,sha256=bE5EkM8ddKPqdm4QUYMDGtK6vMJr40XzeiUJSCFNDYo,53
|
|
10
|
+
openapi_agent_ready-0.1.0.dist-info/licenses/LICENSE,sha256=T94jHloVOq8AA5rMQA7wPNhqyPp1NYgRhCviREhs4TQ,1077
|
|
11
|
+
openapi_agent_ready-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Shah Faisal Darwaish
|
|
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.
|