opedd-mcp 0.6.14 → 0.6.15

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.
Files changed (2) hide show
  1. package/dist/index.js +29 -15
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -136,6 +136,17 @@ function credErr(missing, envVar, howToGet) {
136
136
  const HOW_BUYER_JWT = "Buyer signup is free and takes ~2 minutes: https://opedd.com/buyer/signup (an API key is issued instantly at signup). " +
137
137
  "This tool authenticates with your buyer session JWT: sign in at https://opedd.com/buyer and use the Supabase session access token. " +
138
138
  "Blocked? hello@opedd.com.";
139
+ // Phase 3 scoped keys (2026-08-26, backend PR #336): the three audit/
140
+ // compliance read surfaces also accept a buyer API key carrying the 'audit'
141
+ // scope. The key (OPEDD_BUYER_TOKEN) is long-lived and portal-manageable —
142
+ // the credential agents can actually hold; the JWT path stays for sessions.
143
+ const HOW_AUDIT_CRED = "EITHER a buyer API key with the 'audit' scope (create one free: https://opedd.com/buyer/signup, then " +
144
+ "Account \u2192 API keys \u2192 Create \u2192 tick 'Audit & compliance access'; supply it as OPEDD_BUYER_TOKEN or the " +
145
+ "Authorization header) OR a buyer portal session JWT (OPEDD_BUYER_JWT). Blocked? hello@opedd.com.";
146
+ function auditCred(creds) {
147
+ // Key preferred (durable, revocable, scope-checked server-side); JWT kept.
148
+ return creds.buyerToken || creds.buyerJwt;
149
+ }
139
150
  const HOW_ACCESS_KEY = "Enterprise access keys (ent_*) are delivered when an enterprise licence is issued — start at https://opedd.com/enterprise " +
140
151
  "or purchase programmatically with the purchase_enterprise_license tool.";
141
152
  const HOW_PUB_BEARER = "Publisher keys (opedd_pub_*) come from the publisher dashboard: sign up free at https://opedd.com, then Settings → API keys.";
@@ -492,8 +503,11 @@ function buildTools(has) {
492
503
  },
493
504
  });
494
505
  }
495
- // If a Supabase buyer JWT is configured, expose audit + compliance tools
496
- if (has.buyerJwt) {
506
+ // Expose audit + compliance tools when buyer credentials exist. Since the
507
+ // 2026-08-26 scoped-keys change (backend #336) an 'audit'-scoped buyer API
508
+ // key (OPEDD_BUYER_TOKEN) works on 3 of these 4; get_buyer_account remains
509
+ // JWT-only (its endpoint mints keys — a key must never mint keys).
510
+ if (has.buyerJwt || has.buyerToken) {
497
511
  TOOLS.push({
498
512
  name: "get_audit_events",
499
513
  description: "Browse per-event audit rows for the authenticated buyer via GET /buyer-audit (Phase 9.x). " +
@@ -501,7 +515,7 @@ function buildTools(has) {
501
515
  "Optional filter by event_type ('content_access', 'bulk_content_access', 'compliance_report_generated'). " +
502
516
  "Window cap 30 days (vs 90-day cap on get_compliance_dossier). " +
503
517
  "Attestation inclusion proof is included on every row by default — no separate flag needed (M6.4 consolidation per founder ratification: tools 4 + 6 merged into one cleaner mental model). " +
504
- "Requires OPEDD_BUYER_JWT (Supabase session JWT from the buyer portal).",
518
+ "Auth: an audit-scoped buyer API key (OPEDD_BUYER_TOKEN — create at opedd.com/buyer, Account \u2192 API keys) or OPEDD_BUYER_JWT.",
505
519
  inputSchema: {
506
520
  type: "object",
507
521
  properties: {
@@ -538,7 +552,7 @@ function buildTools(has) {
538
552
  "Use cases: post-signup verification ('what was just issued to me?'), buyer dashboard mental model " +
539
553
  "('what licenses do I currently hold?'), audit prep ('show me the key list before rotation'). " +
540
554
  "For full mid-lifecycle license details (filter_rules, billing, payouts), buyers consult the buyer portal at opedd.com/buyer. " +
541
- "Requires OPEDD_BUYER_JWT.",
555
+ "Requires OPEDD_BUYER_JWT (JWT-only by design: this surface manages API keys, and a key must never mint keys).",
542
556
  inputSchema: {
543
557
  type: "object",
544
558
  properties: {},
@@ -556,7 +570,7 @@ function buildTools(has) {
556
570
  "transparency obligation). It does NOT discharge a publisher's CDSM Article 4(3) reservation obligation — " +
557
571
  "that lives on the rsl_get tool (jsonld=true variant). Never conflate. " +
558
572
  "Optional `content_id` scopes the attestation to one article; default is license-wide. " +
559
- "Window cap: 365 days. Requires OPEDD_BUYER_JWT.",
573
+ "Window cap: 365 days. Auth: an audit-scoped buyer API key (OPEDD_BUYER_TOKEN) or OPEDD_BUYER_JWT.",
560
574
  inputSchema: {
561
575
  type: "object",
562
576
  required: ["license_id"],
@@ -588,7 +602,7 @@ function buildTools(has) {
588
602
  "Self-audit invariant: every successful call writes one license_events row with event_type='compliance_report_generated' BEFORE returning. " +
589
603
  "Window cap: 90 days per call (vs 30-day cap on get_audit_events). For annual audits, paginate via _meta.next_cursor across 4 quarterly windows. " +
590
604
  "Compliance framework anchors (boolean flags) map to EU AI Act Article 53, CDSM Article 4(3), on-chain attestation, TDM reservation. " +
591
- "Requires OPEDD_BUYER_JWT.",
605
+ "Auth: an audit-scoped buyer API key (OPEDD_BUYER_TOKEN) or OPEDD_BUYER_JWT.",
592
606
  inputSchema: {
593
607
  type: "object",
594
608
  required: ["from", "to"],
@@ -929,8 +943,8 @@ export async function dispatchTool(name, args, creds = ENV_CREDS) {
929
943
  }
930
944
  // ── get_audit_events (Phase 9.x + 10 M5 attestation) ───────────────────
931
945
  case "get_audit_events": {
932
- if (!creds.buyerJwt) {
933
- return credErr("A buyer session JWT is required for this tool", "OPEDD_BUYER_JWT", HOW_BUYER_JWT);
946
+ if (!auditCred(creds)) {
947
+ return credErr("Buyer credentials are required for this tool", "OPEDD_BUYER_TOKEN (audit-scoped key) or OPEDD_BUYER_JWT", HOW_AUDIT_CRED);
934
948
  }
935
949
  const { from, to, event_type, cursor, limit = 50 } = args;
936
950
  const params = new URLSearchParams({
@@ -945,7 +959,7 @@ export async function dispatchTool(name, args, creds = ENV_CREDS) {
945
959
  if (cursor)
946
960
  params.set("cursor", cursor);
947
961
  const data = await opeddFetch(creds, `/buyer-audit?${params.toString()}`, {
948
- headers: { Authorization: `Bearer ${creds.buyerJwt}` },
962
+ headers: { Authorization: `Bearer ${auditCred(creds)}` },
949
963
  });
950
964
  return ok(data);
951
965
  }
@@ -961,8 +975,8 @@ export async function dispatchTool(name, args, creds = ENV_CREDS) {
961
975
  }
962
976
  // ── article_53_attestation (Phase 12 Wave 1 W1.4) ──────────────────────
963
977
  case "article_53_attestation": {
964
- if (!creds.buyerJwt) {
965
- return credErr("A buyer session JWT is required for this tool", "OPEDD_BUYER_JWT", HOW_BUYER_JWT);
978
+ if (!auditCred(creds)) {
979
+ return credErr("Buyer credentials are required for this tool", "OPEDD_BUYER_TOKEN (audit-scoped key) or OPEDD_BUYER_JWT", HOW_AUDIT_CRED);
966
980
  }
967
981
  const { license_id, content_id, window_start, window_end } = args;
968
982
  if (!license_id)
@@ -979,13 +993,13 @@ export async function dispatchTool(name, args, creds = ENV_CREDS) {
979
993
  // slashed "/eu-ai-act/article-53-attestation" resolved to a
980
994
  // nonexistent function named "eu-ai-act" and 404'd — this tool had
981
995
  // NEVER worked in production until the 2026-07-10 fix (live-probed).
982
- const data = await opeddFetch(creds, `/eu-ai-act-article-53-attestation?${params.toString()}`, { headers: { Authorization: `Bearer ${creds.buyerJwt}` } });
996
+ const data = await opeddFetch(creds, `/eu-ai-act-article-53-attestation?${params.toString()}`, { headers: { Authorization: `Bearer ${auditCred(creds)}` } });
983
997
  return ok(data);
984
998
  }
985
999
  // ── get_compliance_dossier (Phase 11 M4) ───────────────────────────────
986
1000
  case "get_compliance_dossier": {
987
- if (!creds.buyerJwt) {
988
- return credErr("A buyer session JWT is required for this tool", "OPEDD_BUYER_JWT", HOW_BUYER_JWT);
1001
+ if (!auditCred(creds)) {
1002
+ return credErr("Buyer credentials are required for this tool", "OPEDD_BUYER_TOKEN (audit-scoped key) or OPEDD_BUYER_JWT", HOW_AUDIT_CRED);
989
1003
  }
990
1004
  const { from, to, cursor } = args;
991
1005
  if (!from)
@@ -1000,7 +1014,7 @@ export async function dispatchTool(name, args, creds = ENV_CREDS) {
1000
1014
  if (cursor)
1001
1015
  params.set("cursor", cursor);
1002
1016
  const data = await opeddFetch(creds, `/buyer-compliance-report?${params.toString()}`, {
1003
- headers: { Authorization: `Bearer ${creds.buyerJwt}` },
1017
+ headers: { Authorization: `Bearer ${auditCred(creds)}` },
1004
1018
  });
1005
1019
  return ok(data);
1006
1020
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opedd-mcp",
3
- "version": "0.6.14",
3
+ "version": "0.6.15",
4
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",