@stackline/tool-router 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.
- package/CHANGELOG.md +24 -0
- package/CONTRIBUTING.md +34 -0
- package/LICENSE +21 -0
- package/NOTICE +5 -0
- package/README.md +336 -0
- package/SECURITY.md +33 -0
- package/dist/index.cjs +1123 -0
- package/dist/index.cjs.map +7 -0
- package/dist/index.d.cts +247 -0
- package/dist/index.d.mts +247 -0
- package/dist/index.d.ts +247 -0
- package/dist/index.js +1102 -0
- package/dist/index.js.map +7 -0
- package/dist/index.min.js +3 -0
- package/dist/index.min.js.map +7 -0
- package/package.json +100 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented in this file. The format is
|
|
4
|
+
based on Keep a Changelog and the project follows Semantic Versioning.
|
|
5
|
+
|
|
6
|
+
## [1.0.0] - 2026-08-20
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
|
|
10
|
+
- Deterministic BM25F-style routing over names, namespaces, aliases, tags,
|
|
11
|
+
descriptions, and JSON Schema text.
|
|
12
|
+
- Automatic normalization for MCP, OpenAI Responses, OpenAI Chat, Anthropic,
|
|
13
|
+
Gemini, and canonical tool definitions.
|
|
14
|
+
- Bounded prefix completion, typo tolerance, uppercase acronym matching, and
|
|
15
|
+
weighted action-synonym expansion.
|
|
16
|
+
- `search`, `select`, and budget-aware `route` APIs with ranking evidence and
|
|
17
|
+
original-definition preservation.
|
|
18
|
+
- Incremental `add`, `remove`, `replace`, and `clear` catalog operations.
|
|
19
|
+
- Provider-shaped `createToolSearch` discovery helper.
|
|
20
|
+
- ESM, CommonJS, browser, TypeScript 3.9+, Deno, and Bun distributions.
|
|
21
|
+
- Security limits and regression coverage for prototype pollution, accessors,
|
|
22
|
+
cyclic schemas, oversized input, and malformed long queries.
|
|
23
|
+
- Reproducible benchmark corpus, public documentation, CI, CodeQL, package
|
|
24
|
+
smoke tests, and release artifact verification.
|
package/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Contributions should preserve deterministic routing, provider-shape
|
|
4
|
+
compatibility, bounded processing, and zero runtime dependencies.
|
|
5
|
+
|
|
6
|
+
## Development
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
npm install
|
|
10
|
+
npm test
|
|
11
|
+
npm run test:attw
|
|
12
|
+
npm run benchmark
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Node.js 20.20.0 is the reference development runtime. The CI matrix validates
|
|
16
|
+
the published artifact on every supported Node.js line plus Deno, Bun,
|
|
17
|
+
CommonJS, ESM, and multiple TypeScript versions.
|
|
18
|
+
|
|
19
|
+
## Pull requests
|
|
20
|
+
|
|
21
|
+
- Add a focused regression test for behavior changes.
|
|
22
|
+
- Keep provider definitions unchanged unless an API explicitly promises a
|
|
23
|
+
conversion.
|
|
24
|
+
- Do not add a runtime dependency without a documented architecture review.
|
|
25
|
+
- Report ranking changes against the transparent evaluation corpus.
|
|
26
|
+
- Avoid hard timing assertions that become unstable on shared CI runners.
|
|
27
|
+
- Update README and architecture documentation for public API changes.
|
|
28
|
+
|
|
29
|
+
Run `npm test`, `npm run test:attw`, and `npm run audit:dependencies` before
|
|
30
|
+
requesting review.
|
|
31
|
+
|
|
32
|
+
## Security
|
|
33
|
+
|
|
34
|
+
Do not open public issues for vulnerabilities. Follow SECURITY.md.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Alexandro Paixao Marques
|
|
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.
|
package/NOTICE
ADDED
package/README.md
ADDED
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
# @stackline/tool-router
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@stackline/tool-router)
|
|
4
|
+
[](https://www.npmjs.com/package/@stackline/tool-router)
|
|
5
|
+
[](https://github.com/alexandroit/stackline-tool-router/actions/workflows/ci.yml)
|
|
6
|
+
[](https://github.com/alexandroit/stackline-tool-router/actions/workflows/codeql.yml)
|
|
7
|
+
[](LICENSE)
|
|
8
|
+
|
|
9
|
+
Route a user request to the smallest relevant subset of an AI tool catalog.
|
|
10
|
+
The router is local, deterministic, zero-dependency, and understands MCP,
|
|
11
|
+
OpenAI, Anthropic, Gemini, and provider-neutral definitions.
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install @stackline/tool-router
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Quick start
|
|
18
|
+
|
|
19
|
+
```js
|
|
20
|
+
import { createToolRouter } from '@stackline/tool-router';
|
|
21
|
+
|
|
22
|
+
const tools = [
|
|
23
|
+
{
|
|
24
|
+
type: 'function',
|
|
25
|
+
name: 'github_create_issue',
|
|
26
|
+
description: 'Create a GitHub issue in a repository.',
|
|
27
|
+
parameters: {
|
|
28
|
+
type: 'object',
|
|
29
|
+
properties: {
|
|
30
|
+
repository: { type: 'string' },
|
|
31
|
+
title: { type: 'string' }
|
|
32
|
+
},
|
|
33
|
+
required: ['repository', 'title'],
|
|
34
|
+
additionalProperties: false
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
type: 'function',
|
|
39
|
+
name: 'slack_send_message',
|
|
40
|
+
description: 'Send a message to a Slack channel.',
|
|
41
|
+
parameters: {
|
|
42
|
+
type: 'object',
|
|
43
|
+
properties: {
|
|
44
|
+
channel: { type: 'string' },
|
|
45
|
+
text: { type: 'string' }
|
|
46
|
+
},
|
|
47
|
+
required: ['channel', 'text'],
|
|
48
|
+
additionalProperties: false
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
];
|
|
52
|
+
|
|
53
|
+
const router = createToolRouter(tools);
|
|
54
|
+
const prompt = 'Open an issue for the checkout regression';
|
|
55
|
+
const routed = router.route(prompt, { maxTools: 4 });
|
|
56
|
+
|
|
57
|
+
// The original OpenAI definitions are returned by reference.
|
|
58
|
+
const response = await openai.responses.create({
|
|
59
|
+
model: 'your-model',
|
|
60
|
+
input: prompt,
|
|
61
|
+
tools: routed.tools
|
|
62
|
+
});
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
No provider SDK is required by the package. Route first, then pass
|
|
66
|
+
`routed.tools` to the SDK already used by the application.
|
|
67
|
+
|
|
68
|
+
## Why route tools
|
|
69
|
+
|
|
70
|
+
Large tool catalogs create three practical problems:
|
|
71
|
+
|
|
72
|
+
- definitions consume context before the task starts;
|
|
73
|
+
- similar tools become harder for a model to distinguish;
|
|
74
|
+
- sending every schema increases request size, latency, and cost.
|
|
75
|
+
|
|
76
|
+
`@stackline/tool-router` builds an in-memory BM25F-style index over names,
|
|
77
|
+
namespaces, aliases, tags, descriptions, and JSON Schema text. It adds bounded
|
|
78
|
+
prefix matching, typo tolerance, uppercase acronym recognition, and a small
|
|
79
|
+
action-synonym layer. Literal name and namespace matches remain stronger than
|
|
80
|
+
synonym matches.
|
|
81
|
+
|
|
82
|
+
The router never calls a model, embedding endpoint, database, or network
|
|
83
|
+
service. The same catalog and query produce the same ordering.
|
|
84
|
+
|
|
85
|
+
## Supported definitions
|
|
86
|
+
|
|
87
|
+
| Source | Recognized shape | Returned by `route()` |
|
|
88
|
+
| --- | --- | --- |
|
|
89
|
+
| MCP | `{ name, inputSchema }` | original MCP tool |
|
|
90
|
+
| OpenAI Responses | `{ type: 'function', name, parameters }` | original Responses tool |
|
|
91
|
+
| OpenAI Chat | `{ type: 'function', function: { ... } }` | original Chat tool |
|
|
92
|
+
| Anthropic | `{ name, input_schema }` | original Anthropic tool |
|
|
93
|
+
| Gemini | `{ name, parameters }` or `functionDeclarations` | original Gemini declaration |
|
|
94
|
+
| Canonical | `{ name, inputSchema }` or `{ name, schema }` | original object |
|
|
95
|
+
|
|
96
|
+
Provider envelopes are accepted directly:
|
|
97
|
+
|
|
98
|
+
```js
|
|
99
|
+
const openaiRouter = createToolRouter({ tools: openaiTools });
|
|
100
|
+
const geminiRouter = createToolRouter({ functionDeclarations });
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Keep one provider-compatible catalog per outbound request. The package
|
|
104
|
+
normalizes definitions for retrieval; it does not rewrite JSON Schema dialects
|
|
105
|
+
or convert one provider's wire format into another.
|
|
106
|
+
|
|
107
|
+
## Search and route
|
|
108
|
+
|
|
109
|
+
Use `search` when ranking evidence matters:
|
|
110
|
+
|
|
111
|
+
```js
|
|
112
|
+
const matches = router.search('post the release note in Slack', {
|
|
113
|
+
limit: 5,
|
|
114
|
+
namespaces: ['slack'],
|
|
115
|
+
tags: ['write']
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
for (const match of matches) {
|
|
119
|
+
console.log(match.name, match.score, match.matchedFields);
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Use `select` for only the original definitions:
|
|
124
|
+
|
|
125
|
+
```js
|
|
126
|
+
const tools = router.select('find the Q4 plan in Drive', { limit: 3 });
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Use `route` for production request controls:
|
|
130
|
+
|
|
131
|
+
```js
|
|
132
|
+
const result = router.route(userMessage, {
|
|
133
|
+
maxTools: 6,
|
|
134
|
+
maxEstimatedTokens: 4_000,
|
|
135
|
+
pinned: ['auth_get_current_user'],
|
|
136
|
+
fallback: 'none'
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
console.log({
|
|
140
|
+
selected: result.selectedCount,
|
|
141
|
+
estimatedTokens: result.estimatedTokens,
|
|
142
|
+
estimatedReduction: result.tokenReduction
|
|
143
|
+
});
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Pinned tools are always included before ranked tools. If pinned definitions
|
|
147
|
+
exceed the token budget, `budgetExceeded` is `true`; explicit policy is never
|
|
148
|
+
silently discarded.
|
|
149
|
+
|
|
150
|
+
Token counts are transparent estimates based on JSON character length divided
|
|
151
|
+
by four. They are useful for relative budgets, not a replacement for a
|
|
152
|
+
provider-specific tokenizer.
|
|
153
|
+
|
|
154
|
+
## Dynamic catalogs
|
|
155
|
+
|
|
156
|
+
Updates maintain postings and document frequencies without rebuilding the
|
|
157
|
+
router:
|
|
158
|
+
|
|
159
|
+
```js
|
|
160
|
+
const router = createToolRouter([], { onDuplicate: 'replace' });
|
|
161
|
+
|
|
162
|
+
router.add(tool);
|
|
163
|
+
router.add(updatedTool); // replaces the same id
|
|
164
|
+
router.remove('github_create_issue');
|
|
165
|
+
router.replace(await loadCurrentCatalog());
|
|
166
|
+
router.clear();
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
By default, duplicate IDs throw `ERR_TOOL_DUPLICATE`. Tool IDs use an explicit
|
|
170
|
+
`id` when present, otherwise `namespace:name`, otherwise `name`.
|
|
171
|
+
|
|
172
|
+
## BYOT discovery helper
|
|
173
|
+
|
|
174
|
+
`createToolSearch` creates a compact search function and an executor for
|
|
175
|
+
bring-your-own-tool discovery loops:
|
|
176
|
+
|
|
177
|
+
```js
|
|
178
|
+
import { createToolSearch, createToolRouter } from '@stackline/tool-router';
|
|
179
|
+
|
|
180
|
+
const router = createToolRouter(mcpTools);
|
|
181
|
+
const discovery = createToolSearch(router, {
|
|
182
|
+
target: 'mcp',
|
|
183
|
+
limit: 5
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
console.log(discovery.definition);
|
|
187
|
+
console.log(discovery.execute({ query: 'search production errors' }));
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Targets are `canonical`, `mcp`, `openai-responses`, `openai-chat`,
|
|
191
|
+
`anthropic`, and `gemini`. The executor returns compact summaries, not full
|
|
192
|
+
schemas. Applications decide how selected tools are admitted into the next
|
|
193
|
+
model request.
|
|
194
|
+
|
|
195
|
+
## Ranking controls
|
|
196
|
+
|
|
197
|
+
Default field weights favor intent-bearing identifiers:
|
|
198
|
+
|
|
199
|
+
| Field | Weight |
|
|
200
|
+
| --- | ---: |
|
|
201
|
+
| name | 10 |
|
|
202
|
+
| namespace | 8 |
|
|
203
|
+
| aliases | 7 |
|
|
204
|
+
| tags | 5 |
|
|
205
|
+
| description | 2 |
|
|
206
|
+
| schema | 1 |
|
|
207
|
+
|
|
208
|
+
Override only what the catalog needs:
|
|
209
|
+
|
|
210
|
+
```js
|
|
211
|
+
const router = createToolRouter(tools, {
|
|
212
|
+
fieldWeights: {
|
|
213
|
+
tags: 8,
|
|
214
|
+
schema: 2
|
|
215
|
+
},
|
|
216
|
+
fuzzy: true,
|
|
217
|
+
k1: 1.2,
|
|
218
|
+
b: 0.75
|
|
219
|
+
});
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
The built-in English action synonyms cover common tool verbs such as
|
|
223
|
+
`find/search`, `send/post`, `create/open`, and `change/update`. Extend them:
|
|
224
|
+
|
|
225
|
+
```js
|
|
226
|
+
const router = createToolRouter(tools, {
|
|
227
|
+
synonyms: {
|
|
228
|
+
archive: ['store', 'retain'],
|
|
229
|
+
deploy: ['release', 'ship']
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
Set `synonyms: false` for literal-only retrieval. Custom tokenizers are also
|
|
235
|
+
supported and receive both indexed text and queries.
|
|
236
|
+
|
|
237
|
+
## Catalog metadata
|
|
238
|
+
|
|
239
|
+
Canonical metadata improves routing without changing provider payloads:
|
|
240
|
+
|
|
241
|
+
```js
|
|
242
|
+
const tool = {
|
|
243
|
+
id: 'github:pull-request:create',
|
|
244
|
+
namespace: 'github',
|
|
245
|
+
tags: ['git', 'write'],
|
|
246
|
+
aliases: ['open pull request', 'new PR'],
|
|
247
|
+
name: 'github_create_pull_request',
|
|
248
|
+
description: 'Create a pull request from one branch into another.',
|
|
249
|
+
inputSchema: { type: 'object', properties: {} }
|
|
250
|
+
};
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
For provider definitions, metadata can be placed on the outer tool object.
|
|
254
|
+
The original object is returned unchanged and by reference.
|
|
255
|
+
|
|
256
|
+
## API
|
|
257
|
+
|
|
258
|
+
| Export | Purpose |
|
|
259
|
+
| --- | --- |
|
|
260
|
+
| `createToolRouter(tools, options)` | build a mutable in-memory router |
|
|
261
|
+
| `router.search(query, options)` | ranked matches with evidence |
|
|
262
|
+
| `router.select(query, options)` | original tool definitions only |
|
|
263
|
+
| `router.route(query, options)` | selected tools plus budget metrics |
|
|
264
|
+
| `router.add/remove/replace/clear` | update a live catalog |
|
|
265
|
+
| `router.get/list/has/stats` | inspect the normalized catalog |
|
|
266
|
+
| `routeTools(tools, query, options)` | one-shot routing helper |
|
|
267
|
+
| `createToolSearch(router, options)` | provider-shaped discovery function |
|
|
268
|
+
| `normalizeTool/normalizeTools` | inspect canonical retrieval records |
|
|
269
|
+
| `detectToolFormat(tool)` | detect a supported provider shape |
|
|
270
|
+
| `estimateToolTokens(tool)` | bounded provider-neutral size estimate |
|
|
271
|
+
| `tokenize/normalizeText` | use the default text pipeline directly |
|
|
272
|
+
|
|
273
|
+
Every validation error is a `ToolRouterError` with a stable `code` beginning
|
|
274
|
+
with `ERR_TOOL_`.
|
|
275
|
+
|
|
276
|
+
## Evaluation and performance
|
|
277
|
+
|
|
278
|
+
The repository includes the complete corpus and benchmark command:
|
|
279
|
+
|
|
280
|
+
```bash
|
|
281
|
+
npm run benchmark
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
The 1.0.0 release baseline on the maintainer workstation:
|
|
285
|
+
|
|
286
|
+
- 30-tool, 30-query transparent intent corpus: recall@1 `100%`, recall@5 `100%`;
|
|
287
|
+
- average estimated catalog-token reduction when selecting five tools: `85.28%`;
|
|
288
|
+
- 10,000-tool synthetic catalog: build about `759 ms`;
|
|
289
|
+
- 10,000-tool catalog search: about `67 ms` p50 and `109 ms` p95.
|
|
290
|
+
|
|
291
|
+
These numbers are implementation baselines, not universal guarantees. Hardware,
|
|
292
|
+
catalog vocabulary, descriptions, aliases, and query distribution materially
|
|
293
|
+
change the result. Run the included benchmark with representative tools before
|
|
294
|
+
choosing production limits.
|
|
295
|
+
|
|
296
|
+
## Security and limits
|
|
297
|
+
|
|
298
|
+
Tool definitions are untrusted input. The implementation:
|
|
299
|
+
|
|
300
|
+
- uses `Map` and null-prototype records for internal dictionaries;
|
|
301
|
+
- ignores `__proto__`, `prototype`, and `constructor` during schema traversal;
|
|
302
|
+
- reads own data properties without invoking getters;
|
|
303
|
+
- detects cyclic JSON definitions;
|
|
304
|
+
- bounds catalog size, schema depth, schema nodes, text, query length, token
|
|
305
|
+
expansion, and edit distance;
|
|
306
|
+
- uses no user-built regular expressions and no catastrophic-backtracking
|
|
307
|
+
patterns;
|
|
308
|
+
- has zero runtime dependencies and performs no network access.
|
|
309
|
+
|
|
310
|
+
Defaults are intended for ordinary provider schemas. Raise limits only for a
|
|
311
|
+
catalog that has already been validated. See [SECURITY.md](SECURITY.md) for
|
|
312
|
+
private vulnerability reporting.
|
|
313
|
+
|
|
314
|
+
## Compatibility
|
|
315
|
+
|
|
316
|
+
- Node.js 14.17 and newer;
|
|
317
|
+
- ESM and CommonJS;
|
|
318
|
+
- browsers through the `StacklineToolRouter` global build;
|
|
319
|
+
- TypeScript 3.9 through current releases;
|
|
320
|
+
- Deno and Bun through the ESM build;
|
|
321
|
+
- no runtime dependencies.
|
|
322
|
+
|
|
323
|
+
Detailed runtime and declaration guarantees are in
|
|
324
|
+
[docs/COMPATIBILITY.md](docs/COMPATIBILITY.md).
|
|
325
|
+
|
|
326
|
+
## Documentation
|
|
327
|
+
|
|
328
|
+
- [Live routing workbench](https://alexandro.net/docs/vanilla/tool-router/)
|
|
329
|
+
- [Architecture](docs/ARCHITECTURE.md)
|
|
330
|
+
- [Market research](docs/MARKET_RESEARCH.md)
|
|
331
|
+
- [Changelog](CHANGELOG.md)
|
|
332
|
+
- [Contributing](CONTRIBUTING.md)
|
|
333
|
+
|
|
334
|
+
## License
|
|
335
|
+
|
|
336
|
+
[MIT](LICENSE)
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## Supported versions
|
|
4
|
+
|
|
5
|
+
| Version | Supported |
|
|
6
|
+
| --- | --- |
|
|
7
|
+
| 1.x | Yes |
|
|
8
|
+
| 0.x | No public release |
|
|
9
|
+
|
|
10
|
+
## Reporting a vulnerability
|
|
11
|
+
|
|
12
|
+
Use the repository's private GitHub security advisory form:
|
|
13
|
+
|
|
14
|
+
https://github.com/alexandroit/stackline-tool-router/security/advisories/new
|
|
15
|
+
|
|
16
|
+
Include the affected version, minimal reproduction, impact, and any proposed
|
|
17
|
+
mitigation. Do not disclose the issue publicly before a coordinated fix is
|
|
18
|
+
available.
|
|
19
|
+
|
|
20
|
+
## Security boundaries
|
|
21
|
+
|
|
22
|
+
The package ranks tool definitions. It does not authenticate tool calls,
|
|
23
|
+
authorize actions, validate tool arguments against JSON Schema, execute tools,
|
|
24
|
+
or make outbound requests. Applications remain responsible for those controls.
|
|
25
|
+
|
|
26
|
+
Definitions are treated as untrusted during indexing. Dangerous prototype
|
|
27
|
+
keys and accessors are not traversed, internal dictionaries avoid ordinary
|
|
28
|
+
object prototypes, cyclic definitions are rejected, and size/depth limits are
|
|
29
|
+
enabled by default.
|
|
30
|
+
|
|
31
|
+
No package can promise universal freedom from vulnerabilities. Consumers
|
|
32
|
+
should pin reviewed versions, inspect release notes, run their own audit, and
|
|
33
|
+
apply application-specific security controls.
|