@integraledger/lcp-mcp-server 0.10.0 → 0.11.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 +69 -0
- package/README.md +11 -9
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +22 -1
- package/dist/server.js.map +1 -1
- package/package.json +11 -11
- package/src/server.ts +25 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,74 @@
|
|
|
1
1
|
# @integraledger/lcp-mcp-server
|
|
2
2
|
|
|
3
|
+
## 0.11.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 5159d60: The server declares the LCP capability, and the protocol line moves to 0.13.
|
|
8
|
+
|
|
9
|
+
`lcp-mcp-server` now advertises `com.integraledger/legal-context` in
|
|
10
|
+
`capabilities.extensions`, so an MCP host can discover that this server verifies the legal context bound
|
|
11
|
+
to a payment **without calling a tool**. The identifier and its settings value are both imported —
|
|
12
|
+
`LCP_MCP_EXTENSION_ID` from `lcp-discovery`, `LCP_SPEC_VERSION` from `lcp-kernel` — because a wire
|
|
13
|
+
identity spelled locally is a second home the wire seal cannot see, and a hardcoded spec version drifts
|
|
14
|
+
the first time the specification moves.
|
|
15
|
+
|
|
16
|
+
⭐ **This is the one capability that must be asserted in the constructor, and it does not contradict the
|
|
17
|
+
rule beside it.** `tools` is left to the registrations because the SDK DERIVES it, so restating it would
|
|
18
|
+
duplicate a fact something else owns. Nothing derives an extension: no registration implies this server
|
|
19
|
+
speaks LCP, so the constructor is the only place the declaration can come from. Measured — deleting it
|
|
20
|
+
makes the extension vanish from what a client sees.
|
|
21
|
+
|
|
22
|
+
**Graceful degradation is total, which is what makes this safe to ship.** A client that ignores the
|
|
23
|
+
identifier gets a byte-identical server; there is no branch in which the extension refuses a request, and
|
|
24
|
+
a test asserts the tool list is unchanged. A client must not read the declaration as a claim that any
|
|
25
|
+
seller's terms are bound — it describes the server's capability, not a transaction.
|
|
26
|
+
|
|
27
|
+
Three assertions, each driven red against a planted defect: the declaration removed (the "consistency
|
|
28
|
+
fix" the docblock warns against), UCP's `com.integraledger.legal_context` substituted for MCP's
|
|
29
|
+
slash-form identifier, and the spec version hardcoded rather than derived.
|
|
30
|
+
|
|
31
|
+
⛔ **Protocol repin: `0.13.0`.** Exact in `devDependencies`, `^0.13.0` in shipped `dependencies` and
|
|
32
|
+
`peerDependencies` — the three shapes `check:wire` enforces. The line moves for a reason rather than a
|
|
33
|
+
bump: `LCP_MCP_EXTENSION_ID` is new API, and it first shipped as `0.12.3`, a **patch**. That broke the
|
|
34
|
+
invariant `check:wire` is built on — every patch inside a line is API-equivalent — while the gate
|
|
35
|
+
requires the caret at the minor's zero patch and refuses a raised floor. With `0.12.2` resolved, squarely
|
|
36
|
+
inside `^0.12.0`, the export is `undefined` and the capability key serialises as
|
|
37
|
+
`{"extensions":{"undefined":{}}}`. The declaration was deliberately not shipped against that floor.
|
|
38
|
+
Verified afterwards that the invariant had otherwise held: of the nine runtime protocol dependencies,
|
|
39
|
+
eight added no exports anywhere across `0.12.x`.
|
|
40
|
+
|
|
41
|
+
⚠️ The spec is `docs/2026-08-25-lcp-mcp-extension-specification.md`. `@modelcontextprotocol/server@2.0.0`
|
|
42
|
+
negotiates wire era `2025-11-25` and has no `server/discover`, so the declaration rides the `initialize`
|
|
43
|
+
handshake today and carries forward unchanged when the SDK ships the modern era.
|
|
44
|
+
|
|
45
|
+
### Patch Changes
|
|
46
|
+
|
|
47
|
+
- @integraledger/agent-guard@0.11.0
|
|
48
|
+
|
|
49
|
+
## 0.10.1
|
|
50
|
+
|
|
51
|
+
### Patch Changes
|
|
52
|
+
|
|
53
|
+
- 5154cfb: Install one copy of the protocol packages, not two.
|
|
54
|
+
|
|
55
|
+
`lcp-mcp-server` pinned its `@integraledger/lcp-*` dependencies to an exact version while `agent-guard`
|
|
56
|
+
— which it depends on — declares the same packages as peers at a caret range. Those two declarations
|
|
57
|
+
cannot be satisfied by a single copy, so installing both packages resolved the protocol line **twice**:
|
|
58
|
+
once hoisted to satisfy the caret, and once nested under `lcp-mcp-server` to satisfy the exact pin. The
|
|
59
|
+
two halves of one install then read different protocol code, with `instanceof` failing across the seam
|
|
60
|
+
between them.
|
|
61
|
+
|
|
62
|
+
`lcp-mcp-server` now declares those dependencies as a caret at the minor line's zero patch, matching its
|
|
63
|
+
sibling. A tree holding both resolves a single copy, and `npx lcp-mcp` still installs standalone.
|
|
64
|
+
|
|
65
|
+
Nothing about either package's API, behaviour or guarantees changes. Both were correct in isolation; only
|
|
66
|
+
a tree holding both was affected.
|
|
67
|
+
|
|
68
|
+
- Updated dependencies [5154cfb]
|
|
69
|
+
- Updated dependencies [ccf4bb4]
|
|
70
|
+
- @integraledger/agent-guard@0.10.1
|
|
71
|
+
|
|
3
72
|
## 0.10.0
|
|
4
73
|
|
|
5
74
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -80,15 +80,17 @@ document for your agent to send with its own keys.
|
|
|
80
80
|
|
|
81
81
|
## One protocol line in the tree
|
|
82
82
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
83
|
+
This server declares the protocol line as a **caret at the minor's zero patch**, and `agent-guard` peers it
|
|
84
|
+
the same way. That is what puts **one** line of the protocol packages in `node_modules` when you install
|
|
85
|
+
both: the two ranges overlap, so a package manager resolves a single copy that satisfies each. An exact
|
|
86
|
+
runtime pin would do the opposite — it cannot be satisfied by the sibling's range, so the resolver nests a
|
|
87
|
+
second copy underneath this package, and the two halves of one install then read different protocol code.
|
|
88
|
+
|
|
89
|
+
If a mixed install ever does put two lines in one tree, the seam stays safe: what this package takes from
|
|
90
|
+
`agent-guard` is the fetcher and nothing else — `makeCachingFetcher`, `nodeDnsLookup`, and the
|
|
91
|
+
`TermsFetcher` type — whose entire vocabulary is `fetch(url: string)` in, `{ bytes, format, fetchedAt }`
|
|
92
|
+
out, plus a `{ address, family }` DNS answer. Not one of those names an `lcp-kernel`, `lcp-binding-core` or
|
|
93
|
+
`lcp-discovery` type in either direction, so two lines never exchange a value.
|
|
92
94
|
|
|
93
95
|
## Checked against the live MCP specification — 2026-07-30
|
|
94
96
|
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAS9C;;;;;;;;;GASG;AACH,eAAO,MAAM,WAAW,YAAY,CAAC;AAErC;;;;;;;;;;GAUG;AACH,eAAO,MAAM,cAAc,YACzB,qBAAqB,EACrB,4BAA4B,EAC5B,uBAAuB,EACvB,0BAA0B,EAC1B,qBAAqB,EACrB,uBAAuB,CACf,CAAC;AAEX;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,WAAW,GAAG,SAAS,CA+BhE"}
|
package/dist/server.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { LCP_MCP_EXTENSION_ID } from "@integraledger/lcp-discovery";
|
|
2
|
+
import { LCP_SPEC_VERSION } from "@integraledger/lcp-kernel";
|
|
1
3
|
import { McpServer } from "@modelcontextprotocol/server";
|
|
2
4
|
import { registerComputeAtrHash } from "./tools/compute-atrhash.js";
|
|
3
5
|
import { registerExtractReference } from "./tools/extract-reference.js";
|
|
@@ -55,7 +57,26 @@ export const LCP_TOOL_NAMES = [
|
|
|
55
57
|
* the boundary above. When there is a resource to serve that is not one of those, it is declared then.
|
|
56
58
|
*/
|
|
57
59
|
export function createLcpMcpServer(ports) {
|
|
58
|
-
const server = new McpServer({ name: SERVER_NAME, version: serverVersion() }
|
|
60
|
+
const server = new McpServer({ name: SERVER_NAME, version: serverVersion() }, {
|
|
61
|
+
// THE ONE CAPABILITY THAT MUST BE ASSERTED, AND IT DOES NOT CONTRADICT THE PARAGRAPH ABOVE.
|
|
62
|
+
//
|
|
63
|
+
// `tools` is left to the registrations because the SDK DERIVES it — restating it in the constructor
|
|
64
|
+
// is a second statement of a fact something else already owns. An extension has no such deriver:
|
|
65
|
+
// nothing about registering a tool implies this server speaks LCP, so the constructor is the only
|
|
66
|
+
// place the declaration can come from, and asserting it here states a fact rather than duplicating
|
|
67
|
+
// one. Do not "consistency-fix" this by deleting it; measured, removing it makes the extension
|
|
68
|
+
// vanish from what a client sees, which is precisely what the sibling test asserts.
|
|
69
|
+
//
|
|
70
|
+
// BOTH VALUES ARE IMPORTED, NEITHER IS SPELLED HERE. The identifier is a wire identity a
|
|
71
|
+
// counterparty must recognise, and `check:wire` seals it by importing `lcp-discovery`; a local copy
|
|
72
|
+
// would be a second home the gate cannot see. `LCP_SPEC_VERSION` is the kernel's own answer to which
|
|
73
|
+
// revision this stack implements, so a literal here would drift the first time the spec moved.
|
|
74
|
+
capabilities: {
|
|
75
|
+
extensions: {
|
|
76
|
+
[LCP_MCP_EXTENSION_ID]: { specVersion: LCP_SPEC_VERSION },
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
});
|
|
59
80
|
registerComputeAtrHash(server, ports);
|
|
60
81
|
registerGenerateLegalContext(server, ports);
|
|
61
82
|
registerVerifyBeforePay(server, ports);
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAEzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACpE,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EAAE,4BAA4B,EAAE,MAAM,mCAAmC,CAAC;AACjF,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACpE,OAAO,EAAE,2BAA2B,EAAE,MAAM,iCAAiC,CAAC;AAC9E,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,SAAS,CAAC;AAErC;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,qBAAqB;IACrB,4BAA4B;IAC5B,uBAAuB;IACvB,0BAA0B;IAC1B,qBAAqB;IACrB,uBAAuB;CACf,CAAC;AAEX;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAkB;IACnD,MAAM,MAAM,GAAG,IAAI,SAAS,
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAEzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACpE,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EAAE,4BAA4B,EAAE,MAAM,mCAAmC,CAAC;AACjF,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACpE,OAAO,EAAE,2BAA2B,EAAE,MAAM,iCAAiC,CAAC;AAC9E,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,SAAS,CAAC;AAErC;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,qBAAqB;IACrB,4BAA4B;IAC5B,uBAAuB;IACvB,0BAA0B;IAC1B,qBAAqB;IACrB,uBAAuB;CACf,CAAC;AAEX;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAkB;IACnD,MAAM,MAAM,GAAG,IAAI,SAAS,CAC1B,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,aAAa,EAAE,EAAE,EAC/C;QACE,4FAA4F;QAC5F,EAAE;QACF,oGAAoG;QACpG,iGAAiG;QACjG,kGAAkG;QAClG,mGAAmG;QACnG,+FAA+F;QAC/F,oFAAoF;QACpF,EAAE;QACF,yFAAyF;QACzF,oGAAoG;QACpG,qGAAqG;QACrG,+FAA+F;QAC/F,YAAY,EAAE;YACZ,UAAU,EAAE;gBACV,CAAC,oBAAoB,CAAC,EAAE,EAAE,WAAW,EAAE,gBAAgB,EAAE;aAC1D;SACF;KACF,CACF,CAAC;IACF,sBAAsB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACtC,4BAA4B,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAC5C,uBAAuB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACvC,2BAA2B,CAAC,MAAM,CAAC,CAAC;IACpC,sBAAsB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACtC,wBAAwB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACxC,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@integraledger/lcp-mcp-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -28,18 +28,18 @@
|
|
|
28
28
|
"directory": "packages/lcp-mcp-server"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@integraledger/lcp-authority": "0.
|
|
32
|
-
"@integraledger/lcp-binding-core": "0.
|
|
33
|
-
"@integraledger/lcp-discovery": "0.
|
|
34
|
-
"@integraledger/lcp-evidence": "0.
|
|
35
|
-
"@integraledger/lcp-kernel": "0.
|
|
36
|
-
"@integraledger/lcp-placement-ack": "0.
|
|
37
|
-
"@integraledger/lcp-placement-ap2": "0.
|
|
38
|
-
"@integraledger/lcp-placements": "0.
|
|
39
|
-
"@integraledger/lcp-verify": "0.
|
|
31
|
+
"@integraledger/lcp-authority": "^0.13.0",
|
|
32
|
+
"@integraledger/lcp-binding-core": "^0.13.0",
|
|
33
|
+
"@integraledger/lcp-discovery": "^0.13.0",
|
|
34
|
+
"@integraledger/lcp-evidence": "^0.13.0",
|
|
35
|
+
"@integraledger/lcp-kernel": "^0.13.0",
|
|
36
|
+
"@integraledger/lcp-placement-ack": "^0.13.0",
|
|
37
|
+
"@integraledger/lcp-placement-ap2": "^0.13.0",
|
|
38
|
+
"@integraledger/lcp-placements": "^0.13.0",
|
|
39
|
+
"@integraledger/lcp-verify": "^0.13.0",
|
|
40
40
|
"@modelcontextprotocol/server": "2.0.0",
|
|
41
41
|
"zod": "4.4.3",
|
|
42
|
-
"@integraledger/agent-guard": "0.
|
|
42
|
+
"@integraledger/agent-guard": "0.11.0"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@modelcontextprotocol/client": "2.0.0",
|
package/src/server.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { LCP_MCP_EXTENSION_ID } from "@integraledger/lcp-discovery";
|
|
2
|
+
import { LCP_SPEC_VERSION } from "@integraledger/lcp-kernel";
|
|
1
3
|
import { McpServer } from "@modelcontextprotocol/server";
|
|
2
4
|
import type { LcpMcpPorts } from "./ports.js";
|
|
3
5
|
import { registerComputeAtrHash } from "./tools/compute-atrhash.js";
|
|
@@ -59,7 +61,29 @@ export const LCP_TOOL_NAMES = [
|
|
|
59
61
|
* the boundary above. When there is a resource to serve that is not one of those, it is declared then.
|
|
60
62
|
*/
|
|
61
63
|
export function createLcpMcpServer(ports: LcpMcpPorts): McpServer {
|
|
62
|
-
const server = new McpServer(
|
|
64
|
+
const server = new McpServer(
|
|
65
|
+
{ name: SERVER_NAME, version: serverVersion() },
|
|
66
|
+
{
|
|
67
|
+
// THE ONE CAPABILITY THAT MUST BE ASSERTED, AND IT DOES NOT CONTRADICT THE PARAGRAPH ABOVE.
|
|
68
|
+
//
|
|
69
|
+
// `tools` is left to the registrations because the SDK DERIVES it — restating it in the constructor
|
|
70
|
+
// is a second statement of a fact something else already owns. An extension has no such deriver:
|
|
71
|
+
// nothing about registering a tool implies this server speaks LCP, so the constructor is the only
|
|
72
|
+
// place the declaration can come from, and asserting it here states a fact rather than duplicating
|
|
73
|
+
// one. Do not "consistency-fix" this by deleting it; measured, removing it makes the extension
|
|
74
|
+
// vanish from what a client sees, which is precisely what the sibling test asserts.
|
|
75
|
+
//
|
|
76
|
+
// BOTH VALUES ARE IMPORTED, NEITHER IS SPELLED HERE. The identifier is a wire identity a
|
|
77
|
+
// counterparty must recognise, and `check:wire` seals it by importing `lcp-discovery`; a local copy
|
|
78
|
+
// would be a second home the gate cannot see. `LCP_SPEC_VERSION` is the kernel's own answer to which
|
|
79
|
+
// revision this stack implements, so a literal here would drift the first time the spec moved.
|
|
80
|
+
capabilities: {
|
|
81
|
+
extensions: {
|
|
82
|
+
[LCP_MCP_EXTENSION_ID]: { specVersion: LCP_SPEC_VERSION },
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
);
|
|
63
87
|
registerComputeAtrHash(server, ports);
|
|
64
88
|
registerGenerateLegalContext(server, ports);
|
|
65
89
|
registerVerifyBeforePay(server, ports);
|