opedd-mcp 0.6.7 → 0.6.9

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/README.md CHANGED
@@ -128,7 +128,7 @@ Exposes up to 17 tools to any AI assistant (some are conditional on env vars):
128
128
 
129
129
  ### Regulatory framing (CDSM Article 4 vs EU AI Act Article 53 — never conflated)
130
130
 
131
- Per the [opedd-backend INVARIANTS.md W1.6 amendment](https://github.com/Opedd/opedd-backend/blob/main/INVARIANTS.md):
131
+ Per Opedd's platform invariants (W1.6 amendment):
132
132
 
133
133
  - **`rsl_get(publisher_id, jsonld=true)`** → publisher-side **CDSM Article 4(3)** opt-out declaration (signed JSON-LD receipt over the reservation state).
134
134
  - **`article_53_attestation(license_id)`** → buyer-side **EU AI Act Article 53** attestation (signed HS256 JWT scoped to one license).
package/dist/index.js CHANGED
@@ -41,7 +41,15 @@ async function opeddFetch(creds, path, options = {}) {
41
41
  let msg = `HTTP ${res.status}`;
42
42
  try {
43
43
  const errBody = await res.json();
44
- msg = errBody?.error || errBody?.message || msg;
44
+ // Backend envelope upgraded to structured errors ({ error: { code,
45
+ // message } }); the old string-shape is kept as fallback. Passing the
46
+ // object into Error() rendered "[object Object]" — every agent-facing
47
+ // failure was unreadable (launch-gaps follow-on, 2026-07-17).
48
+ const e = errBody?.error;
49
+ msg =
50
+ (typeof e === "object" && e !== null ? [e.code, e.message].filter(Boolean).join(": ") : e) ||
51
+ errBody?.message ||
52
+ msg;
45
53
  }
46
54
  catch {
47
55
  // non-JSON error body — keep the HTTP-status default
@@ -66,7 +74,15 @@ async function opeddFetchNdjson(creds, path, options = {}) {
66
74
  let msg = `HTTP ${res.status}`;
67
75
  try {
68
76
  const errBody = await res.json();
69
- msg = errBody?.error || errBody?.message || msg;
77
+ // Backend envelope upgraded to structured errors ({ error: { code,
78
+ // message } }); the old string-shape is kept as fallback. Passing the
79
+ // object into Error() rendered "[object Object]" — every agent-facing
80
+ // failure was unreadable (launch-gaps follow-on, 2026-07-17).
81
+ const e = errBody?.error;
82
+ msg =
83
+ (typeof e === "object" && e !== null ? [e.code, e.message].filter(Boolean).join(": ") : e) ||
84
+ errBody?.message ||
85
+ msg;
70
86
  }
71
87
  catch {
72
88
  // non-JSON error body — keep the HTTP-status default
@@ -396,7 +412,7 @@ function buildTools(has) {
396
412
  },
397
413
  cursor: {
398
414
  type: "string",
399
- description: "Opaque cursor from prior response's _meta.next_cursor",
415
+ description: "Opaque cursor from the prior response's data.pagination.next_cursor",
400
416
  },
401
417
  limit: {
402
418
  type: "number",
@@ -423,7 +439,7 @@ function buildTools(has) {
423
439
  },
424
440
  cursor: {
425
441
  type: "string",
426
- description: "Opaque cursor from prior response's _meta.next_cursor",
442
+ description: "Opaque cursor from the prior result's meta.next_cursor",
427
443
  },
428
444
  limit: {
429
445
  type: "number",
@@ -640,7 +656,10 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
640
656
  // dispatchTool) keeps unit tests, which call dispatchTool directly, silent.
641
657
  const start = Date.now();
642
658
  const result = await dispatchTool(request.params.name, (request.params.arguments ?? {}));
643
- captureToolCall(request.params.name, Date.now() - start, result.isError !== true);
659
+ // channel:"stdio" lets the channel report separate local (npx) usage from
660
+ // hosted-gateway usage (channel:"gateway"); the Phase-2 hosted trigger
661
+ // counts only the latter.
662
+ captureToolCall(request.params.name, Date.now() - start, result.isError !== true, { channel: "stdio" });
644
663
  return result;
645
664
  });
646
665
  // ─── Tool dispatcher (exported for unit tests) ────────────────────────────────
package/dist/telemetry.js CHANGED
@@ -37,12 +37,17 @@ export function isTelemetryEnabled() {
37
37
  * the privacy invariant directly.
38
38
  */
39
39
  export function toolCallProperties(tool, durationMs, ok, extra) {
40
+ // Spread `extra` FIRST so it can never overwrite the privacy-critical /
41
+ // integrity fields below. Otherwise a future caller passing e.g.
42
+ // { tool: ... } or { ok: ... } could silently forge metrics or shadow the
43
+ // canonical fields — the "nothing sensitive by construction" guarantee
44
+ // must hold even against a coding mistake in a caller.
40
45
  return {
46
+ ...extra,
41
47
  tool,
42
48
  duration_ms: Math.round(durationMs),
43
49
  ok,
44
50
  server_version: SERVER_VERSION,
45
- ...extra,
46
51
  };
47
52
  }
48
53
  let client = null;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "opedd-mcp",
3
- "version": "0.6.7",
4
- "description": "Licensed, rights-cleared content for AI agents \u2014 verifiable license keys, on-chain proof, and EU AI Act attestation. The MCP alternative to unlicensed scraping for RAG and AI search.",
3
+ "version": "0.6.9",
4
+ "description": "Licensed, rights-cleared content for AI agents — verifiable license keys, on-chain proof, and EU AI Act attestation. The MCP alternative to unlicensed scraping for RAG and AI search.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "mcpName": "com.opedd/opedd-mcp",