caplets 0.1.0 → 0.2.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.
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2026 Ian Pascoe
3
+ Copyright (c) 2026 Spirit-Led Software LLC
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,14 +1,334 @@
1
1
  # Caplets
2
2
 
3
- Caplets is a local MCP gateway that exposes configured downstream MCP servers as capability-level tools first, then progressively discloses each server's underlying tools on demand.
3
+ Caplets is a progressive-disclosure gateway for Model Context Protocol (MCP) servers.
4
+
5
+ Instead of connecting an MCP client to many downstream servers and exposing every tool up
6
+ front, Caplets exposes one top-level tool per configured server. An agent first chooses a
7
+ capability domain, then asks Caplets to list, search, inspect, or call that server's
8
+ underlying tools.
9
+
10
+ This keeps the initial MCP tool list small, makes tool selection easier, and avoids
11
+ flattened tool-name collisions across servers.
12
+
13
+ ## Inspiration
14
+
15
+ Caplets is a mashup of two ideas that work well separately but leave a gap together:
16
+ agent skills and MCP servers.
17
+
18
+ Agent skills are great at progressive disclosure. They show an agent a compact capability
19
+ card first, then let it read deeper instructions only when that skill is relevant. MCP
20
+ servers are great at live tool execution, but most clients expose their tools as one flat
21
+ list up front. That means a powerful MCP setup can flood the agent with every tool from
22
+ every server before it knows which capability area matters.
23
+
24
+ Caplets borrows the skill-shaped discovery model and applies it to MCP. Each downstream
25
+ server becomes a skill-like capability card first; its actual MCP tools stay hidden until
26
+ the agent chooses that server and asks to search, list, inspect, or call them.
27
+
28
+ ## What It Does
29
+
30
+ - Reads downstream MCP server definitions from `~/.caplets/config.json`.
31
+ - Registers one generated MCP tool for each enabled server.
32
+ - Uses the configured server ID as the generated tool name.
33
+ - Uses the configured `name` and `description` as the capability card shown to agents.
34
+ - Starts downstream servers lazily when an operation needs them.
35
+ - 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 server namespace.
37
+ - Preserves downstream tool results instead of rewriting them into a custom format.
38
+ - Redacts secrets from structured errors.
39
+ - Supports static remote auth and OAuth token storage for remote servers.
40
+
41
+ ## Install
42
+
43
+ Caplets requires Node.js 22 or newer.
44
+
45
+ ```sh
46
+ pnpm add -g caplets
47
+ ```
48
+
49
+ For local development from this repository:
50
+
51
+ ```sh
52
+ pnpm install
53
+ pnpm build
54
+ ```
55
+
56
+ ## Configure
57
+
58
+ Create a starter `~/.caplets/config.json`:
59
+
60
+ ```sh
61
+ caplets init
62
+ ```
63
+
64
+ The generated config includes a disabled example server. Replace it with the MCP servers
65
+ you want Caplets to expose:
66
+
67
+ ```json
68
+ {
69
+ "$schema": "https://raw.githubusercontent.com/spiritledsoftware/caplets/main/schemas/caplets-config.schema.json",
70
+ "version": 1,
71
+ "defaultSearchLimit": 20,
72
+ "maxSearchLimit": 50,
73
+ "mcpServers": {
74
+ "filesystem": {
75
+ "name": "Project Files",
76
+ "description": "Read, search, and edit local project files.",
77
+ "command": "npx",
78
+ "args": ["-y", "@modelcontextprotocol/server-filesystem", "/home/you/code"],
79
+ "cwd": "/home/you/code",
80
+ "startupTimeoutMs": 10000,
81
+ "callTimeoutMs": 60000,
82
+ "toolCacheTtlMs": 30000
83
+ },
84
+ "docs": {
85
+ "name": "Hosted Docs",
86
+ "description": "Search hosted product and API documentation.",
87
+ "transport": "http",
88
+ "url": "https://mcp.example.com/mcp",
89
+ "auth": {
90
+ "type": "bearer",
91
+ "token": "$env:DOCS_MCP_TOKEN"
92
+ }
93
+ }
94
+ }
95
+ }
96
+ ```
97
+
98
+ The default config path can be overridden with `CAPLETS_CONFIG`:
99
+
100
+ ```sh
101
+ CAPLETS_CONFIG=/path/to/config.json caplets init
102
+ CAPLETS_CONFIG=/path/to/config.json caplets serve
103
+ ```
104
+
105
+ Caplets validates this file at startup. Config changes take effect after restarting the
106
+ Caplets MCP server.
107
+
108
+ The optional `$schema` field points editors at the generated JSON Schema in
109
+ [`schemas/caplets-config.schema.json`](schemas/caplets-config.schema.json). CI verifies that
110
+ the committed schema stays in sync with the Zod config validator.
111
+
112
+ `caplets init` refuses to overwrite an existing config. To intentionally replace the file:
113
+
114
+ ```sh
115
+ caplets init --force
116
+ ```
117
+
118
+ ### Server IDs
119
+
120
+ Each key under `mcpServers` is the stable server ID. It becomes the generated MCP tool
121
+ name exactly, so keep it short and specific:
122
+
123
+ ```json
124
+ {
125
+ "mcpServers": {
126
+ "linear": {
127
+ "name": "Linear",
128
+ "description": "Read and update Linear issues and projects.",
129
+ "command": "npx",
130
+ "args": ["-y", "linear-mcp-server"]
131
+ }
132
+ }
133
+ }
134
+ ```
135
+
136
+ Server IDs must match `^[a-zA-Z0-9_-]{1,64}$`. Spaces, dots, slashes, colons, and
137
+ Unicode IDs are rejected.
138
+
139
+ ### Stdio Servers
140
+
141
+ Use `command` for a local stdio MCP server. `args`, `env`, and `cwd` are optional.
142
+
143
+ ```json
144
+ {
145
+ "name": "Local Tools",
146
+ "description": "Run local development tools through stdio.",
147
+ "command": "node",
148
+ "args": ["./server.mjs"],
149
+ "env": {
150
+ "API_TOKEN": "${API_TOKEN}"
151
+ },
152
+ "cwd": "/home/you/project"
153
+ }
154
+ ```
155
+
156
+ ### Remote Servers
157
+
158
+ Use `transport` and `url` for remote MCP servers.
159
+
160
+ ```json
161
+ {
162
+ "name": "Remote Docs",
163
+ "description": "Search documentation from a remote MCP server.",
164
+ "transport": "http",
165
+ "url": "https://mcp.example.com/mcp",
166
+ "auth": {
167
+ "type": "headers",
168
+ "headers": {
169
+ "x-api-key": "$env:REMOTE_DOCS_API_KEY"
170
+ }
171
+ }
172
+ }
173
+ ```
174
+
175
+ `transport` can be `http` for MCP Streamable HTTP or `sse` for legacy HTTP+SSE. Remote
176
+ URLs must use `https://`, except loopback development URLs such as `http://localhost`.
177
+
178
+ ### Authentication
179
+
180
+ Remote servers can use:
181
+
182
+ - `{"type": "none"}`
183
+ - `{"type": "bearer", "token": "$env:TOKEN"}`
184
+ - `{"type": "headers", "headers": {"x-api-key": "$env:API_KEY"}}`
185
+ - `{"type": "oauth2", ...}`
186
+
187
+ For OAuth-backed remote servers, authenticate once with:
188
+
189
+ ```sh
190
+ caplets auth login <server>
191
+ ```
192
+
193
+ For headless terminals:
194
+
195
+ ```sh
196
+ caplets auth login <server> --no-open
197
+ ```
198
+
199
+ OAuth tokens are stored under `~/.caplets/auth/<server>.json` with owner-only file
200
+ permissions where the platform supports them. When an OAuth token expires, run
201
+ `caplets auth login <server>` again.
202
+
203
+ To inspect or remove stored OAuth credentials:
204
+
205
+ ```sh
206
+ caplets auth list
207
+ caplets auth logout <server>
208
+ ```
209
+
210
+ ### Optional Server Settings
211
+
212
+ Every server can set:
213
+
214
+ - `startupTimeoutMs`: timeout for starting or checking the downstream server. Defaults to `10000`.
215
+ - `callTimeoutMs`: timeout for downstream tool calls. Defaults to `60000`.
216
+ - `toolCacheTtlMs`: how long downstream tool metadata stays fresh. Defaults to `30000`; `0` refreshes every time.
217
+ - `disabled`: omit the server from Caplets discovery. Defaults to `false`.
218
+
219
+ ## Add Caplets To An MCP Client
220
+
221
+ Configure your MCP client to run Caplets as a stdio server:
222
+
223
+ ```json
224
+ {
225
+ "mcpServers": {
226
+ "caplets": {
227
+ "command": "caplets",
228
+ "args": ["serve"]
229
+ }
230
+ }
231
+ }
232
+ ```
233
+
234
+ If your client starts the configured command directly, `caplets` without arguments also
235
+ starts the MCP server. `serve` is explicit and recommended for clarity.
236
+
237
+ ## How Agents Use It
238
+
239
+ Caplets initially exposes one MCP tool per enabled server. If the config has `filesystem`
240
+ and `docs`, the client sees two top-level tools: `filesystem` and `docs`.
241
+
242
+ Each generated server tool accepts an `operation`:
243
+
244
+ ```json
245
+ {
246
+ "operation": "list_tools"
247
+ }
248
+ ```
249
+
250
+ Search within a selected server:
251
+
252
+ ```json
253
+ {
254
+ "operation": "search_tools",
255
+ "query": "read file",
256
+ "limit": 10
257
+ }
258
+ ```
259
+
260
+ Inspect one exact downstream tool:
261
+
262
+ ```json
263
+ {
264
+ "operation": "get_tool",
265
+ "tool": "read_file"
266
+ }
267
+ ```
268
+
269
+ Call one exact downstream tool:
270
+
271
+ ```json
272
+ {
273
+ "operation": "call_tool",
274
+ "tool": "read_file",
275
+ "arguments": {
276
+ "path": "/home/you/code/project/README.md"
277
+ }
278
+ }
279
+ ```
280
+
281
+ Available operations:
282
+
283
+ - `get_server`: return the configured capability card without starting the downstream server.
284
+ - `check_server`: start or connect to the downstream server and verify its tool list.
285
+ - `list_tools`: return compact downstream tool metadata.
286
+ - `search_tools`: search downstream tool names and descriptions within this server.
287
+ - `get_tool`: return full metadata for one exact downstream tool.
288
+ - `call_tool`: invoke one exact downstream tool with JSON object arguments.
289
+
290
+ Requests are strict: operation-specific extra fields are rejected, and `call_tool` requires
291
+ `arguments` to be a JSON object.
4
292
 
5
293
  ## Development
6
294
 
7
295
  ```sh
8
296
  pnpm install
297
+ pnpm dev
298
+ ```
299
+
300
+ Useful commands:
301
+
302
+ ```sh
303
+ pnpm build
304
+ pnpm test
305
+ pnpm typecheck
306
+ pnpm lint
307
+ pnpm format:check
308
+ pnpm schema:generate
309
+ pnpm schema:check
9
310
  pnpm verify
10
311
  ```
11
312
 
313
+ `pnpm dev` rebuilds on source changes and restarts the local stdio MCP server from
314
+ `dist/index.js`. Use it for local development, not as the command configured in an MCP
315
+ client, because build logs are written to stdout.
316
+
317
+ ## Product Notes
318
+
319
+ The product requirements document lives at
320
+ [`docs/product/caplets-progressive-mcp-disclosure-prd.md`](docs/product/caplets-progressive-mcp-disclosure-prd.md).
321
+ It describes the progressive MCP disclosure model, configuration rules, MVP tool surface,
322
+ security expectations, and non-goals.
323
+
324
+ Caplets intentionally does not provide a hosted service, GUI, cross-server flattened tool
325
+ search, automatic MCP client config import, or namespaced flattened tool IDs such as
326
+ `server.tool`.
327
+
328
+ Progressive disclosure is context management, not a security boundary. Caplets reduces the
329
+ tool surface shown to the agent up front, but downstream MCP servers remain responsible for
330
+ their own tool behavior and any client-side confirmations.
331
+
12
332
  ## Release Flow
13
333
 
14
334
  User-facing changes should include a changeset:
@@ -17,4 +337,9 @@ User-facing changes should include a changeset:
17
337
  pnpm changeset
18
338
  ```
19
339
 
20
- Merging changesets to `main` lets the release workflow open a version PR. Merging that version PR publishes the package to npm through trusted publishing.
340
+ Merging changesets to `main` lets the release workflow open a version PR. Merging that
341
+ version PR publishes the package to npm through trusted publishing.
342
+
343
+ ## License
344
+
345
+ MIT