@frontmcp/plugin-skilled-openapi 1.4.0 → 1.5.0-rc.1

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 (39) hide show
  1. package/README.md +123 -17
  2. package/esm/index.mjs +640 -433
  3. package/esm/package.json +19 -8
  4. package/executor/execute-skill-action.d.ts +44 -0
  5. package/executor/execute-skill-action.d.ts.map +1 -0
  6. package/executor/host-concurrency.d.ts +9 -0
  7. package/executor/host-concurrency.d.ts.map +1 -0
  8. package/executor/openapi-runtime.d.ts.map +1 -1
  9. package/executor/ssrf-guard.d.ts +4 -0
  10. package/executor/ssrf-guard.d.ts.map +1 -1
  11. package/index.d.ts +1 -0
  12. package/index.d.ts.map +1 -1
  13. package/index.js +643 -421
  14. package/package.json +19 -8
  15. package/registry/hidden-op.registry.d.ts +15 -1
  16. package/registry/hidden-op.registry.d.ts.map +1 -1
  17. package/security/authority-guard.d.ts +35 -5
  18. package/security/authority-guard.d.ts.map +1 -1
  19. package/skilled-openapi.plugin.d.ts +41 -2
  20. package/skilled-openapi.plugin.d.ts.map +1 -1
  21. package/skilled-openapi.symbols.d.ts +3 -0
  22. package/skilled-openapi.symbols.d.ts.map +1 -1
  23. package/skilled-openapi.types.d.ts +22 -0
  24. package/skilled-openapi.types.d.ts.map +1 -1
  25. package/sync/bundle-sync.service.d.ts +1 -1
  26. package/sync/bundle-sync.service.d.ts.map +1 -1
  27. package/tools/operation-tool.factory.d.ts +5 -4
  28. package/tools/operation-tool.factory.d.ts.map +1 -1
  29. package/tools/run-workflow.schema.d.ts +28 -0
  30. package/tools/run-workflow.schema.d.ts.map +1 -0
  31. package/tools/run-workflow.tool.d.ts +6 -0
  32. package/tools/run-workflow.tool.d.ts.map +1 -0
  33. package/tools/search-skill.schema.d.ts +5 -1
  34. package/tools/search-skill.schema.d.ts.map +1 -1
  35. package/tools/search-skill.tool.d.ts.map +1 -1
  36. package/tools/execute-action.schema.d.ts +0 -26
  37. package/tools/execute-action.schema.d.ts.map +0 -1
  38. package/tools/execute-action.tool.d.ts +0 -6
  39. package/tools/execute-action.tool.d.ts.map +0 -1
package/README.md CHANGED
@@ -2,39 +2,145 @@
2
2
 
3
3
  > Wrap your REST API as a **skilled MCP server** without rewriting any controllers.
4
4
 
5
- This plugin lets a FrontMCP server consume **signed skill bundles** produced by an external pipeline (typically FrontMCP Cloud, from your customer's OpenAPI spec at CI time) and serve them as MCP **skills**. The MCP client only sees three meta-tools — `search_skill`, `load_skill`, `execute_action` — while the per-operation REST tools stay hidden behind the skill abstraction. This avoids the well-documented "tool overload" problem (Claude reliability degrades past ~20 tools, GPT Actions caps at 30, Cursor at 40) when wrapping a real-world API with hundreds of endpoints.
5
+ This plugin lets a FrontMCP server consume **skill bundles** (a standard OpenAPI spec plus an Overlay, optionally signed) and serve them as MCP **skills**. The MCP client only ever sees three meta-tools — `search_skill`, `load_skill`, `run_workflow` — while the per-operation REST tools stay hidden behind the skill abstraction. `run_workflow` runs a short AgentScript program in a dependency-free enclave sandbox where each `await callTool(actionId, input)` invokes a loaded skill's operation, so one workflow can chain many calls in a single round-trip.
6
+
7
+ This sidesteps the well-documented "tool overload" problem (model reliability degrades past ~20 tools, GPT Actions caps at 30, Cursor at 40) when wrapping a real-world API with hundreds of endpoints.
8
+
9
+ ## Installation
10
+
11
+ ```bash
12
+ npm install @frontmcp/plugin-skilled-openapi
13
+ ```
14
+
15
+ The `run_workflow` meta-tool runs AgentScript in the [`@enclave-vm`](https://www.npmjs.com/package/@enclave-vm/core) sandbox, which is an **optional** peer dependency. Install it to enable workflows (without it, `search_skill`/`load_skill` still work and `run_workflow` returns a clear "sandbox not installed" error):
16
+
17
+ ```bash
18
+ npm install @enclave-vm/core @enclave-vm/ast
19
+ ```
20
+
21
+ ## Usage
22
+
23
+ Register the plugin with `SkilledOpenApiPlugin.init(...)` and point it at a bundle source. The `dev: true` flag bypasses signature verification and allows `http://` upstreams for local iteration — see [Security](https://docs.agentfront.dev/frontmcp/plugins/skilled-openapi/security) before going to production.
24
+
25
+ ```typescript
26
+ import * as path from 'node:path';
27
+ import { FrontMcp, LogLevel } from '@frontmcp/sdk';
28
+ import SkilledOpenApiPlugin from '@frontmcp/plugin-skilled-openapi';
29
+
30
+ @FrontMcp({
31
+ info: { name: 'Skilled-OpenAPI Demo', version: '0.1.0' },
32
+ apps: [],
33
+ plugins: [
34
+ SkilledOpenApiPlugin.init({
35
+ source: { type: 'static', path: path.resolve(__dirname, '../bundle.json'), watch: true },
36
+ // Local iteration only — bypasses signing and allows http:// upstreams.
37
+ dev: true,
38
+ requireSignature: false,
39
+ // Dev/single-tenant credential map (vaultRef -> secret). In production,
40
+ // resolve credentials from @frontmcp/auth's vault instead.
41
+ credentials: { 'billing-token': 'demo-bearer-xyz' },
42
+ }),
43
+ ],
44
+ http: { port: 3010 },
45
+ logging: { level: LogLevel.Info },
46
+ })
47
+ export default class Server {}
48
+ ```
49
+
50
+ With the server running, `tools/list` returns **only** `search_skill`, `load_skill`, `run_workflow`; the bundle's operations are hidden. A workflow then drives them:
51
+
52
+ ```jsonc
53
+ // run_workflow
54
+ { "script": "const inv = await callTool('createInvoice', { customerId: 'cus_1', amount: 4200 }); return inv;" }
55
+ // -> { "success": true, "value": { "id": "inv_1", "status": "open" }, "stats": { "durationMs": 12, "toolCalls": 1, "steps": 3 } }
56
+ ```
57
+
58
+ See the [5-minute quickstart](https://docs.agentfront.dev/frontmcp/plugins/skilled-openapi/quickstart) for an end-to-end run against a mock upstream.
6
59
 
7
60
  ## How it works
8
61
 
9
62
  ```text
10
- OpenAPI spec --(SaaS analyzer, signs)--> spec.yaml + overlay.yaml (signed bundle)
63
+ OpenAPI spec --(analyzer + optional signing)--> bundle (spec + overlay)
11
64
  │
12
65
  ▼
13
66
  FrontMCP server with @frontmcp/plugin-skilled-openapi
14
67
  │
15
68
  ▼
16
- tools/list -> [search_skill, load_skill, execute_action, ...]
17
- skills/* -> curated skills (each carrying instructions + actions[])
18
- execute_action -> ABAC -> input validate -> HTTP -> output validate -> result
69
+ tools/list -> [ search_skill, load_skill, run_workflow ]
70
+ skills/* -> curated skills (each carrying instructions + actions[])
71
+ run_workflow -> enclave sandbox runs AgentScript; per callTool(actionId, input):
72
+ authorize (ABAC) -> validate input -> HTTPS -> validate output -> result
19
73
  ```
20
74
 
75
+ ## Meta-Tools
76
+
77
+ | Tool | Purpose |
78
+ | --- | --- |
79
+ | `search_skill` | Semantic search over the loaded skills; returns matching `skillId`s with scores. The live skill catalog is injected into the tool description so the model can discover what's available. |
80
+ | `load_skill` | Returns a skill's markdown instructions plus its `actions[]` and their JSON Schemas (the `actionId`s a workflow calls). |
81
+ | `run_workflow` | Runs an AgentScript `script` in the enclave sandbox. Each `await callTool(actionId, input)` invokes a loaded operation through the full authorize → validate → HTTPS → validate path; the script's `return` value is surfaced as the result. |
82
+
83
+ ## Features
84
+
85
+ - **Three meta-tools instead of hundreds of endpoints** — keeps the client's tool list small and reliable.
86
+ - **Composable workflows** — one `run_workflow` call can chain multiple operations in a sandboxed AgentScript program.
87
+ - **Multiple bundle sources** — `static` (file), `npm` (pinned package), `saas` (CI-driven, signed, hot-pulled), or `inline`.
88
+ - **Hot reload** — `static`/`saas` sources watch for changes and emit `notifications/skills/list_changed` on an atomic swap.
89
+ - **Hidden operation tools** — per-operation REST tools never reach `tools/list`; they're reachable only via `callTool` inside a workflow.
90
+ - **Defense-in-depth security** — see below.
91
+
92
+ ## Configuration
93
+
94
+ All options are validated by a strict Zod schema (`skilledOpenApiPluginOptionsSchema`).
95
+
96
+ | Option | Type | Default | Description |
97
+ | --- | --- | --- | --- |
98
+ | `source` | `static \| npm \| saas \| inline` | — (required) | Where bundles come from. `{ type: 'static', path, watch? }`, `{ type: 'npm', package }`, `{ type: 'saas', endpoint, ... }`, or `{ type: 'inline', ... }`. |
99
+ | `requireSignature` | `boolean` | `true` | Require a valid bundle signature (RS256/Ed25519 JWT-of-hashes). Opt out only with `dev: true`. |
100
+ | `trustedKeys` | `SignatureKey[]` | `[]` | Public keys trusted to sign bundles. |
101
+ | `dev` | `boolean` | `false` | Local-dev escape hatch: bypasses signing and widens `outbound` to allow `http://`. **Never enable in production.** |
102
+ | `outbound` | `OutboundOptions` | see below | SSRF / egress controls. |
103
+ | `unprotectedOps` | `'allow' \| 'deny'` | `'allow'` | Default-deny policy for operations that declare no required authorities. |
104
+ | `sourceConflictPolicy` | `'static-wins' \| 'last-wins' \| 'reject'` | `'static-wins'` | How to resolve two sources registering the same skill id. |
105
+ | `bundleCacheDir` | `string` | — | Last-good cache directory (only for `source.type === 'saas'`). |
106
+ | `credentials` | `Record<vaultRef, secret>` | — | In-memory credential map for dev / single-tenant. In production resolve via `@frontmcp/auth`'s vault. |
107
+ | `exposeOperationsAsInternalTools` | `boolean` | `true` | Keep operations reachable via `callTool` inside workflows. |
108
+
109
+ `outbound` (SSRF + egress):
110
+
111
+ | Field | Default | Description |
112
+ | --- | --- | --- |
113
+ | `allowPrivateNetworks` | `false` | Allow connections to private/loopback/link-local IPs. |
114
+ | `allowHttp` | `false` | Allow `http://` upstreams (auto-enabled by `dev: true`). |
115
+ | `maxConcurrencyPerHost` | `10` | Per-host concurrency cap. |
116
+ | `defaultTimeoutMs` | `30000` | Per-request timeout. |
117
+ | `defaultMaxResponseBytes` | `262144` | Per-response size cap. |
118
+
119
+ Full reference: [Configuration](https://docs.agentfront.dev/frontmcp/plugins/skilled-openapi/configuration).
120
+
121
+ ## Security model
122
+
123
+ - **Optional bundle signing** (RS256/Ed25519 JWT-of-hashes). `requireSignature: true` is the default; opt out only via explicit `dev: true`.
124
+ - **RFC 8707 Resource Indicators** enforced on every inbound JWT (per the MCP authorization spec), blocking confused-deputy attacks at admission.
125
+ - **Layered SSRF defenses** — URL string check → host allowlist (the operation's single declared service) → post-DNS-resolution IP blocklist (RFC 1918, link-local incl. cloud metadata, loopback, ULA) → DNS-rebinding pin → per-host concurrency cap → optional egress proxy.
126
+ - **Bundle data treated as adversarial** even after signature verification — WHATWG `URL` only, RFC 7230 header validation, no shell-out, no `eval`, strict JSON Schema with `additionalProperties: false`.
127
+ - **Indirect-prompt-injection mitigations** — `run_workflow` runs in a no-host-access sandbox (upstream data reaches the model only via the script's `return`), output-schema validation is mandatory on each action, and responses are size-capped.
128
+
129
+ Details: [Security](https://docs.agentfront.dev/frontmcp/plugins/skilled-openapi/security).
130
+
21
131
  ## Standards alignment
22
132
 
23
- - **OpenAPI Overlay 1.0/1.1** — bundle is a standard OpenAPI spec plus an Overlay layering `x-frontmcp-skill: <id>` annotations on operations. Customers can hand-author overlays in any OpenAPI tool.
24
- - **SEP-2076** (Agent Skills as a First-Class MCP Primitive, working-group draft) — skills surface via the SDK's skills primitive when the MCP client supports it, falling back to meta-tool-only mode otherwise.
133
+ - **OpenAPI Overlay 1.0/1.1** — a bundle is a standard OpenAPI spec plus an Overlay layering `x-frontmcp-skill: <id>` annotations onto operations, so customers can hand-author overlays in any OpenAPI tool.
134
+ - **SEP-2076** (Agent Skills as a First-Class MCP Primitive, working-group draft) — skills surface via the SDK's skills primitive when the client supports it, falling back to meta-tool-only mode otherwise.
25
135
  - **Anthropic Agent Skills format** — skill content is markdown with progressive disclosure.
26
136
 
27
- ## Security model (MUST-HAVE defaults)
137
+ ## Documentation
28
138
 
29
- - **Mandatory bundle signing** (RS256/Ed25519 JWT-of-hashes per OPA's bundle model). `requireSignature: true` is the default; opt-out only via explicit `dev: true`.
30
- - **RFC 8707 Resource Indicators** enforced on every JWT (per the 2026-03-15 MCP authorization spec). Confused-deputy class attacks blocked at admission.
31
- - **SSRF defenses** layered: URL string check → host allowlist → post-DNS-resolution IP blocklist (RFC 1918, link-local incl. AWS/GCP/Azure metadata, loopback, ULA) → DNS-rebinding pin → per-host concurrency cap → optional egress proxy.
32
- - **Bundle data treated as adversarial** even after signature verify (CVE-2025-6514 lesson). WHATWG `URL` only, RFC 7230 header validation, no shell-out, no `eval`, strict JSON Schema with `additionalProperties: false`.
33
- - **Five-gate authorization stack**: bundle signature → inbound JWT (RFC 8707) → per-skill ABAC → credential allowlist → outbound SSRF + circuit breaker.
34
- - **Indirect prompt injection** mitigations: `execute_action` returns a structured envelope; output schema validation is mandatory; response size capped; optional sanitizer hook.
139
+ Full docs: **https://docs.agentfront.dev/frontmcp/plugins/skilled-openapi**
35
140
 
36
- See the OWASP MCP Top 10 (2026) coverage table in the plan document for full mapping.
141
+ - [Overview](https://docs.agentfront.dev/frontmcp/plugins/skilled-openapi/overview) · [Quickstart](https://docs.agentfront.dev/frontmcp/plugins/skilled-openapi/quickstart) · [Sources](https://docs.agentfront.dev/frontmcp/plugins/skilled-openapi/sources) · [Bundle format](https://docs.agentfront.dev/frontmcp/plugins/skilled-openapi/bundle-format)
142
+ - [Configuration](https://docs.agentfront.dev/frontmcp/plugins/skilled-openapi/configuration) · [Meta-tools](https://docs.agentfront.dev/frontmcp/plugins/skilled-openapi/meta-tools) · [Security](https://docs.agentfront.dev/frontmcp/plugins/skilled-openapi/security) · [API reference](https://docs.agentfront.dev/frontmcp/plugins/skilled-openapi/api-reference)
37
143
 
38
- ## Status
144
+ ## License
39
145
 
40
- ⚠️ Under active development for FrontMCP v1.2.0. The wire format and SaaS push API are subject to change while SEP-2076 firms up.
146
+ Apache-2.0