opedd-mcp 0.6.8 → 0.6.10

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
@@ -125,8 +141,13 @@ function buildTools(has) {
125
141
  "License types: 'human' = republication rights, 'ai' = training dataset rights, 'ai_inference' = inference/RAG rights.",
126
142
  inputSchema: {
127
143
  type: "object",
128
- required: ["license_type"],
144
+ required: ["license_type", "terms_accepted"],
129
145
  properties: {
146
+ terms_accepted: {
147
+ type: "boolean",
148
+ description: "REQUIRED. Set true only after the buyer (your principal) has accepted the Opedd licence terms at opedd.com/terms. " +
149
+ "The acceptance timestamp is recorded with the licence; purchases without genuine acceptance are rejected.",
150
+ },
130
151
  article_url: {
131
152
  type: "string",
132
153
  description: "URL of the article to license (use this OR article_id)",
@@ -396,7 +417,7 @@ function buildTools(has) {
396
417
  },
397
418
  cursor: {
398
419
  type: "string",
399
- description: "Opaque cursor from prior response's _meta.next_cursor",
420
+ description: "Opaque cursor from the prior response's data.pagination.next_cursor",
400
421
  },
401
422
  limit: {
402
423
  type: "number",
@@ -423,7 +444,7 @@ function buildTools(has) {
423
444
  },
424
445
  cursor: {
425
446
  type: "string",
426
- description: "Opaque cursor from prior response's _meta.next_cursor",
447
+ description: "Opaque cursor from the prior result's meta.next_cursor",
427
448
  },
428
449
  limit: {
429
450
  type: "number",
@@ -670,6 +691,10 @@ export async function dispatchTool(name, args, creds = ENV_CREDS) {
670
691
  if (!article_url && !article_id) {
671
692
  return err("Either article_url or article_id is required");
672
693
  }
694
+ const termsAccepted = args.terms_accepted;
695
+ if (termsAccepted !== true) {
696
+ return err("terms_accepted must be true — confirm with the buyer that they accept the Opedd licence terms (opedd.com/terms) before purchasing.");
697
+ }
673
698
  const buyerEmail = argEmail || creds.buyerEmail;
674
699
  if (!buyerEmail) {
675
700
  return err("buyer_email is required (or set the OPEDD_BUYER_EMAIL env var)");
@@ -682,6 +707,8 @@ export async function dispatchTool(name, args, creds = ENV_CREDS) {
682
707
  const body = {
683
708
  license_type,
684
709
  buyer_email: buyerEmail,
710
+ // Genuine assent moment: the agent asserted terms_accepted=true just now.
711
+ terms_accepted_at: new Date().toISOString(),
685
712
  payment: { method: "stripe_pm", payment_method_id: paymentMethodId },
686
713
  ...(article_id ? { article_id } : { article_url }),
687
714
  ...(buyer_name ? { buyer_name } : {}),
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "opedd-mcp",
3
- "version": "0.6.8",
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.10",
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",