@mcp-index/sdk 0.14.0 → 0.15.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 +63 -41
- package/README.md +24 -20
- package/dist/src/canonical.d.ts +4 -0
- package/dist/src/canonical.d.ts.map +1 -1
- package/dist/src/canonical.js +54 -17
- package/dist/src/canonical.js.map +1 -1
- package/dist/src/gate.d.ts +17 -0
- package/dist/src/gate.d.ts.map +1 -1
- package/dist/src/gate.js +184 -16
- package/dist/src/gate.js.map +1 -1
- package/dist/src/index.d.ts +2 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +2 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/listingFilter.d.ts +38 -0
- package/dist/src/listingFilter.d.ts.map +1 -0
- package/dist/src/listingFilter.js +174 -0
- package/dist/src/listingFilter.js.map +1 -0
- package/dist/src/preflight.d.ts +19 -0
- package/dist/src/preflight.d.ts.map +1 -1
- package/dist/src/preflight.js +237 -0
- package/dist/src/preflight.js.map +1 -1
- package/dist/src/schemaDiff.d.ts +5 -0
- package/dist/src/schemaDiff.d.ts.map +1 -1
- package/dist/src/schemaDiff.js +66 -16
- package/dist/src/schemaDiff.js.map +1 -1
- package/dist/src/wrap.d.ts +17 -9
- package/dist/src/wrap.d.ts.map +1 -1
- package/dist/src/wrap.js +126 -16
- package/dist/src/wrap.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,10 +1,32 @@
|
|
|
1
|
-
# Changelog
|
|
1
|
+
# Changelog - @mcp-index/sdk
|
|
2
2
|
|
|
3
3
|
All notable changes to the TypeScript SDK. Versioning is semver (0.x: minor =
|
|
4
4
|
additive feature, patch = fix). Backward-compatible additions only in 0.2.0.
|
|
5
5
|
|
|
6
6
|
## [Unreleased]
|
|
7
7
|
|
|
8
|
+
## 0.15.0 - 2026-10-05
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- Under guard and strict, a tool whose description or input-schema text changed is left out of the tool list, and a call to that tool holds until it is reviewed.
|
|
13
|
+
- Monitor still shows the full list.
|
|
14
|
+
- When you pass a `serverId`, pins are kept on disk by default, under `MCPINDEX_STATE_DIR/pins/<server id>.json` or `~/.mcpindex/pins/<server id>.json`, and survive a restart. Without a `serverId` they stay in memory, as before, so unnamed sessions never share a pin file. `pinStore: "memory"` or `pinStore: "file"` overrides either default.
|
|
15
|
+
- These fields are not yet covered, so a change in only one of them still reaches the host: tool title, icons, _meta, annotations.title, a new annotation key, and first-time outputSchema text on an otherwise unchanged tool.
|
|
16
|
+
- The SDK client's listChanged refresh calls the inner client, so that refresh is not filtered.
|
|
17
|
+
- A list longer than 2,000 tools, or a list the gate cannot filter, comes back with every tool left out. It does not throw.
|
|
18
|
+
|
|
19
|
+
## 0.14.1 - 2026-10-04
|
|
20
|
+
|
|
21
|
+
### Security
|
|
22
|
+
|
|
23
|
+
- Fixes GHSA-g737-65vx-q7qm (https://github.com/mcpindex-ai/mcpindex-sdk-ts/security/advisories/GHSA-g737-65vx-q7qm), cases where a changed tool contract was treated as unchanged or auto-accepted. Affected: @mcp-index/sdk < 0.14.1 and mcpindex-gate < 0.16.1.
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
|
|
27
|
+
- Some changes that used to auto-accept now hold for review.
|
|
28
|
+
- Tool hashes for existing pins are unchanged.
|
|
29
|
+
|
|
8
30
|
## 0.14.0 - 2026-10-02
|
|
9
31
|
|
|
10
32
|
### Changed
|
|
@@ -122,7 +144,7 @@ classifications on the measured corpus.
|
|
|
122
144
|
|
|
123
145
|
New export: `isNumericOnlyDescriptionChange(before, after)`.
|
|
124
146
|
|
|
125
|
-
## 0.10.0
|
|
147
|
+
## 0.10.0 - 2026-08-05
|
|
126
148
|
|
|
127
149
|
**The HOLD text an agent reads is now separate from the one a human reads.** Behaviour
|
|
128
150
|
change on a shipped surface: `PreflightHold.message` (and the proxy's JSON-RPC error
|
|
@@ -130,22 +152,22 @@ change on a shipped surface: `PreflightHold.message` (and the proxy's JSON-RPC e
|
|
|
130
152
|
|
|
131
153
|
Why: on 2026-08-05 a frontier model met a real HOLD, classified the banner as a
|
|
132
154
|
prompt-injection attempt, refused to act on it, retried the held call, and told the user
|
|
133
|
-
something suspicious was intercepting its tools. Its load-bearing objection was not tone
|
|
155
|
+
something suspicious was intercepting its tools. Its load-bearing objection was not tone -
|
|
134
156
|
it could not verify us. The gate diffs the pin against the LIVE contract while the agent
|
|
135
157
|
sees only its own cached tool list, a third view that legitimately disagrees. We were
|
|
136
158
|
asserting a change the reader could not observe and then inviting it to act, which is the
|
|
137
159
|
shape of a manipulation attempt. Refusing was correct behaviour.
|
|
138
160
|
|
|
139
|
-
- **Added** `renderHoldMessage()`
|
|
161
|
+
- **Added** `renderHoldMessage()` - the agent-facing text. Renders the drift as an evidence
|
|
140
162
|
block (tool / change + path / effect / call sent), names the stale-tool-list mismatch
|
|
141
163
|
before the agent trips over it, and states the disposition without inviting any action.
|
|
142
|
-
- **Added** `PreflightHold.presentation`
|
|
164
|
+
- **Added** `PreflightHold.presentation` - the human brand banner, kept off `message`.
|
|
143
165
|
`String(err)` is what a builder is most likely to hand to a model.
|
|
144
|
-
- **Unchanged** `renderHoldBanner()` and `holdBanner()`
|
|
166
|
+
- **Unchanged** `renderHoldBanner()` and `holdBanner()` - same text, same meaning, for
|
|
145
167
|
humans and hosts.
|
|
146
|
-
- **Security:** the agent-facing message may only CONSTRAIN. `[Review
|
|
147
|
-
invited the reader toward `repin()`
|
|
148
|
-
new trusted baseline
|
|
168
|
+
- **Security:** the agent-facing message may only CONSTRAIN. `[Review | Re-pin | Validate]`
|
|
169
|
+
invited the reader toward `repin()` - the one action that makes a changed contract the
|
|
170
|
+
new trusted baseline - on a channel the agent must treat as attacker-controlled. That is
|
|
149
171
|
the text an attacker would forge; forging "stop and ask your human" earns them nothing.
|
|
150
172
|
- **Security:** no defence was traded away to get there. `mdText` escaping and
|
|
151
173
|
`redactGreenWords` now run per untrusted value rather than over the whole render, so they
|
|
@@ -153,13 +175,13 @@ shape of a manipulation attempt. Refusing was correct behaviour.
|
|
|
153
175
|
(`VALUE_CHAR_CAP`), closing an unbounded-render vector a security audit measured at 5.2 MB
|
|
154
176
|
from a 1.6 MB hostile tool name.
|
|
155
177
|
- **Fixed** (audit HIGH) `holdBanner()` fell through to the full detail banner when the
|
|
156
|
-
provenance choke refused or on an internal-error verdict
|
|
178
|
+
provenance choke refused or on an internal-error verdict - asserting a specific contract
|
|
157
179
|
change that, in the latter case, never happened. It now returns the generic notice, as
|
|
158
180
|
Python always did.
|
|
159
181
|
- **Fixed** evidence rows sort by codepoint, not `localeCompare`, so the two SDKs cannot
|
|
160
182
|
render different evidence for identical drift.
|
|
161
183
|
|
|
162
|
-
## 0.9.2
|
|
184
|
+
## 0.9.2 - 2026-07-29
|
|
163
185
|
|
|
164
186
|
Copy only, no behaviour change.
|
|
165
187
|
|
|
@@ -170,22 +192,22 @@ Copy only, no behaviour change.
|
|
|
170
192
|
- `package.json` description likewise names mcpindex.ai + the category; added
|
|
171
193
|
`mcpindex` keyword. Lockfile version resynced (was stale at 0.7.0).
|
|
172
194
|
|
|
173
|
-
## 0.9.1
|
|
195
|
+
## 0.9.1 - 2026-07-18
|
|
174
196
|
|
|
175
197
|
### Fixed
|
|
176
|
-
- **`wrap(session)` now works with no options
|
|
198
|
+
- **`wrap(session)` now works with no options - the README quickstart is honest
|
|
177
199
|
again.** `pin` and `serverId` are now OPTIONAL: when omitted, `wrap()` creates an
|
|
178
200
|
ephemeral in-memory `PreflightPin()` under the new `DEFAULT_SERVER_ID` ("mcp") and
|
|
179
201
|
pins each tool trust-on-first-use. Previously `wrap(session)` threw
|
|
180
202
|
`TypeError: Cannot read properties of undefined (reading 'pin')`, and
|
|
181
203
|
`wrap(session, { scanResults: true, onHold })` (no pin/serverId) HELD **every** call
|
|
182
204
|
with the internal-error banner. Security posture is unchanged: a missing pin
|
|
183
|
-
pins-on-first-use (TOFU) and HOLDs on drift
|
|
205
|
+
pins-on-first-use (TOFU) and HOLDs on drift - it never fails open. Pass an explicit
|
|
184
206
|
`{ pin, serverId }` for a durable/shared baseline or fleet telemetry.
|
|
185
207
|
- Exported `DEFAULT_SERVER_ID` for callers that want to reference the default pin
|
|
186
208
|
namespace explicitly.
|
|
187
209
|
|
|
188
|
-
## 0.9.0
|
|
210
|
+
## 0.9.0 - 2026-07-14
|
|
189
211
|
|
|
190
212
|
### Added
|
|
191
213
|
- **`mcpindex login` CLI.** New `mcpindex` bin with `login` / `whoami`. `login` opens
|
|
@@ -195,14 +217,14 @@ Copy only, no behaviour change.
|
|
|
195
217
|
callback is bound to a per-session nonce carried in the loopback path (closes
|
|
196
218
|
key-fixation); the key never transits a third party. `MCPINDEX_WEB_BASE` overrides the
|
|
197
219
|
default host. `whoami` reports sign-in state without ever printing the key.
|
|
198
|
-
- **`--provider github|google`** on `mcpindex login` (default `github`)
|
|
220
|
+
- **`--provider github|google`** on `mcpindex login` (default `github`) - selects the
|
|
199
221
|
identity provider; the loopback/nonce handoff is provider-agnostic.
|
|
200
222
|
|
|
201
|
-
## 0.7.0
|
|
223
|
+
## 0.7.0 - 2026-07-12
|
|
202
224
|
|
|
203
225
|
### Added
|
|
204
226
|
- **Result-content scanning (`scanResults`).** New opt-in gate that scans tool
|
|
205
|
-
RESULT content
|
|
227
|
+
RESULT content - text blocks and `structuredContent` - for prompt-injection,
|
|
206
228
|
exfiltration, and credential-path markers, giving TS parity with the Python
|
|
207
229
|
client. **Default OFF** (zero behavior change): a hostile result passes through
|
|
208
230
|
untouched unless enabled. When ON, a tainted result is WITHHELD under `GUARD`/
|
|
@@ -221,12 +243,12 @@ Copy only, no behaviour change.
|
|
|
221
243
|
`resource_link` URI is no longer a false positive; the scan budget is shared
|
|
222
244
|
across `content[]` + structured so a large result can't evade the cap.
|
|
223
245
|
|
|
224
|
-
## 0.6.1
|
|
246
|
+
## 0.6.1 - 2026-06-11
|
|
225
247
|
|
|
226
248
|
### Added
|
|
227
249
|
- **Read-only `lookup` telemetry mode.** `MCPINDEX_DRIFT_TELEMETRY` gains `lookup`
|
|
228
250
|
(vocabulary is now `off | lookup | detection | contribute`). `lookup` RECEIVES fleet
|
|
229
|
-
drift warnings (the salted-fingerprint query) while SENDING nothing
|
|
251
|
+
drift warnings (the salted-fingerprint query) while SENDING nothing - the gate splits the
|
|
230
252
|
former single switch into `readEnabled()` (any non-off mode) and `sendEnabled()`
|
|
231
253
|
(detection/contribute only), with a re-check at the enqueue boundary. Cross-language
|
|
232
254
|
parity with the Python client. Default stays `off` (zero egress).
|
|
@@ -236,7 +258,7 @@ Copy only, no behaviour change.
|
|
|
236
258
|
list) now name the `sdk` tag (`py`/`ts`) that the wire payload already includes, and
|
|
237
259
|
document `lookup` as low-egress (not zero-egress). Kept byte-identical to the Python notice.
|
|
238
260
|
|
|
239
|
-
## 0.6.0
|
|
261
|
+
## 0.6.0 - 2026-06-09
|
|
240
262
|
|
|
241
263
|
### Added
|
|
242
264
|
- **Fleet drift query (M3, "warns you on call 1").** On first pin the gate fire-and-forgets a
|
|
@@ -246,11 +268,11 @@ Copy only, no behaviour change.
|
|
|
246
268
|
fingerprint is the one already emitted), fail-open, AD-6-safe (never moves PROCEED/HOLD;
|
|
247
269
|
redirects hard-off). Exported: `driftQuery`, `FleetAdvisory`; surfaced by `renderVerdict`.
|
|
248
270
|
|
|
249
|
-
## 0.5.0
|
|
271
|
+
## 0.5.0 - 2026-06-09
|
|
250
272
|
|
|
251
273
|
### Added
|
|
252
274
|
- **Drift telemetry (M1, opt-in, OFF by default).** On a tool pin or a contract drift the
|
|
253
|
-
gate can emit one one-way signal
|
|
275
|
+
gate can emit one one-way signal - salted (HMAC) fingerprints of the server/tool id, the
|
|
254
276
|
contract hashes, the change type, a safety flag, an hour-rounded time, and a random install
|
|
255
277
|
id. Never a schema, argument, description, URL, or server/tool name. Enable with
|
|
256
278
|
`MCPINDEX_DRIFT_TELEMETRY=detection`; fail-open (never blocks or changes a tool call). The
|
|
@@ -261,45 +283,45 @@ Copy only, no behaviour change.
|
|
|
261
283
|
classification) shipped in 0.4.0, with the `MCPINDEX_ACTION_CLASSIFICATION_ENABLED=0`
|
|
262
284
|
opt-out. (0.4.0 published before the README caught up.)
|
|
263
285
|
|
|
264
|
-
## 0.4.0
|
|
286
|
+
## 0.4.0 - 2026-06-08
|
|
265
287
|
|
|
266
288
|
### Added
|
|
267
289
|
- **Local Tier-0a action classification (blast radius).** The gate now COMPUTES the
|
|
268
|
-
advisory `actionClassification` block locally from the live tool definition
|
|
269
|
-
type, resource, side-effect, reversibility, egress, and a static autonomy ceiling
|
|
290
|
+
advisory `actionClassification` block locally from the live tool definition - action
|
|
291
|
+
type, resource, side-effect, reversibility, egress, and a static autonomy ceiling -
|
|
270
292
|
instead of leaving it `null` until a hosted verdict supplied one. So the blast-radius
|
|
271
293
|
grade is on by default in the SDK, at parity with the Python `mcpindex-gate`
|
|
272
294
|
client. Default-on; opt out with `MCPINDEX_ACTION_CLASSIFICATION_ENABLED=0`. Pure,
|
|
273
295
|
deterministic, total, and a byte-for-byte port of the Python `cse.action_class.classify`
|
|
274
|
-
(12-case cross-language golden parity test). **Advisory only**
|
|
296
|
+
(12-case cross-language golden parity test). **Advisory only** - it rides alongside the
|
|
275
297
|
decision and never moves `PROCEED`/`HOLD` (AD-1). New exports: `classifyAction`,
|
|
276
298
|
`classifyToolDef`, `actionClassificationEnabled`, and the `ActionType` /
|
|
277
299
|
`SideEffectClass` / `Reversibility` / `Egress` / `ScopeHint` / `PatternShape` /
|
|
278
300
|
`AutonomyCeiling` / `NoteClass` / `Severity` / `EvidenceRefType` enums.
|
|
279
301
|
|
|
280
|
-
## 0.3.2
|
|
302
|
+
## 0.3.2 - 2026-06-08
|
|
281
303
|
|
|
282
304
|
### Fixed
|
|
283
|
-
- **Schema-content scanner no longer false-flags benign URLs**
|
|
305
|
+
- **Schema-content scanner no longer false-flags benign URLs** - the exfil tripwire
|
|
284
306
|
(`scanSchemaHasMarker`) had a bare `https?://` rule that flagged any URL in a tool's
|
|
285
307
|
declared schema as a CRITICAL exfil marker. A real crawl tripped it on a benign
|
|
286
308
|
`web_url_reader` whose `url` param carried example URLs. A URL now signals exfil only
|
|
287
|
-
in an exfil-verb context (`forward
|
|
309
|
+
in an exfil-verb context (`forward ... https://...`); example/doc URLs are clean.
|
|
288
310
|
Credential-path and injection detection unchanged. Mirrors the Python `schema_scan` fix.
|
|
289
311
|
|
|
290
|
-
## 0.3.1
|
|
312
|
+
## 0.3.1 - 2026-06-08
|
|
291
313
|
|
|
292
314
|
### Changed
|
|
293
|
-
- **Ambient line reworded `watching`
|
|
315
|
+
- **Ambient line reworded `watching` -> `noted`** - `mcpindex | noted <server>/<tool> - ...`.
|
|
294
316
|
The previous "watching" read like surveillance *of the user*; "noted" frames it as
|
|
295
317
|
mcpindex quietly keeping track on your behalf. Copy-only; behavior identical.
|
|
296
318
|
|
|
297
|
-
## 0.3.0
|
|
319
|
+
## 0.3.0 - 2026-06-08
|
|
298
320
|
|
|
299
321
|
### Added
|
|
300
|
-
- **Ambient presence (default-on).** A subtle, low-frequency `mcpindex
|
|
322
|
+
- **Ambient presence (default-on).** A subtle, low-frequency `mcpindex | watching
|
|
301
323
|
<server>/<tool>` line on the gate's PROCEED path so a user remembers mcpindex is
|
|
302
|
-
working
|
|
324
|
+
working - first-touch per tool (one line per distinct tool, silent on repeats) plus a
|
|
303
325
|
once-per-session summary. New `onInvocation` option on `wrap()` lets an integrator
|
|
304
326
|
render the signal in their own UI. The first line carries `(silence:
|
|
305
327
|
MCPINDEX_AMBIENT_NOTICE=off)` so the off-switch is always discoverable; cadence tunes
|
|
@@ -310,20 +332,20 @@ Copy only, no behaviour change.
|
|
|
310
332
|
decision or a tool call's result (a HOLD emits nothing; a broken notifier is swallowed).
|
|
311
333
|
New `ambient.ts` + 12 tests (incl. a stdout-stays-empty channel-safety assertion).
|
|
312
334
|
|
|
313
|
-
## 0.2.0
|
|
335
|
+
## 0.2.0 - 2026-06-07
|
|
314
336
|
|
|
315
337
|
### Added
|
|
316
|
-
- **`actionClassification` on `PreflightVerdict`**
|
|
338
|
+
- **`actionClassification` on `PreflightVerdict`** - the read-side mirror of the
|
|
317
339
|
server's Tier 0a advisory action-classification block: the *blast radius* of a tool
|
|
318
340
|
call (action type, resource, side-effect, reversibility, egress, and a static
|
|
319
341
|
autonomy ceiling). New exported `ActionClassification` type. Lets TS/JS consumers
|
|
320
342
|
read the block off a verdict.
|
|
321
|
-
- **Advisory only**
|
|
343
|
+
- **Advisory only** - it rides *alongside* the decision and never alters
|
|
322
344
|
`PROCEED`/`HOLD` (`isProceed` reads only `decision`).
|
|
323
|
-
- **Read-side only in this release**
|
|
345
|
+
- **Read-side only in this release** - the SDK does **not** yet *compute* the block
|
|
324
346
|
locally; the field is populated from a server/hosted verdict, else `null`. The
|
|
325
347
|
local `classify()` port lands with the in-process interceptor (deferred).
|
|
326
|
-
- **Backward-compatible**
|
|
348
|
+
- **Backward-compatible** - the field defaults to `null` in `makeVerdict`, so existing
|
|
327
349
|
consumers are unaffected. The nested block uses the snake_case wire keys (the server
|
|
328
350
|
JSON contract); the envelope stays camelCase.
|
|
329
351
|
|
|
@@ -334,6 +356,6 @@ Copy only, no behaviour change.
|
|
|
334
356
|
|
|
335
357
|
## 0.1.0
|
|
336
358
|
|
|
337
|
-
- Initial release: pre-flight MCP tool-contract drift interceptor
|
|
359
|
+
- Initial release: pre-flight MCP tool-contract drift interceptor - `wrap()` over an
|
|
338
360
|
MCP client session that HOLDs a tool call when the contract drifted from your pin.
|
|
339
361
|
No credential handling.
|
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
The TypeScript client of [mcpindex.ai](https://mcpindex.ai) - the drift-monitored
|
|
4
4
|
MCP server index with an in-path trust gate for agent tool calls.
|
|
5
5
|
|
|
6
|
-
Pre-flight MCP tool-contract drift interceptor. One line
|
|
6
|
+
Pre-flight MCP tool-contract drift interceptor. One line - `wrap()` an MCP client
|
|
7
7
|
session and the gate **HOLDs a tool call before your agent acts** the moment the
|
|
8
8
|
tool's contract silently changes from what you pinned. In-path, on your host; no
|
|
9
9
|
credentials, no egress.
|
|
@@ -29,21 +29,25 @@ const guarded = wrap(session); // pins each tool's contract on first use (TOFU
|
|
|
29
29
|
// Review / Re-pin / Validate.
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
-
`wrap(session)`
|
|
33
|
-
process
|
|
34
|
-
|
|
32
|
+
`wrap(session)` with no server id keeps an **in-memory** pin baseline that dies
|
|
33
|
+
with the process. Pass a stable server id and the baseline is kept on disk and
|
|
34
|
+
survives restarts, under `MCPINDEX_STATE_DIR/pins/<server id>.json` or
|
|
35
|
+
`~/.mcpindex/pins/<server id>.json`:
|
|
35
36
|
|
|
36
37
|
```ts
|
|
37
|
-
import { wrap
|
|
38
|
+
import { wrap } from '@mcp-index/sdk';
|
|
38
39
|
|
|
39
|
-
const
|
|
40
|
-
const guarded = wrap(session, { pin, serverId: 'my-mcp-server' });
|
|
40
|
+
const guarded = wrap(session, { serverId: 'my-mcp-server' }); // pins on disk
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
`pinStore: 'memory'` keeps pins in the process even with a server id, and
|
|
44
|
+
`pinStore: 'file'` forces the file store without one. You can also pass your own
|
|
45
|
+
`PreflightPin` as `pin`.
|
|
46
|
+
|
|
47
|
+
## Sign in (optional) - `mcpindex login`
|
|
44
48
|
|
|
45
49
|
Signs you in with GitHub and stores a free API key at `~/.mcpindex/credentials.json`
|
|
46
|
-
(mode `0600`), used to authenticate deeper trust checks. Optional
|
|
50
|
+
(mode `0600`), used to authenticate deeper trust checks. Optional - `wrap()` needs no
|
|
47
51
|
account and sends nothing on its own.
|
|
48
52
|
|
|
49
53
|
```sh
|
|
@@ -57,7 +61,7 @@ npx -p @mcp-index/sdk mcpindex login
|
|
|
57
61
|
```
|
|
58
62
|
|
|
59
63
|
The key is minted server-side after GitHub OAuth and handed to a one-shot HTTP listener
|
|
60
|
-
bound to `127.0.0.1`
|
|
64
|
+
bound to `127.0.0.1` - it never transits a third party. Point `MCPINDEX_WEB_BASE` at a
|
|
61
65
|
different host to override the default (`https://mcpindex.ai`).
|
|
62
66
|
|
|
63
67
|
## What it does
|
|
@@ -65,32 +69,32 @@ different host to override the default (`https://mcpindex.ai`).
|
|
|
65
69
|
- Pins each MCP tool's contract trust-on-first-use (TOFU), persisted across restarts.
|
|
66
70
|
- Runs a **deterministic** contract-diff (the ChangeKind taxonomy: added-required-param,
|
|
67
71
|
constraint-narrowed, annotation-flip-to-destructive, output-schema-changed,
|
|
68
|
-
type/enum/removed,
|
|
69
|
-
- **HOLDs** the call with the
|
|
72
|
+
type/enum/removed, ...) plus an injection/exfil marker scan over input and output schema.
|
|
73
|
+
- **HOLDs** the call with the mcpindex hold banner when the contract drifted; **PROCEEDs** silently
|
|
70
74
|
on a benign change (no false alarm).
|
|
71
75
|
- Postures: `Monitor` (notify + proceed) / `Guard` (default; hold dangerous) /
|
|
72
76
|
`Strict` (hold any drift).
|
|
73
77
|
- Grades each call's **blast radius** (Tier-0a action classification) on the verdict:
|
|
74
|
-
action type (read / write / delete / send /
|
|
75
|
-
autonomy ceiling, computed locally from the live contract. **Advisory**
|
|
78
|
+
action type (read / write / delete / send / ...), reversibility, egress, and a static
|
|
79
|
+
autonomy ceiling, computed locally from the live contract. **Advisory** - it rides
|
|
76
80
|
alongside the decision and never moves HOLD/PROCEED. On by default; opt out with
|
|
77
81
|
`MCPINDEX_ACTION_CLASSIFICATION_ENABLED=0`.
|
|
78
82
|
|
|
79
83
|
## What it is NOT
|
|
80
84
|
|
|
81
|
-
The verdict is a **contract-diff, not a safety oracle**
|
|
85
|
+
The verdict is a **contract-diff, not a safety oracle** - it tells you the contract
|
|
82
86
|
*changed* versus your pin, not that the new contract is safe. It does not "block attacks"
|
|
83
87
|
or "guarantee safe." You decide what a HOLD means for your agent.
|
|
84
88
|
|
|
85
89
|
## Result-content scanning (opt-in, OFF by default)
|
|
86
90
|
|
|
87
91
|
Beyond the contract diff, the SDK can scan a tool's **returned result** (text blocks and
|
|
88
|
-
`structuredContent`) for prompt-injection / exfiltration / credential-path markers
|
|
92
|
+
`structuredContent`) for prompt-injection / exfiltration / credential-path markers - the
|
|
89
93
|
attack where a *compromised result*, not a changed contract, tries to steer your agent. It
|
|
90
94
|
is **off by default** (zero behavior change) and enabled per-wrap:
|
|
91
95
|
|
|
92
96
|
```ts
|
|
93
|
-
const safe = wrap(session, { scanResults: true, onHold: (v) => { /*
|
|
97
|
+
const safe = wrap(session, { scanResults: true, onHold: (v) => { /* ... */ } });
|
|
94
98
|
```
|
|
95
99
|
|
|
96
100
|
Once on, a tainted result is **withheld under `Guard` / `Strict`** and **passes through
|
|
@@ -100,7 +104,7 @@ client's `wrap(..., scan_results=...)`.
|
|
|
100
104
|
|
|
101
105
|
## Drift telemetry (opt-in, OFF by default)
|
|
102
106
|
|
|
103
|
-
The SDK can report **that** a tool's contract drifted
|
|
107
|
+
The SDK can report **that** a tool's contract drifted - so mcpindex can track drift on servers
|
|
104
108
|
it can't crawl itself (private / auth-gated). It is **off by default and sends nothing** unless
|
|
105
109
|
you turn it on:
|
|
106
110
|
|
|
@@ -113,7 +117,7 @@ When enabled, each tool you pin and each contract drift sends **one one-way sign
|
|
|
113
117
|
- **What it sends:** fingerprints (HMAC) of the server/tool id, the contract hashes, the
|
|
114
118
|
change type (the fixed ChangeKind vocabulary), a safety flag, an **hour-rounded** timestamp,
|
|
115
119
|
a random install id (a token that links one machine's signals so distinct installs can be
|
|
116
|
-
counted
|
|
120
|
+
counted - not derived from you), and a client SDK tag (`py` or `ts`).
|
|
117
121
|
- **What it NEVER sends:** tool schemas, arguments, descriptions, URLs, or any of your data.
|
|
118
122
|
The fingerprints carry no plaintext name and they are **not anonymity**: the salt is a
|
|
119
123
|
constant in this client and the registry is public, so a listed server's fingerprint
|
|
@@ -140,5 +144,5 @@ Three ways to bring mcpindex into an agent, for different surfaces:
|
|
|
140
144
|
|
|
141
145
|
## License
|
|
142
146
|
|
|
143
|
-
PolyForm Noncommercial 1.0.0
|
|
147
|
+
PolyForm Noncommercial 1.0.0 - (c) Bhartis LLC. Free for noncommercial use; commercial use
|
|
144
148
|
requires a separate license. See [`LICENSE`](./LICENSE) and https://mcpindex.ai.
|
package/dist/src/canonical.d.ts
CHANGED
|
@@ -25,6 +25,10 @@ export type Json = null | boolean | number | string | Json[] | {
|
|
|
25
25
|
/** THE canonical serialization — every hash site MUST use this (port of
|
|
26
26
|
* `contract.canonical_bytes`). */
|
|
27
27
|
export declare function canonicalBytes(obj: unknown): Buffer;
|
|
28
|
+
/** Tool-contract serialization. Same walker as `canonicalBytes`, plus the
|
|
29
|
+
* NFC-collision and float-shaped-string rules. Ordinary inputs match
|
|
30
|
+
* `canonicalBytes`. Objects in this walker are `Object.create(null)`. */
|
|
31
|
+
export declare function contractBytes(obj: unknown): Buffer;
|
|
28
32
|
/** The connector's per-tool hash, byte-identical to Python `_tool_hash`. The
|
|
29
33
|
* preimage is `{name, description, input_schema}` (snake_case schema key). */
|
|
30
34
|
export declare function toolHash(name: string, description: string, inputSchema: Record<string, unknown>): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"canonical.d.ts","sourceRoot":"","sources":["../../src/canonical.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAOH,kDAAkD;AAClD,MAAM,MAAM,IAAI,GACZ,IAAI,GACJ,OAAO,GACP,MAAM,GACN,MAAM,GACN,IAAI,EAAE,GACN;IAAE,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"canonical.d.ts","sourceRoot":"","sources":["../../src/canonical.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAOH,kDAAkD;AAClD,MAAM,MAAM,IAAI,GACZ,IAAI,GACJ,OAAO,GACP,MAAM,GACN,MAAM,GACN,IAAI,EAAE,GACN;IAAE,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AAiM1B;kCACkC;AAClC,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAEnD;AAED;;yEAEyE;AACzE,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAElD;AAED;8EAC8E;AAC9E,wBAAgB,QAAQ,CACtB,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACnC,MAAM,CAOR;AAED;;;;;;;;;oFASoF;AACpF,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAY9D"}
|
package/dist/src/canonical.js
CHANGED
|
@@ -81,7 +81,14 @@ function pythonFloatRepr(n) {
|
|
|
81
81
|
exp = exp.padStart(2, "0");
|
|
82
82
|
return `${mantissa}e${sign}${exp}`;
|
|
83
83
|
}
|
|
84
|
-
|
|
84
|
+
const FLOATISH = /^-?[0-9]\.[0-9]{17}e[+-][0-9]{2,}$/;
|
|
85
|
+
function contractString(s) {
|
|
86
|
+
const n = nfc(s);
|
|
87
|
+
if (n.startsWith("\0") || FLOATISH.test(n))
|
|
88
|
+
return "\0" + n;
|
|
89
|
+
return n;
|
|
90
|
+
}
|
|
91
|
+
function canonicalize(o, depth, contract = false) {
|
|
85
92
|
if (depth > MAX_CANON_DEPTH) {
|
|
86
93
|
throw new Error("canonical depth exceeded");
|
|
87
94
|
}
|
|
@@ -104,23 +111,45 @@ function canonicalize(o, depth) {
|
|
|
104
111
|
return Number(o);
|
|
105
112
|
}
|
|
106
113
|
if (typeof o === "string") {
|
|
107
|
-
return nfc(o);
|
|
114
|
+
return contract ? contractString(o) : nfc(o);
|
|
108
115
|
}
|
|
109
116
|
if (Array.isArray(o)) {
|
|
110
|
-
return o.map((v) => canonicalize(v, depth + 1));
|
|
117
|
+
return o.map((v) => canonicalize(v, depth + 1, contract));
|
|
111
118
|
}
|
|
112
119
|
if (typeof o === "object") {
|
|
113
120
|
const src = o;
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
src[k]
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
121
|
+
const keys = Object.keys(src);
|
|
122
|
+
if (!contract) {
|
|
123
|
+
// NFC-normalize keys, then sort by the normalized string (Python sorts by
|
|
124
|
+
// `str(k)`; all our keys are already strings).
|
|
125
|
+
const entries = keys.map((k) => [nfc(k), src[k]]);
|
|
126
|
+
entries.sort((a, b) => (a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0));
|
|
127
|
+
const out = {};
|
|
128
|
+
for (const [k, v] of entries) {
|
|
129
|
+
out[k] = canonicalize(v, depth + 1, false);
|
|
130
|
+
}
|
|
131
|
+
return out;
|
|
132
|
+
}
|
|
133
|
+
const groups = new Map();
|
|
134
|
+
for (const k of keys) {
|
|
135
|
+
const nk = nfc(k);
|
|
136
|
+
const g = groups.get(nk);
|
|
137
|
+
if (g === undefined)
|
|
138
|
+
groups.set(nk, [k]);
|
|
139
|
+
else
|
|
140
|
+
g.push(k);
|
|
141
|
+
}
|
|
142
|
+
const out = Object.create(null);
|
|
143
|
+
for (const [nk, ks] of groups) {
|
|
144
|
+
if (ks.length === 1) {
|
|
145
|
+
const only = ks[0];
|
|
146
|
+
out[nk] = canonicalize(src[only], depth + 1, true);
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
for (const k of ks) {
|
|
150
|
+
out[k] = canonicalize(src[k], depth + 1, true);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
124
153
|
}
|
|
125
154
|
return out;
|
|
126
155
|
}
|
|
@@ -143,9 +172,11 @@ function encodeAscii(v) {
|
|
|
143
172
|
if (Array.isArray(v)) {
|
|
144
173
|
return "[" + v.map(encodeAscii).join(",") + "]";
|
|
145
174
|
}
|
|
146
|
-
//
|
|
175
|
+
// sort_keys, matching Python json.dumps. The contract walker inserts in
|
|
176
|
+
// first-seen order; the dump is what makes ordinary objects byte-stable.
|
|
147
177
|
const parts = [];
|
|
148
|
-
|
|
178
|
+
const keys = Object.keys(v).sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));
|
|
179
|
+
for (const k of keys) {
|
|
149
180
|
parts.push(encodeAsciiString(k) + ":" + encodeAscii(v[k]));
|
|
150
181
|
}
|
|
151
182
|
return "{" + parts.join(",") + "}";
|
|
@@ -195,12 +226,18 @@ function encodeAsciiString(s) {
|
|
|
195
226
|
/** THE canonical serialization — every hash site MUST use this (port of
|
|
196
227
|
* `contract.canonical_bytes`). */
|
|
197
228
|
export function canonicalBytes(obj) {
|
|
198
|
-
return Buffer.from(encodeAscii(canonicalize(obj, 0)), "utf-8");
|
|
229
|
+
return Buffer.from(encodeAscii(canonicalize(obj, 0, false)), "utf-8");
|
|
230
|
+
}
|
|
231
|
+
/** Tool-contract serialization. Same walker as `canonicalBytes`, plus the
|
|
232
|
+
* NFC-collision and float-shaped-string rules. Ordinary inputs match
|
|
233
|
+
* `canonicalBytes`. Objects in this walker are `Object.create(null)`. */
|
|
234
|
+
export function contractBytes(obj) {
|
|
235
|
+
return Buffer.from(encodeAscii(canonicalize(obj, 0, true)), "utf-8");
|
|
199
236
|
}
|
|
200
237
|
/** The connector's per-tool hash, byte-identical to Python `_tool_hash`. The
|
|
201
238
|
* preimage is `{name, description, input_schema}` (snake_case schema key). */
|
|
202
239
|
export function toolHash(name, description, inputSchema) {
|
|
203
|
-
const bytes =
|
|
240
|
+
const bytes = contractBytes({
|
|
204
241
|
name,
|
|
205
242
|
description,
|
|
206
243
|
input_schema: inputSchema,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"canonical.js","sourceRoot":"","sources":["../../src/canonical.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,YAAY,GAAG,EAAE,CAAC;AACxB,MAAM,eAAe,GAAG,EAAE,CAAC;AAW3B,SAAS,GAAG,CAAC,CAAS;IACpB,OAAO,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;AAC5B,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,SAAS,UAAU,CAAC,CAAS;IAC3B,OAAO,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AAC7B,CAAC;AAED,SAAS,eAAe,CAAC,CAAS;IAChC,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3C,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAC7D,CAAC;IACD,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,IAAI,CAAC,KAAK,CAAC;QAAE,CAAC,GAAG,CAAC,CAAC,CAAC,uBAAuB;IAC3C,6EAA6E;IAC7E,MAAM,GAAG,GAAG,CAAC,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;IAC1C,MAAM,CAAC,GAAG,2BAA2B,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAChD,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,gCAAgC,GAAG,EAAE,CAAC,CAAC;IACzD,CAAC;IACD,MAAM,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACtB,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAClB,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACf,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC;QAAE,GAAG,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC/C,OAAO,GAAG,QAAQ,IAAI,IAAI,GAAG,GAAG,EAAE,CAAC;AACrC,CAAC;AAED,SAAS,YAAY,CAAC,CAAU,EAAE,KAAa;
|
|
1
|
+
{"version":3,"file":"canonical.js","sourceRoot":"","sources":["../../src/canonical.ts"],"names":[],"mappings":"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"}
|
package/dist/src/gate.d.ts
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
import { PreflightPin } from "./preflight.js";
|
|
10
10
|
import type { PinnedTool, PreflightVerdict, ToolDef } from "./preflight.js";
|
|
11
11
|
import { ChangeKind, isSafetyRelevant } from "./schemaDiff.js";
|
|
12
|
+
import type { Change } from "./schemaDiff.js";
|
|
12
13
|
import { ErrorStore, Operation } from "./errors.js";
|
|
13
14
|
declare const DEFAULT_BEHAVIORAL_MANDATED_KINDS: ReadonlySet<ChangeKind>;
|
|
14
15
|
export declare enum Posture {
|
|
@@ -114,6 +115,14 @@ export interface GateOptions {
|
|
|
114
115
|
posture?: Posture;
|
|
115
116
|
errors?: ErrorStore | null;
|
|
116
117
|
}
|
|
118
|
+
export interface GateEffect {
|
|
119
|
+
kind: "repin" | "drift" | "fleet";
|
|
120
|
+
toolName: string;
|
|
121
|
+
observed?: ToolDef | null;
|
|
122
|
+
oldHash?: string;
|
|
123
|
+
newHash?: string;
|
|
124
|
+
drift?: readonly Change[];
|
|
125
|
+
}
|
|
117
126
|
export declare class Gate {
|
|
118
127
|
private readonly pin;
|
|
119
128
|
private readonly _serverId;
|
|
@@ -127,6 +136,7 @@ export declare class Gate {
|
|
|
127
136
|
private readonly errors;
|
|
128
137
|
constructor(opts: GateOptions);
|
|
129
138
|
get serverId(): string;
|
|
139
|
+
get pinPath(): string | null;
|
|
130
140
|
get posture(): Posture;
|
|
131
141
|
get verifier(): BehavioralVerifier | null;
|
|
132
142
|
get ownership(): Ownership;
|
|
@@ -140,6 +150,11 @@ export declare class Gate {
|
|
|
140
150
|
* null when the live definition is unavailable or the flag is off. Mirrors the
|
|
141
151
|
* Python wrapper's `build_action_classification`. */
|
|
142
152
|
evaluate(name: string, observed: ToolDef | null): PreflightVerdict;
|
|
153
|
+
/** `(static, effective, effects)` with no pin write, telemetry send, or fleet read. */
|
|
154
|
+
assess(name: string, observed: ToolDef | null): [PreflightVerdict, PreflightVerdict, GateEffect[]];
|
|
155
|
+
/** Run effects, then re-apply posture so the fleet advisory rides as `evaluate` did. */
|
|
156
|
+
commit(stat: PreflightVerdict, effects: readonly GateEffect[]): [PreflightVerdict, PreflightVerdict];
|
|
157
|
+
private collect;
|
|
143
158
|
private decideContract;
|
|
144
159
|
private classifyDrift;
|
|
145
160
|
private mandatedUnhashedDrift;
|
|
@@ -154,6 +169,8 @@ export declare class Gate {
|
|
|
154
169
|
private holdOrFailopen;
|
|
155
170
|
applyPosture(stat: PreflightVerdict): PreflightVerdict;
|
|
156
171
|
decide(name: string, observed: ToolDef | null): [PreflightVerdict, PreflightVerdict];
|
|
172
|
+
private tamperReason;
|
|
173
|
+
private tamperHold;
|
|
157
174
|
internalErrorVerdict(name: string): PreflightVerdict;
|
|
158
175
|
captureError(exc: unknown, operation: Operation, ourCodeLocation: string): void;
|
|
159
176
|
private isUnambiguousDangerous;
|
package/dist/src/gate.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gate.d.ts","sourceRoot":"","sources":["../../src/gate.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAGL,YAAY,EAIb,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAC5E,OAAO,EACL,UAAU,
|
|
1
|
+
{"version":3,"file":"gate.d.ts","sourceRoot":"","sources":["../../src/gate.ts"],"names":[],"mappings":"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"}
|