caplets 0.3.0 → 0.5.0
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.
- package/README.md +168 -24
- package/dist/index.js +26060 -244
- package/package.json +3 -1
- package/schemas/caplet.schema.json +511 -2
- package/schemas/caplets-config.schema.json +568 -0
package/README.md
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
# Caplets
|
|
2
2
|
|
|
3
|
-
Caplets is a progressive-disclosure gateway for Model Context Protocol (MCP) servers
|
|
3
|
+
Caplets is a progressive-disclosure gateway for Model Context Protocol (MCP) servers,
|
|
4
|
+
native OpenAPI endpoints, and native GraphQL endpoints.
|
|
4
5
|
|
|
5
|
-
Instead of connecting an MCP client to many downstream servers
|
|
6
|
-
front, Caplets exposes one top-level tool per configured
|
|
7
|
-
capability domain, then asks Caplets to list, search, inspect,
|
|
8
|
-
underlying tools.
|
|
6
|
+
Instead of connecting an MCP client to many downstream servers or HTTP APIs and exposing
|
|
7
|
+
every operation up front, Caplets exposes one top-level tool per configured capability.
|
|
8
|
+
An agent first chooses a capability domain, then asks Caplets to list, search, inspect,
|
|
9
|
+
or call that backend's underlying tools or operations.
|
|
9
10
|
|
|
10
11
|
This keeps the initial MCP tool list small, makes tool selection easier, and avoids
|
|
11
12
|
flattened tool-name collisions across servers.
|
|
@@ -27,13 +28,15 @@ the agent chooses that server and asks to search, list, inspect, or call them.
|
|
|
27
28
|
|
|
28
29
|
## What It Does
|
|
29
30
|
|
|
30
|
-
- Reads downstream MCP server definitions from `~/.caplets/config.json`.
|
|
31
|
-
- Registers one generated MCP tool for each enabled server.
|
|
31
|
+
- Reads downstream MCP server definitions, native OpenAPI endpoint definitions, and native GraphQL endpoint definitions from `~/.caplets/config.json`.
|
|
32
|
+
- Registers one generated MCP tool for each enabled MCP server, OpenAPI endpoint, or GraphQL endpoint.
|
|
32
33
|
- Uses the configured server ID as the generated tool name.
|
|
33
34
|
- Uses the configured `name` and `description` as the capability card shown to agents.
|
|
34
|
-
- Starts downstream servers lazily when an operation needs them.
|
|
35
|
+
- Starts downstream MCP servers and loads OpenAPI specs lazily when an operation needs them.
|
|
35
36
|
- Supports stdio, Streamable HTTP, and legacy HTTP+SSE downstream servers.
|
|
36
|
-
- Lets agents `list_tools`, `search_tools`, `get_tool`, and `call_tool` within one selected
|
|
37
|
+
- Lets agents `list_tools`, `search_tools`, `get_tool`, and `call_tool` within one selected Caplet namespace.
|
|
38
|
+
- Converts OpenAPI operations into MCP-style tool metadata and executes HTTP calls directly.
|
|
39
|
+
- Converts configured GraphQL operations into MCP-style tool metadata, and can auto-generate GraphQL tools from schema root query and mutation fields.
|
|
37
40
|
- Preserves downstream tool results instead of rewriting them into a custom format.
|
|
38
41
|
- Redacts secrets from structured errors.
|
|
39
42
|
- Supports static remote auth and OAuth token storage for remote servers.
|
|
@@ -91,6 +94,30 @@ you want Caplets to expose:
|
|
|
91
94
|
"token": "$env:DOCS_MCP_TOKEN"
|
|
92
95
|
}
|
|
93
96
|
}
|
|
97
|
+
},
|
|
98
|
+
"openapiEndpoints": {
|
|
99
|
+
"users": {
|
|
100
|
+
"name": "Users API",
|
|
101
|
+
"description": "Manage users through the internal HTTP API.",
|
|
102
|
+
"specPath": "./openapi.json",
|
|
103
|
+
"baseUrl": "https://api.example.com",
|
|
104
|
+
"auth": {
|
|
105
|
+
"type": "bearer",
|
|
106
|
+
"token": "$env:USERS_API_TOKEN"
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
"graphqlEndpoints": {
|
|
111
|
+
"catalog": {
|
|
112
|
+
"name": "Catalog GraphQL",
|
|
113
|
+
"description": "Query and update catalog records through GraphQL.",
|
|
114
|
+
"endpointUrl": "https://api.example.com/graphql",
|
|
115
|
+
"introspection": true,
|
|
116
|
+
"auth": {
|
|
117
|
+
"type": "oidc",
|
|
118
|
+
"issuer": "https://login.example.com"
|
|
119
|
+
}
|
|
120
|
+
}
|
|
94
121
|
}
|
|
95
122
|
}
|
|
96
123
|
```
|
|
@@ -112,8 +139,9 @@ the committed schema stays in sync with the Zod config validator.
|
|
|
112
139
|
### Caplet Files
|
|
113
140
|
|
|
114
141
|
For richer skill-like cards, add Markdown Caplet files beside `config.json`. Every Caplet
|
|
115
|
-
file must include
|
|
116
|
-
|
|
142
|
+
file must include exactly one executable backend: `mcpServer`, `openapiEndpoint`, or
|
|
143
|
+
`graphqlEndpoint`;
|
|
144
|
+
serverless Caplets are intentionally out of scope.
|
|
117
145
|
|
|
118
146
|
Top-level files derive the Caplet ID from the filename:
|
|
119
147
|
|
|
@@ -135,7 +163,41 @@ mcpServer:
|
|
|
135
163
|
Use this Caplet for repository, issue, pull request, and code review workflows.
|
|
136
164
|
```
|
|
137
165
|
|
|
138
|
-
|
|
166
|
+
OpenAPI-backed Caplet files use `openapiEndpoint`:
|
|
167
|
+
|
|
168
|
+
```md
|
|
169
|
+
---
|
|
170
|
+
name: Users API
|
|
171
|
+
description: Manage users through the internal HTTP API.
|
|
172
|
+
openapiEndpoint:
|
|
173
|
+
specPath: ./openapi.json
|
|
174
|
+
baseUrl: https://api.example.com
|
|
175
|
+
auth:
|
|
176
|
+
type: bearer
|
|
177
|
+
token: $env:USERS_API_TOKEN
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
# Users API
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
GraphQL-backed Caplet files use `graphqlEndpoint`:
|
|
184
|
+
|
|
185
|
+
```md
|
|
186
|
+
---
|
|
187
|
+
name: Catalog GraphQL
|
|
188
|
+
description: Query and update catalog records through GraphQL.
|
|
189
|
+
graphqlEndpoint:
|
|
190
|
+
endpointUrl: https://api.example.com/graphql
|
|
191
|
+
schemaPath: ./schema.graphql
|
|
192
|
+
auth:
|
|
193
|
+
type: oidc
|
|
194
|
+
issuer: https://login.example.com
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
# Catalog GraphQL
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Top-level files derive their Caplet ID from the filename. Directory-style Caplets use
|
|
139
201
|
`linear/CAPLET.md`, which is exposed as `linear`; sibling files can be referenced with
|
|
140
202
|
normal Markdown links from `CAPLET.md`.
|
|
141
203
|
|
|
@@ -156,10 +218,10 @@ project `config.json`, and, only when trusted, project Caplet files.
|
|
|
156
218
|
caplets init --force
|
|
157
219
|
```
|
|
158
220
|
|
|
159
|
-
###
|
|
221
|
+
### Caplet IDs
|
|
160
222
|
|
|
161
|
-
Each key under `mcpServers` is the stable
|
|
162
|
-
name exactly, so keep it short and specific:
|
|
223
|
+
Each key under `mcpServers` or `openapiEndpoints` is the stable Caplet ID. It becomes the
|
|
224
|
+
generated MCP tool name exactly, so keep it short and specific:
|
|
163
225
|
|
|
164
226
|
```json
|
|
165
227
|
{
|
|
@@ -174,8 +236,8 @@ name exactly, so keep it short and specific:
|
|
|
174
236
|
}
|
|
175
237
|
```
|
|
176
238
|
|
|
177
|
-
|
|
178
|
-
Unicode IDs are rejected.
|
|
239
|
+
Caplet IDs must match `^[a-zA-Z0-9_-]{1,64}$` and must be unique across `mcpServers`,
|
|
240
|
+
`openapiEndpoints`, and `graphqlEndpoints`. Spaces, dots, slashes, colons, and Unicode IDs are rejected.
|
|
179
241
|
|
|
180
242
|
### Stdio Servers
|
|
181
243
|
|
|
@@ -216,6 +278,84 @@ Use `transport` and `url` for remote MCP servers.
|
|
|
216
278
|
`transport` can be `http` for MCP Streamable HTTP or `sse` for legacy HTTP+SSE. Remote
|
|
217
279
|
URLs must use `https://`, except loopback development URLs such as `http://localhost`.
|
|
218
280
|
|
|
281
|
+
### OpenAPI Endpoints
|
|
282
|
+
|
|
283
|
+
Use `openapiEndpoints` for native HTTP APIs described by OpenAPI 3 specs. Each entry
|
|
284
|
+
points at one spec through either `specPath` or `specUrl`, and may override the request
|
|
285
|
+
base URL with `baseUrl`.
|
|
286
|
+
|
|
287
|
+
```json
|
|
288
|
+
{
|
|
289
|
+
"name": "Users API",
|
|
290
|
+
"description": "Manage users through the internal HTTP API.",
|
|
291
|
+
"specPath": "./openapi.json",
|
|
292
|
+
"baseUrl": "https://api.example.com",
|
|
293
|
+
"auth": { "type": "none" }
|
|
294
|
+
}
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
OpenAPI auth is explicit and supports:
|
|
298
|
+
|
|
299
|
+
- `{"type": "none"}`
|
|
300
|
+
- `{"type": "bearer", "token": "$env:TOKEN"}`
|
|
301
|
+
- `{"type": "headers", "headers": {"x-api-key": "$env:API_KEY"}}`
|
|
302
|
+
- `{"type": "oauth2", ...}`
|
|
303
|
+
- `{"type": "oidc", ...}`
|
|
304
|
+
|
|
305
|
+
OpenAPI `call_tool.arguments` uses grouped HTTP inputs:
|
|
306
|
+
|
|
307
|
+
```json
|
|
308
|
+
{
|
|
309
|
+
"operation": "call_tool",
|
|
310
|
+
"tool": "GET /users/{id}",
|
|
311
|
+
"arguments": {
|
|
312
|
+
"path": { "id": "42" },
|
|
313
|
+
"query": { "active": true },
|
|
314
|
+
"body": { "name": "Ada" }
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
Every OpenAPI endpoint can set:
|
|
320
|
+
|
|
321
|
+
- `requestTimeoutMs`: timeout for HTTP calls. Defaults to `60000`.
|
|
322
|
+
- `operationCacheTtlMs`: how long OpenAPI operation metadata stays fresh. Defaults to `30000`; `0` refreshes every time.
|
|
323
|
+
- `disabled`: omit the endpoint from Caplets discovery. Defaults to `false`.
|
|
324
|
+
|
|
325
|
+
### GraphQL Endpoints
|
|
326
|
+
|
|
327
|
+
Use `graphqlEndpoints` for native GraphQL APIs. Each entry points at a GraphQL HTTP
|
|
328
|
+
endpoint and exactly one schema source: `schemaPath`, `schemaUrl`, or `introspection: true`.
|
|
329
|
+
|
|
330
|
+
```json
|
|
331
|
+
{
|
|
332
|
+
"name": "Catalog GraphQL",
|
|
333
|
+
"description": "Query and update catalog records through GraphQL.",
|
|
334
|
+
"endpointUrl": "https://api.example.com/graphql",
|
|
335
|
+
"schemaPath": "./schema.graphql",
|
|
336
|
+
"auth": { "type": "oidc", "issuer": "https://login.example.com" },
|
|
337
|
+
"operations": {
|
|
338
|
+
"product": {
|
|
339
|
+
"document": "query Product($id: ID!) { product(id: $id) { id name } }",
|
|
340
|
+
"operationName": "Product",
|
|
341
|
+
"description": "Fetch a product by ID."
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
When `operations` is omitted or empty, Caplets auto-generates tools from schema root
|
|
348
|
+
fields: `query_<field>` and `mutation_<field>`. Generated tools use bounded scalar
|
|
349
|
+
selection sets and pass `call_tool.arguments` directly as GraphQL variables/root-field
|
|
350
|
+
arguments.
|
|
351
|
+
|
|
352
|
+
Every GraphQL endpoint can set:
|
|
353
|
+
|
|
354
|
+
- `requestTimeoutMs`: timeout for HTTP calls. Defaults to `60000`.
|
|
355
|
+
- `operationCacheTtlMs`: how long GraphQL operation metadata stays fresh. Defaults to `30000`; `0` refreshes every time.
|
|
356
|
+
- `selectionDepth`: maximum depth for generated selection sets. Defaults to `2`; maximum `5`.
|
|
357
|
+
- `disabled`: omit the endpoint from Caplets discovery. Defaults to `false`.
|
|
358
|
+
|
|
219
359
|
### Authentication
|
|
220
360
|
|
|
221
361
|
Remote servers can use:
|
|
@@ -224,8 +364,9 @@ Remote servers can use:
|
|
|
224
364
|
- `{"type": "bearer", "token": "$env:TOKEN"}`
|
|
225
365
|
- `{"type": "headers", "headers": {"x-api-key": "$env:API_KEY"}}`
|
|
226
366
|
- `{"type": "oauth2", ...}`
|
|
367
|
+
- `{"type": "oidc", ...}`
|
|
227
368
|
|
|
228
|
-
For OAuth-backed
|
|
369
|
+
For OAuth/OIDC-backed MCP, OpenAPI, and GraphQL Caplets, authenticate once with:
|
|
229
370
|
|
|
230
371
|
```sh
|
|
231
372
|
caplets auth login <server>
|
|
@@ -237,8 +378,9 @@ For headless terminals:
|
|
|
237
378
|
caplets auth login <server> --no-open
|
|
238
379
|
```
|
|
239
380
|
|
|
240
|
-
OAuth tokens are stored under `~/.caplets/auth/<server>.json` with owner-only file
|
|
241
|
-
permissions where the platform supports them.
|
|
381
|
+
OAuth/OIDC tokens are stored under `~/.caplets/auth/<server>.json` with owner-only file
|
|
382
|
+
permissions where the platform supports them. Caplets supports well-known OAuth/OIDC
|
|
383
|
+
discovery and dynamic client registration when advertised. When a token expires, run
|
|
242
384
|
`caplets auth login <server>` again.
|
|
243
385
|
|
|
244
386
|
To inspect or remove stored OAuth credentials:
|
|
@@ -277,8 +419,9 @@ starts the MCP server. `serve` is explicit and recommended for clarity.
|
|
|
277
419
|
|
|
278
420
|
## How Agents Use It
|
|
279
421
|
|
|
280
|
-
Caplets initially exposes one MCP tool per enabled Caplet. If the config has `filesystem
|
|
281
|
-
and `
|
|
422
|
+
Caplets initially exposes one MCP tool per enabled Caplet. If the config has `filesystem`,
|
|
423
|
+
`docs`, and `users`, the client sees three top-level tools: `filesystem`, `docs`, and
|
|
424
|
+
`users`.
|
|
282
425
|
|
|
283
426
|
Each generated Caplet tool accepts an `operation`:
|
|
284
427
|
|
|
@@ -322,9 +465,10 @@ Call one exact downstream tool:
|
|
|
322
465
|
Available operations:
|
|
323
466
|
|
|
324
467
|
- `get_caplet`: return the configured capability card without starting the downstream server.
|
|
325
|
-
- `
|
|
468
|
+
- `check_backend`: verify the selected backend, whether MCP, OpenAPI, or GraphQL.
|
|
469
|
+
- `check_mcp_server`: start or connect to an MCP server and verify its tool list.
|
|
326
470
|
- `list_tools`: return compact downstream tool metadata.
|
|
327
|
-
- `search_tools`: search downstream tool names and descriptions within this
|
|
471
|
+
- `search_tools`: search downstream tool names and descriptions within this Caplet.
|
|
328
472
|
- `get_tool`: return full metadata for one exact downstream tool.
|
|
329
473
|
- `call_tool`: invoke one exact downstream tool with JSON object arguments.
|
|
330
474
|
|