soup-chop 1.0.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.
Files changed (3) hide show
  1. package/README.md +901 -0
  2. package/dist/index.js +2056 -0
  3. package/package.json +46 -0
package/README.md ADDED
@@ -0,0 +1,901 @@
1
+ <p align="center">
2
+ <h1 align="center">soupChop</h1>
3
+ <p align="center">
4
+ <strong>The Just-In-Time Documentation Proxy for the Model Context Protocol.</strong>
5
+ </p>
6
+ <p align="center">
7
+ Give your AI agent instant, version-accurate access to any NPM package's documentation — no custom servers, no hallucinated APIs.
8
+ </p>
9
+ <p align="center">
10
+ Start from a soup of markdown, then chop and mince it into small, evidence-backed bites an agent can actually use.
11
+ </p>
12
+ </p>
13
+
14
+ ---
15
+
16
+ <p align="center">
17
+ <a href="#why-soup-chop">Why?</a> •
18
+ <a href="#quick-start">Quick Start</a> •
19
+ <a href="#available-tools">Tools</a> •
20
+ <a href="#how-it-works">How It Works</a> •
21
+ <a href="#configuration">Configuration</a> •
22
+ <a href="#for-library-authors">For Library Authors</a> •
23
+ <a href="#examples">Examples</a> •
24
+ <a href="#faq">FAQ</a>
25
+ </p>
26
+
27
+ ---
28
+
29
+ ## The Problem
30
+
31
+ You're using an AI coding assistant. You ask it to help you with `mutts@2.0.0`.
32
+ It confidently writes code using the `v1` API — because that's what was in its
33
+ training data. You correct it. It apologizes. It does it again.
34
+
35
+ **soupChop fixes this.**
36
+
37
+ It gives your AI agent a live, on-demand window into the *actual* documentation
38
+ for the *exact* version of the library you're working with. No pre-training
39
+ required. No stale knowledge. No hallucinated function signatures.
40
+
41
+ ---
42
+
43
+ ## Why soupChop?
44
+
45
+ | Without soupChop | With soupChop |
46
+ | :--- | :--- |
47
+ | AI guesses API from training data | AI reads the real docs for your exact version |
48
+ | You paste READMEs into chat manually | Docs are fetched and structured automatically |
49
+ | Full READMEs flood the context window | Only the relevant section is delivered |
50
+ | Every library needs its own MCP server | One server handles every NPM package |
51
+
52
+ ---
53
+
54
+ ## Quick Start
55
+
56
+ ### Option 1 — Run directly with `npx`
57
+
58
+ ```bash
59
+ npx soup-chop serve
60
+ ```
61
+
62
+ That's it. The MCP server starts on `stdio` and is ready for your AI client to connect.
63
+
64
+ ### Option 2 — Install globally
65
+
66
+ ```bash
67
+ npm install -g soup-chop
68
+ soup-chop serve
69
+ ```
70
+
71
+ ### Option 3 — Inspect the supported clients
72
+
73
+ ```bash
74
+ npx soup-chop clients
75
+ ```
76
+
77
+ This prints the currently documented client list and highlights which clients support
78
+ automatic file-based configuration on your current platform.
79
+
80
+ ### Option 4 — Auto-configure a supported client
81
+
82
+ ```bash
83
+ npx soup-chop configure windsurf
84
+ npx soup-chop configure cursor
85
+ npx soup-chop configure cursor --project
86
+ npx soup-chop configure vscode-copilot
87
+ npx soup-chop configure firebase-studio
88
+ npx soup-chop configure cursor --project --dry-run
89
+ npx soup-chop configure cursor --print
90
+ npx soup-chop configure cursor --project --local-build --dry-run
91
+ ```
92
+
93
+ Use `--project` or `--global` when a client supports more than one writable scope. Without a flag, `soup-chop` uses that client's default writable scope.
94
+
95
+ On Linux today, the exact auto-config targets exposed by `soup-chop help` depend on the current platform and writable config paths.
96
+ On macOS and Windows, Claude Desktop is also documented and may become auto-configurable when its stable config path is available on that platform.
97
+
98
+ For a non-mutating preview, use:
99
+
100
+ ```bash
101
+ npx soup-chop configure cursor --project --dry-run
102
+ npx soup-chop configure vscode-copilot --dry-run
103
+ ```
104
+
105
+ To print only the config snippet for copy-paste workflows, use:
106
+
107
+ ```bash
108
+ npx soup-chop configure cursor --print
109
+ npx soup-chop configure vscode-copilot --print
110
+ ```
111
+
112
+ To generate config for an unpublished local build instead of `npx soup-chop serve`, use:
113
+
114
+ ```bash
115
+ npx soup-chop configure cursor --project --local-build --dry-run
116
+ npx soup-chop configure cursor --local-build
117
+ ```
118
+
119
+ This emits `node /abs/path/to/dist/index.js serve` using the current working directory as the local build root.
120
+
121
+ If you're unsure what the current build supports on your machine, run:
122
+
123
+ ```bash
124
+ npx soup-chop help
125
+ npx soup-chop clients --json
126
+ ```
127
+
128
+ The help output includes the exact auto-config client IDs available on the current platform. `clients --json` emits the same client matrix as structured JSON for setup scripts and tooling.
129
+
130
+ ### Option 5 — Manual configuration matrix
131
+
132
+ The ecosystem is moving quickly, so `soupChop` documents both implemented auto-config targets and UI/manual targets that are officially supported by their clients.
133
+
134
+ | Client | Status | Scope | Verified config path / flow | Notes |
135
+ | :----- | :----- | :---- | :-------------------------- | :---- |
136
+ | Claude Desktop | Auto-config on macOS and Windows | Global | macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`<br>Windows: `%APPDATA%\Claude\claude_desktop_config.json` | Official MCP docs expose this file via Claude > Settings > Developer > Edit Config; Linux remains documented-only in CLI output |
137
+ | Claude Code | Documented | Project / user | `claude mcp add soup-chop npx -- soup-chop serve` | Official docs favor CLI / plugin flows rather than direct file editing |
138
+ | Cursor | Auto-config | Global / project | Global: `~/.cursor/mcp.json`<br>Project: `.cursor/mcp.json` | Use `npx soup-chop configure cursor` for the global file or `npx soup-chop configure cursor --project` for the project file |
139
+ | Windsurf | Auto-config | Global | `~/.codeium/windsurf/mcp_config.json` | Official docs also expose MCP management from the MCP Marketplace / Settings UI |
140
+ | Antigravity | Documented | UI-managed | Agent pane → `MCP Servers` / `MCP Store` / `View raw config` | Official docs describe the flow but do not publish a stable file path |
141
+ | Cline | Documented | UI-managed | MCP Servers icon → Configure MCP Servers → `cline_mcp_settings.json` | Official docs expose the config file through the UI |
142
+ | VS Code Copilot | Auto-config | Project / user | Project: `.vscode/mcp.json`<br>User: VS Code user settings under `mcp.servers` | `soup-chop` writes the project file today; the user-settings path remains manual. Uses `servers` rather than `mcpServers` |
143
+ | Gemini CLI | Documented | Project / user | Project: `.gemini/settings.json`<br>User: `~/.gemini/settings.json` | Same JSON shape as other `mcpServers` clients |
144
+ | Gemini Code Assist | Documented | Project / user | Project: `.gemini/settings.json`<br>User: `~/.gemini/settings.json` | Shares Gemini CLI config format |
145
+ | Firebase Studio | Auto-config | Project | `.idx/mcp.json` | `soup-chop` writes the project-local MCP config directly |
146
+
147
+ ### Option 6 — Manual snippets by client
148
+
149
+ The `configure` command accepts a few convenience aliases, for example `claude`, `copilot`, and `firebase`, and it supports explicit `--project` / `--global` scope selection when a client exposes more than one writable file target. Use `--dry-run` to preview the resolved file and merged JSON, `--print` to emit just the minimal snippet, or `--local-build` to point the config at the local built `dist/index.js` entrypoint.
150
+
151
+ When `configure` cannot write a client automatically, it now reports the documented target and points you back to `soup-chop clients` for the full matrix instead of failing with a generic message.
152
+
153
+ #### Claude Desktop / Cursor / Windsurf / Gemini / Firebase Studio
154
+
155
+ ```json
156
+ {
157
+ "mcpServers": {
158
+ "soup-chop": {
159
+ "command": "npx",
160
+ "args": ["soup-chop", "serve"]
161
+ }
162
+ }
163
+ }
164
+ ```
165
+
166
+ #### VS Code Copilot project config
167
+
168
+ ```json
169
+ {
170
+ "servers": {
171
+ "soup-chop": {
172
+ "type": "stdio",
173
+ "command": "npx",
174
+ "args": ["soup-chop", "serve"]
175
+ }
176
+ }
177
+ }
178
+ ```
179
+
180
+ #### Claude Code manual registration
181
+
182
+ ```bash
183
+ claude mcp add soup-chop npx -- soup-chop serve
184
+ ```
185
+
186
+ #### Antigravity manual registration
187
+
188
+ Open the Agent pane, then go to `MCP Servers` or `MCP Store`, add a custom stdio server, and point it to:
189
+
190
+ ```bash
191
+ npx soup-chop serve
192
+ ```
193
+
194
+ If Antigravity exposes raw JSON editing in your current build, use the same `mcpServers` JSON shown above.
195
+
196
+ ---
197
+
198
+ ## Available Tools
199
+
200
+ The server is primarily tool-oriented, but it also exposes a small capability
201
+ resource at `soup-chop://capabilities` so MCP clients that inspect resources
202
+ have a useful entry point.
203
+
204
+ ### `get_toc`
205
+
206
+ > **Discover what's in the documentation.**
207
+
208
+ Returns a structured table of contents for a package's markdown docs.
209
+
210
+ Without `origin`, it returns a package-wide multi-document TOC that includes
211
+ synthetic file-root entries such as `README.md`, `CHANGELOG.md`, or
212
+ `docs/faq.md`.
213
+
214
+ With `origin`, it returns the TOC for a single markdown document.
215
+
216
+ **Parameters:**
217
+
218
+ | Name | Type | Required | Description |
219
+ | :-------- | :------- | :------- | :------------------------------------- |
220
+ | `package` | `string` | Yes | NPM package name (e.g., `"express"`) |
221
+ | `version` | `string` | Yes | NPM version string: exact version or published dist-tag (e.g., `"4.18.2"`, `"latest"`) |
222
+ | `origin` | `string` | No | Markdown source path from `search_docs` such as `"docs/faq.md"` or `"CHANGELOG.md"` |
223
+
224
+ **Example call:**
225
+
226
+ ```json
227
+ {
228
+ "name": "get_toc",
229
+ "arguments": {
230
+ "package": "zod",
231
+ "version": "3.23.8"
232
+ }
233
+ }
234
+ ```
235
+
236
+ **Example response:**
237
+
238
+ ```json
239
+ {
240
+ "package": "axios",
241
+ "version": "1.6.7",
242
+ "entries": [
243
+ {
244
+ "depth": 0,
245
+ "title": "README.md",
246
+ "path": "README.md",
247
+ "startLine": 1,
248
+ "endLine": 1648,
249
+ "origin": "README.md",
250
+ "topicId": "README.md"
251
+ },
252
+ {
253
+ "depth": 2,
254
+ "title": "Request Config",
255
+ "path": "Request Config",
256
+ "startLine": 386,
257
+ "endLine": 634,
258
+ "origin": "README.md",
259
+ "topicId": "README.md#Request Config"
260
+ },
261
+ {
262
+ "depth": 0,
263
+ "title": "CHANGELOG.md",
264
+ "path": "CHANGELOG.md",
265
+ "startLine": 1,
266
+ "endLine": 205,
267
+ "origin": "CHANGELOG.md",
268
+ "topicId": "CHANGELOG.md"
269
+ }
270
+ ]
271
+ }
272
+ ```
273
+
274
+ When you already know the document you want, pass `origin` to get just that
275
+ document's headings.
276
+
277
+ ### `get_topic`
278
+
279
+ > **Read a specific section.**
280
+
281
+ Fetches the raw Markdown content for a specific section or whole markdown
282
+ document.
283
+
284
+ You can identify the target either with `topic_id`, or with `path` plus an
285
+ optional `origin`.
286
+
287
+ **Parameters:**
288
+
289
+ | Name | Type | Required | Description |
290
+ | :-------- | :------- | :------- | :------------------------------------------------------- |
291
+ | `package` | `string` | Yes | NPM package name |
292
+ | `version` | `string` | Yes | NPM version string: exact version or published dist-tag |
293
+ | `path` | `string` | No | Section path from `get_toc` (e.g., `"Zod/Installation"`) |
294
+ | `origin` | `string` | No | Markdown source path from `search_docs` such as `"docs/faq.md"` or `"CHANGELOG.md"` |
295
+ | `topic_id`| `string` | No | Stable topic identifier from `search_docs` or aggregated `get_toc` |
296
+
297
+ **Example call using `topic_id`:**
298
+
299
+ ```json
300
+ {
301
+ "name": "get_topic",
302
+ "arguments": {
303
+ "package": "zod",
304
+ "version": "3.23.8",
305
+ "topic_id": "README.md#Coercion for primitives"
306
+ }
307
+ }
308
+ ```
309
+
310
+ ### `search_docs`
311
+
312
+ > **Search package docs when you do not know the exact section yet.**
313
+
314
+ Searches `README.md`, package-local markdown under `doc/` and `docs/`, and a
315
+ small allowlist of top-level markdown docs such as `API.md`, `FAQ.md`,
316
+ `MIGRATING.md`, `UPGRADING.md`, `CHANGELOG.md`, and `CONTRIBUTING.md`.
317
+
318
+ Results are ranked lexically and return the source origin, section path, line
319
+ ranges, a stable `topicId`, and a short preview so the caller can follow up
320
+ with `get_toc` or `get_topic`.
321
+
322
+ **Current language support:** search is currently optimized for **English**
323
+ tokenization and ranking.
324
+
325
+ **TODO:** add better Chinese / broader CJK tokenization and ranking support.
326
+
327
+ **Parameters:**
328
+
329
+ | Name | Type | Required | Description |
330
+ | :-------- | :------- | :------- | :---------------------------------------------------------------------- |
331
+ | `package` | `string` | Yes | NPM package name |
332
+ | `version` | `string` | Yes | NPM version string: exact version or published dist-tag |
333
+ | `query` | `string` | Yes | Keyword query or natural-language question |
334
+ | `limit` | `number` | No | Maximum number of ranked results to return, from `1` to `20`, default `5` |
335
+
336
+ **Example call:**
337
+
338
+ ```json
339
+ {
340
+ "name": "search_docs",
341
+ "arguments": {
342
+ "package": "zod",
343
+ "version": "3.23.8",
344
+ "query": "coercion schema parsing",
345
+ "limit": 3
346
+ }
347
+ }
348
+ ```
349
+
350
+ **Example follow-up flow:**
351
+
352
+ 1. Call `search_docs` to find likely sections.
353
+ 2. If needed, call `get_toc` with the returned `origin` to inspect that doc's structure.
354
+ 3. Call `get_topic` with the returned `topicId`, or with the returned `path` and `origin`, to fetch the exact section.
355
+
356
+ ### `get_traps`
357
+
358
+ > **Surface warnings, caveats, and operational gotchas.**
359
+
360
+ Returns compact, evidence-backed trap findings extracted deterministically from
361
+ the same markdown corpus used by `search_docs`.
362
+
363
+ Each finding includes:
364
+
365
+ - `package`
366
+ - `version`
367
+ - `kind`
368
+ - `severity`
369
+ - `confidence`
370
+ - `title`
371
+ - `summary`
372
+ - `evidence`
373
+
374
+ Each evidence item includes the source document, section path, exact line
375
+ range, snippet, and detector names so the caller can pivot back into
376
+ `get_topic` without losing traceability.
377
+
378
+ **Parameters:**
379
+
380
+ | Name | Type | Required | Description |
381
+ | :-------- | :------- | :------- | :----------------------------------------------------------------------- |
382
+ | `package` | `string` | Yes | NPM package name |
383
+ | `version` | `string` | Yes | NPM version string: exact version or published dist-tag |
384
+ | `limit` | `number` | No | Maximum number of ranked trap findings to return, from `1` to `50`, default `10` |
385
+
386
+ **Example call:**
387
+
388
+ ```json
389
+ {
390
+ "name": "get_traps",
391
+ "arguments": {
392
+ "package": "zod",
393
+ "version": "3.23.8",
394
+ "limit": 2
395
+ }
396
+ }
397
+ ```
398
+
399
+ **Example response:**
400
+
401
+ ```json
402
+ {
403
+ "package": "zod",
404
+ "version": "3.23.8",
405
+ "kind": "traps",
406
+ "findings": [
407
+ {
408
+ "package": "zod",
409
+ "version": "3.23.8",
410
+ "kind": "traps",
411
+ "severity": "warning",
412
+ "confidence": "high",
413
+ "title": "Important caveat noted in documentation",
414
+ "summary": "> IMPORTANT: The value returned by .parse is a deep clone of the variable you passed in.",
415
+ "evidence": [
416
+ {
417
+ "sourceId": "readme__md",
418
+ "sourceKind": "readme",
419
+ "sourceTitle": "README.md",
420
+ "origin": "README.md",
421
+ "path": "Schema methods/.parse",
422
+ "startLine": 1930,
423
+ "endLine": 1930,
424
+ "snippet": "> IMPORTANT: The value returned by .parse is a deep clone of the variable you passed in.",
425
+ "detectors": ["trap.important"]
426
+ }
427
+ ]
428
+ }
429
+ ]
430
+ }
431
+ ```
432
+
433
+ ### `get_deprecations`
434
+
435
+ > **Surface deprecated APIs, legacy guidance, and replacements.**
436
+
437
+ Returns compact, evidence-backed deprecation findings extracted deterministically
438
+ from the same markdown corpus used by `search_docs`.
439
+
440
+ Deprecation findings are surfaced at `warning` severity because they usually
441
+ indicate migration work, compatibility edge-cases, or removal risk rather than
442
+ neutral reference material.
443
+
444
+ Use it when you want focused migration and replacement guidance instead of the
445
+ broader caveat-oriented `get_traps` view.
446
+
447
+ **Parameters:**
448
+
449
+ | Name | Type | Required | Description |
450
+ | :-------- | :------- | :------- | :----------------------------------------------------------------------------- |
451
+ | `package` | `string` | Yes | NPM package name |
452
+ | `version` | `string` | Yes | NPM version string: exact version or published dist-tag |
453
+ | `limit` | `number` | No | Maximum number of ranked deprecation findings to return, from `1` to `50`, default `10` |
454
+
455
+ **Example call:**
456
+
457
+ ```json
458
+ {
459
+ "name": "get_deprecations",
460
+ "arguments": {
461
+ "package": "zod",
462
+ "version": "3.23.8",
463
+ "limit": 2
464
+ }
465
+ }
466
+ ```
467
+
468
+ **Example response:**
469
+
470
+ ```json
471
+ {
472
+ "package": "demo",
473
+ "version": "1.0.0",
474
+ "kind": "deprecations",
475
+ "findings": [
476
+ {
477
+ "package": "demo",
478
+ "version": "1.0.0",
479
+ "kind": "deprecations",
480
+ "severity": "warning",
481
+ "confidence": "high",
482
+ "title": "Deprecation or replacement guidance",
483
+ "summary": "This API is deprecated; use createClient instead.",
484
+ "evidence": [
485
+ {
486
+ "sourceId": "migration",
487
+ "sourceKind": "package_doc",
488
+ "sourceTitle": "migration.md",
489
+ "origin": "docs/migration.md",
490
+ "path": "Migration",
491
+ "startLine": 8,
492
+ "endLine": 8,
493
+ "snippet": "This API is deprecated; use createClient instead.",
494
+ "detectors": ["deprecation.deprecated", "deprecation.use_instead"]
495
+ }
496
+ ]
497
+ }
498
+ ]
499
+ }
500
+ ```
501
+
502
+ ### `get_constraints`
503
+
504
+ > **Surface prerequisites, ordering requirements, and unsupported scenarios.**
505
+
506
+ Returns compact, evidence-backed constraint findings extracted deterministically
507
+ from the same markdown corpus used by `search_docs`.
508
+
509
+ Use it when you want integration requirements and support boundaries rather than
510
+ general caveats.
511
+
512
+ **Parameters:**
513
+
514
+ | Name | Type | Required | Description |
515
+ | :-------- | :------- | :------- | :--------------------------------------------------------------------------- |
516
+ | `package` | `string` | Yes | NPM package name |
517
+ | `version` | `string` | Yes | NPM version string: exact version or published dist-tag |
518
+ | `limit` | `number` | No | Maximum number of ranked constraint findings to return, from `1` to `50`, default `10` |
519
+
520
+ **Example call:**
521
+
522
+ ```json
523
+ {
524
+ "name": "get_constraints",
525
+ "arguments": {
526
+ "package": "demo",
527
+ "version": "1.0.0",
528
+ "limit": 2
529
+ }
530
+ }
531
+ ```
532
+
533
+ **Example response:**
534
+
535
+ ```json
536
+ {
537
+ "package": "demo",
538
+ "version": "1.0.0",
539
+ "kind": "constraints",
540
+ "findings": [
541
+ {
542
+ "package": "demo",
543
+ "version": "1.0.0",
544
+ "kind": "constraints",
545
+ "severity": "warning",
546
+ "confidence": "high",
547
+ "title": "Operational constraint",
548
+ "summary": "This only works after setup and requires a token.",
549
+ "evidence": [
550
+ {
551
+ "sourceId": "guide",
552
+ "sourceKind": "package_doc",
553
+ "sourceTitle": "guide.md",
554
+ "origin": "docs/guide.md",
555
+ "path": "Setup",
556
+ "startLine": 4,
557
+ "endLine": 4,
558
+ "snippet": "This only works after setup and requires a token.",
559
+ "detectors": ["constraint.after_setup", "constraint.only_works", "constraint.requires"]
560
+ }
561
+ ]
562
+ }
563
+ ]
564
+ }
565
+ ```
566
+
567
+ ### `get_performance_notes`
568
+
569
+ > **Surface complexity notes, expensive operations, and hot paths.**
570
+
571
+ Returns compact, evidence-backed performance findings extracted deterministically
572
+ from the same markdown corpus used by `search_docs`.
573
+
574
+ Use it when you want cost and scaling signals rather than functional or
575
+ operational caveats.
576
+
577
+ **Parameters:**
578
+
579
+ | Name | Type | Required | Description |
580
+ | :-------- | :------- | :------- | :----------------------------------------------------------------------------- |
581
+ | `package` | `string` | Yes | NPM package name |
582
+ | `version` | `string` | Yes | NPM version string: exact version or published dist-tag |
583
+ | `limit` | `number` | No | Maximum number of ranked performance findings to return, from `1` to `50`, default `10` |
584
+
585
+ **Example call:**
586
+
587
+ ```json
588
+ {
589
+ "name": "get_performance_notes",
590
+ "arguments": {
591
+ "package": "demo",
592
+ "version": "1.0.0",
593
+ "limit": 2
594
+ }
595
+ }
596
+ ```
597
+
598
+ **Example response:**
599
+
600
+ ```json
601
+ {
602
+ "package": "demo",
603
+ "version": "1.0.0",
604
+ "kind": "performance",
605
+ "findings": [
606
+ {
607
+ "package": "demo",
608
+ "version": "1.0.0",
609
+ "kind": "performance",
610
+ "severity": "warning",
611
+ "confidence": "high",
612
+ "title": "Performance-sensitive behavior",
613
+ "summary": "This operation is expensive on the hot path.",
614
+ "evidence": [
615
+ {
616
+ "sourceId": "perf",
617
+ "sourceKind": "package_doc",
618
+ "sourceTitle": "performance.md",
619
+ "origin": "docs/performance.md",
620
+ "path": "Performance",
621
+ "startLine": 12,
622
+ "endLine": 12,
623
+ "snippet": "This operation is expensive on the hot path.",
624
+ "detectors": ["performance.expensive", "performance.hot_path"]
625
+ }
626
+ ]
627
+ }
628
+ ]
629
+ }
630
+ ```
631
+
632
+ ### `soup-chop://capabilities`
633
+
634
+ > **Quick MCP entry point for resource-oriented clients.**
635
+
636
+ If your client starts by listing resources, `soup-chop://capabilities` explains
637
+ the server surface and points you toward the recommended tool-first flow.
638
+
639
+ Use it to discover:
640
+
641
+ - the main tools
642
+ - the recommended `search_docs` -> `get_toc` / `get_topic` flow
643
+ - the current English-first search behavior
644
+
645
+ ### `get_api_ref`
646
+
647
+ > **Index the published API surface.**
648
+
649
+ Returns a compact index of exported identifiers from published `.d.ts` files.
650
+ Each entry is grouped by identifier name and lists its associated runtime and
651
+ compile-time kinds.
652
+
653
+ **Parameters:**
654
+
655
+ | Name | Type | Required | Description |
656
+ | :-------- | :------- | :------- | :------------------------------------------------------------------------------------- |
657
+ | `package` | `string` | Yes | NPM package name |
658
+ | `version` | `string` | Yes | NPM version string: exact version or published dist-tag (e.g., `"3.23.8"`, `"latest"`) |
659
+
660
+ ### `get_declaration`
661
+
662
+ > **Read the exact declaration body.**
663
+
664
+ Returns the explicit TypeScript declaration text for an exported identifier.
665
+ Use `get_api_ref` to discover names first, then fetch the full declaration body
666
+ only when needed.
667
+
668
+ **Parameters:**
669
+
670
+ | Name | Type | Required | Description |
671
+ | :-------- | :------- | :------- | :------------------------------------------------------------------------------------- |
672
+ | `package` | `string` | Yes | NPM package name |
673
+ | `version` | `string` | Yes | NPM version string: exact version or published dist-tag (e.g., `"3.23.8"`, `"latest"`) |
674
+ | `name` | `string` | Yes | Exported identifier name (e.g., `"ZodType"`) |
675
+
676
+ ### `compare_versions`
677
+
678
+ > **See what changed between versions.**
679
+
680
+ Diffs the documentation structure between two versions of a package, showing
681
+ added, removed, and moved sections.
682
+
683
+ **Parameters:**
684
+
685
+ | Name | Type | Required | Description |
686
+ | :-------- | :------- | :------- | :------------------------------------------------------------------------------------- |
687
+ | `package` | `string` | Yes | NPM package name |
688
+ | `v_old` | `string` | Yes | NPM version string: exact version or published dist-tag (e.g., `"3.22.0"`, `"latest"`) |
689
+ | `v_new` | `string` | Yes | NPM version string: exact version or published dist-tag (e.g., `"3.23.8"`, `"latest"`) |
690
+
691
+ ---
692
+
693
+ ## How It Works
694
+
695
+ ```
696
+ You ask about express@4.18.2
697
+
698
+
699
+ ┌─────────────────┐
700
+ │ Your AI Agent │ "What middleware options are available?"
701
+ │ (Claude, etc.) │
702
+ └────────┬─────────┘
703
+ │ calls get_toc("express", "4.18.2")
704
+
705
+ ┌─────────────────┐
706
+ │ soupChop │ MCP Server (runs locally on stdio)
707
+ └────────┬─────────┘
708
+
709
+ ┌────┴─────────────────────────┐
710
+ │ Is it cached on disk? │
711
+ │ │
712
+ │ YES → read from │
713
+ │ ~/.cache/soup-chop/ │
714
+ │ express/4.18.2/README.md │
715
+ │ │
716
+ │ NO → fetch from │
717
+ │ unpkg.com/express@4.18.2/ │
718
+ │ README.md │
719
+ │ then cache it. │
720
+ └────┬─────────────────────────┘
721
+
722
+
723
+ ┌─────────────────┐
724
+ │ Remark AST │ Parses Markdown into a heading tree
725
+ │ Parser │ with line ranges for each section
726
+ └────────┬─────────┘
727
+
728
+
729
+ Structured TOC returned to the AI
730
+ (only metadata — not the full README)
731
+ ```
732
+
733
+ **Key design decisions:**
734
+
735
+ - **Version-scoped caching** — Each `package@version` pair is cached independently.
736
+ Since published NPM versions are immutable, the cache never goes stale.
737
+ - **No API keys required** — Everything runs locally. No LLM calls, no embeddings
738
+ API, no external services beyond UNPKG (a public CDN).
739
+ - **Surgical delivery** — The AI gets a *table of contents*, not the full README.
740
+ It can then request only the section it needs, keeping context windows lean.
741
+
742
+ ---
743
+
744
+ ## Configuration
745
+
746
+ ### Cache Location
747
+
748
+ soupChop uses [`env-paths`](https://github.com/sindresorhus/env-paths) to store
749
+ cached documentation in the standard OS-specific cache directory:
750
+
751
+ | OS | Path |
752
+ | :------ | :---------------------------------------- |
753
+ | Linux | `~/.cache/soup-chop/` |
754
+ | macOS | `~/Library/Caches/soup-chop/` |
755
+ | Windows | `%LOCALAPPDATA%\soup-chop\Cache\` |
756
+
757
+ Cache is organized as:
758
+
759
+ ```
760
+ ~/.cache/soup-chop/
761
+ ├── express/
762
+ │ └── 4.18.2/
763
+ │ └── README.md
764
+ ├── zod/
765
+ │ └── 3.23.8/
766
+ │ └── README.md
767
+ └── ...
768
+ ```
769
+
770
+ To clear the cache, simply delete the directory.
771
+
772
+ ---
773
+
774
+ ## For Library Authors
775
+
776
+ `soupChop` is designed to work with ordinary package docs. You do not need a special integration, custom metadata, or an MCP-specific format.
777
+
778
+ That said, some documentation patterns make retrieval much more reliable for both humans and AI agents:
779
+
780
+ ### Best Practices for Library Authors
781
+
782
+ #### Use Clear, Specific Headings
783
+
784
+ Prefer headings like `Authentication`, `Error Handling`, `Transactions`, or `React Integration` over vague titles like `Advanced` or `More`. Section-based retrieval works best when the heading already says what problem the section solves.
785
+
786
+ #### Keep Sections Focused
787
+
788
+ One section should usually answer one question well. Very large umbrella sections are harder to retrieve precisely than several smaller, well-named sections.
789
+
790
+ #### Document Important Concepts in Prose, Not Only in Examples
791
+
792
+ Short narrative explanations help retrieval and ranking much more than code alone. Keep examples, but explain what they demonstrate and when to use them.
793
+
794
+ #### Use Stable Terminology Consistently
795
+
796
+ If the product uses terms like `schema`, `resolver`, `adapter`, or `provider`, prefer one canonical term and reuse it throughout the docs. Synonym drift makes both human search and automated retrieval weaker.
797
+
798
+ #### Publish Package-Local Markdown When It Matters
799
+
800
+ `README.md` is a strong default, but additional docs such as `docs/*.md`, `API.md`, `FAQ.md`, or `MIGRATING.md` make specialized topics easier to isolate. Migration guides, upgrade notes, and troubleshooting docs are especially valuable.
801
+
802
+ #### Separate Version-Sensitive Material Clearly
803
+
804
+ If behavior changed in `v2`, say so explicitly in the relevant section. Dedicated upgrade or breaking-change sections are easier to retrieve than scattered notes.
805
+
806
+ #### Include Exact Names and Signatures Where Possible
807
+
808
+ Mention real option names, config keys, CLI flags, and exported identifiers. Precise tokens help users, search, and AI agents converge on the right section faster.
809
+
810
+ #### Prefer Descriptive Links and Filenames
811
+
812
+ `docs/authentication.md` and `docs/error-handling.md` are more useful than opaque file names. Good filenames also make multi-document corpora easier to navigate.
813
+
814
+ A good rule of thumb is simple: write docs so that a person can jump straight to the answer from the table of contents alone. If that works well for a human, it usually works well for `soupChop` too.
815
+
816
+ ---
817
+
818
+ ## Examples
819
+
820
+ ### Example 1 — Exploring a new library
821
+
822
+ > **You:** "I want to use `zod` for form validation. What does it offer?"
823
+ >
824
+ > **AI** *(calls `get_toc("zod", "3.23.8")`)*: "Here's what Zod's documentation
825
+ > covers: Introduction, Installation, Basic Usage, Primitives, Coercion, Literals,
826
+ > Strings, Numbers, ..."
827
+ >
828
+ > **You:** "Tell me about coercion."
829
+ >
830
+ > **AI** *(calls `get_topic("zod", "3.23.8", "Zod/Coercion")`)*: "Zod provides
831
+ > coercion methods that automatically transform input data..."
832
+
833
+ ### Example 2 — Debugging a version mismatch
834
+
835
+ > **You:** "This code worked in express 4 but breaks in express 5."
836
+ >
837
+ > **AI** *(calls `compare_versions("express", "4.18.2", "5.0.0")`)*: "Several
838
+ > sections have changed between these versions. The 'Middleware' section was
839
+ > reorganized and 'Error Handling' has new subsections..."
840
+
841
+ ### Example 3 — Getting accurate type information
842
+
843
+ > **You:** "What's the actual type signature for `z.object`?"
844
+ >
845
+ > **AI** *(calls `get_api_ref("zod", "3.23.8")`)*: "I found `object` in the
846
+ > published API index. It is exported as a function."
847
+ >
848
+ > **AI** *(calls `get_declaration("zod", "3.23.8", "object")`)*: "Here is the
849
+ > explicit declaration from the published type definitions..."
850
+
851
+ ---
852
+
853
+ ## Requirements
854
+
855
+ - **Node.js** 20 or later
856
+ - An MCP-compatible AI client (Claude Desktop, Cursor, Windsurf, etc.)
857
+
858
+ ---
859
+
860
+ ## FAQ
861
+
862
+ ### Why not just paste the README into the chat?
863
+
864
+ Three reasons:
865
+
866
+ 1. **Context window waste.** A typical README is 5,000–50,000 tokens. soupChop
867
+ delivers only the section the AI needs — often under 500 tokens.
868
+ 2. **Version accuracy.** You'd have to find and paste the README for the exact
869
+ version you're using. soupChop does this automatically.
870
+ 3. **Automation.** The AI can explore documentation *on its own*, without you
871
+ acting as a copy-paste intermediary.
872
+
873
+ ### Why UNPKG instead of the npm registry API?
874
+
875
+ UNPKG serves individual files from published packages via a simple URL scheme
876
+ (`unpkg.com/pkg@version/file`). The npm registry API returns package metadata
877
+ but not file contents directly. UNPKG gives us exactly what we need with a
878
+ single HTTP request.
879
+
880
+ ### Does this work with private packages?
881
+
882
+ Not yet. The current version only supports packages published to the public npm
883
+ registry via UNPKG. Private registry support is on the roadmap.
884
+
885
+ ### What if the package has no README?
886
+
887
+ soupChop returns a clear error message indicating that no README was found for
888
+ the requested package and version. The AI can then inform you and suggest
889
+ alternative documentation sources.
890
+
891
+ ### Is my data sent anywhere?
892
+
893
+ **No.** soupChop runs entirely on your machine. The only external request is to
894
+ `unpkg.com` to fetch package files — the same CDN used by millions of
895
+ developers daily. No telemetry, no analytics, no API keys.
896
+
897
+ ---
898
+
899
+ ## License
900
+
901
+ [MIT](LICENSE)