opedd-mcp 0.6.15 → 0.7.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/README.md +3 -3
- package/dist/index.d.ts +1 -1
- package/dist/index.js +49 -8
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -78,7 +78,7 @@ Prefer zero-install? The same 17 tools are served hosted at **`https://mcp.opedd
|
|
|
78
78
|
}
|
|
79
79
|
```
|
|
80
80
|
|
|
81
|
-
Key routing: `opedd_pub_*` → publisher tools · `opedd_buyer_*` → content retrieval · `ent_*` → bulk feeds · buyer-portal JWT → audit/compliance/EU-AI-Act tools. Your key is forwarded per request and never stored by the gateway.
|
|
81
|
+
Key routing: `opedd_sk_*` (legacy `opedd_pub_*`) → publisher tools · `opedd_buyer_*` → content retrieval · `ent_*` → bulk feeds · buyer-portal JWT → audit/compliance/EU-AI-Act tools. Your key is forwarded per request and never stored by the gateway.
|
|
82
82
|
|
|
83
83
|
## What it does
|
|
84
84
|
|
|
@@ -119,7 +119,7 @@ Exposes up to 17 tools to any AI assistant (some are conditional on env vars):
|
|
|
119
119
|
| `get_compliance_dossier` | Procurement-defense compliance dossier mapping retrievals to license terms (Phase 11 M4) |
|
|
120
120
|
| `article_53_attestation` | Signed JWT attesting EU AI Act Article 53(1)(d) compliance for a license — the artifact AI labs hand to legal/procurement (Phase 12 W1.4) |
|
|
121
121
|
|
|
122
|
-
**Requires `OPEDD_PUB_BEARER` (opedd_pub_*) — publisher-side**
|
|
122
|
+
**Requires `OPEDD_PUB_BEARER` (opedd_sk_*; legacy opedd_pub_* still works) — publisher-side**
|
|
123
123
|
|
|
124
124
|
| Tool | Description |
|
|
125
125
|
|------|-------------|
|
|
@@ -159,7 +159,7 @@ Set environment variables to pre-configure the server:
|
|
|
159
159
|
| `OPEDD_BUYER_TOKEN` | Optional | Buyer API token (`opedd_buyer_live_*` canonical; `opedd_buyer_test_*` for sandbox) — enables `get_content` |
|
|
160
160
|
| `OPEDD_ACCESS_KEY` | Optional | Enterprise access key (`ent_*`) — enables `list_feed` + `stream_feed_ndjson` |
|
|
161
161
|
| `OPEDD_BUYER_JWT` | Optional | Supabase session JWT from the buyer portal — enables `get_buyer_account` + `get_audit_events` + `get_compliance_dossier` + `article_53_attestation` |
|
|
162
|
-
| `OPEDD_PUB_BEARER` | Optional |
|
|
162
|
+
| `OPEDD_PUB_BEARER` | Optional | Publisher API key (`opedd_sk_<32-hex>`, canonical since 2026-08-27; older `opedd_pub_<32-hex>` keys keep working) — from the Opedd dashboard, Settings → Developers. Enables `list_publisher_content` (+ `include_body`) and `push_content`. |
|
|
163
163
|
| `OPEDD_API_KEY` | Deprecated | Legacy Publisher API key (`op_...`) — fallback during the transition window; will stop working when opedd-backend Phase C deploys. Migrate to `OPEDD_PUB_BEARER`. |
|
|
164
164
|
| `OPEDD_API_URL` | Optional | Override the API base URL (default: Opedd production) |
|
|
165
165
|
| `OPEDD_MCP_TELEMETRY` | Optional | Set to `0` to disable anonymous usage telemetry (see below) |
|
package/dist/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ export interface Credentials {
|
|
|
5
5
|
apiBase: string;
|
|
6
6
|
buyerEmail?: string;
|
|
7
7
|
paymentMethodId?: string;
|
|
8
|
-
/** canonical
|
|
8
|
+
/** canonical opedd_sk_<32-hex> key (legacy opedd_pub_ accepted) */
|
|
9
9
|
pubBearer?: string;
|
|
10
10
|
/** LEGACY op_<32-hex> — retiring per backend Phase C */
|
|
11
11
|
apiKey?: string;
|
package/dist/index.js
CHANGED
|
@@ -149,7 +149,7 @@ function auditCred(creds) {
|
|
|
149
149
|
}
|
|
150
150
|
const HOW_ACCESS_KEY = "Enterprise access keys (ent_*) are delivered when an enterprise licence is issued — start at https://opedd.com/enterprise " +
|
|
151
151
|
"or purchase programmatically with the purchase_enterprise_license tool.";
|
|
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.";
|
|
152
|
+
const HOW_PUB_BEARER = "Publisher keys (opedd_sk_*, legacy opedd_pub_* still valid) come from the publisher dashboard: sign up free at https://opedd.com, then Settings → API keys.";
|
|
153
153
|
// ─── Tool definitions ─────────────────────────────────────────────────────────
|
|
154
154
|
function buildTools(has) {
|
|
155
155
|
const TOOLS = [
|
|
@@ -629,22 +629,36 @@ function buildTools(has) {
|
|
|
629
629
|
name: "list_publisher_content",
|
|
630
630
|
description: "List all licensable articles for the authenticated publisher (requires OPEDD_PUB_BEARER, or legacy OPEDD_API_KEY). " +
|
|
631
631
|
"Returns articles with titles, descriptions, pricing, and sales statistics. " +
|
|
632
|
+
"Set include_body=true to read back the STORED article text exactly as licensed buyers receive it " +
|
|
633
|
+
"(this is how you check that a push_content call stored what you meant; bodies are truncated to 8,000 characters per article, page size 20, paginate with cursor). " +
|
|
632
634
|
"Use article IDs from this list to purchase licenses via purchase_license.",
|
|
633
635
|
inputSchema: {
|
|
634
636
|
type: "object",
|
|
635
637
|
properties: {
|
|
636
638
|
limit: {
|
|
637
639
|
type: "number",
|
|
638
|
-
description: "Number of results (default: 20, max: 100)",
|
|
640
|
+
description: "Number of results (default: 20, max: 100; max 20 when include_body is true)",
|
|
639
641
|
},
|
|
640
642
|
type: {
|
|
641
643
|
type: "string",
|
|
642
644
|
enum: ["human", "ai"],
|
|
643
|
-
description: "Filter by license type availability",
|
|
645
|
+
description: "Filter by license type availability (ignored when include_body is true)",
|
|
644
646
|
},
|
|
645
647
|
offset: {
|
|
646
648
|
type: "number",
|
|
647
|
-
description: "Pagination offset (default: 0)",
|
|
649
|
+
description: "Pagination offset (default: 0; ignored when include_body is true — use cursor)",
|
|
650
|
+
},
|
|
651
|
+
include_body: {
|
|
652
|
+
type: "boolean",
|
|
653
|
+
description: "Return each article's stored body (what buyers receive). Default false.",
|
|
654
|
+
},
|
|
655
|
+
cursor: {
|
|
656
|
+
type: "string",
|
|
657
|
+
description: "Opaque next_cursor from a previous include_body=true call.",
|
|
658
|
+
},
|
|
659
|
+
id: {
|
|
660
|
+
type: "string",
|
|
661
|
+
description: "With include_body=true: fetch exactly one of your articles by id (full body, no truncation).",
|
|
648
662
|
},
|
|
649
663
|
},
|
|
650
664
|
},
|
|
@@ -653,7 +667,7 @@ function buildTools(has) {
|
|
|
653
667
|
// the AI assistant — the native companion to the /publishers-content API.
|
|
654
668
|
TOOLS.push({
|
|
655
669
|
name: "push_content",
|
|
656
|
-
description: "Push your published articles to Opedd so they can be licensed to AI buyers (requires OPEDD_PUB_BEARER — your
|
|
670
|
+
description: "Push your published articles to Opedd so they can be licensed to AI buyers (requires OPEDD_PUB_BEARER — your opedd_sk_ publisher key). " +
|
|
657
671
|
"Send 1–100 articles per call; batch larger back-catalogues into multiple calls. Each article needs title, url, and html_body — everything else is optional (published_at defaults to now). " +
|
|
658
672
|
"This is the supply-side companion to list_publisher_content: use it to onboard your archive or push new content with no code, straight from your AI assistant.",
|
|
659
673
|
inputSchema: {
|
|
@@ -1021,9 +1035,36 @@ export async function dispatchTool(name, args, creds = ENV_CREDS) {
|
|
|
1021
1035
|
// ── list_publisher_content ─────────────────────────────────────────────
|
|
1022
1036
|
case "list_publisher_content": {
|
|
1023
1037
|
if (!creds.pubBearer && !creds.apiKey) {
|
|
1024
|
-
return credErr("A publisher key (
|
|
1038
|
+
return credErr("A publisher key (opedd_sk_*) is required for this tool", "OPEDD_PUB_BEARER", HOW_PUB_BEARER);
|
|
1039
|
+
}
|
|
1040
|
+
const { limit = 20, type, offset = 0, include_body, cursor, id } = args;
|
|
1041
|
+
// include_body (2026-09-14): the OWNER read model — GET /publishers-content
|
|
1042
|
+
// returns the stored body for the key's own rows. Bodies are truncated
|
|
1043
|
+
// here to keep the assistant's context bounded; ?id= returns one in full.
|
|
1044
|
+
if (include_body === true) {
|
|
1045
|
+
const q = new URLSearchParams({ include_body: "true" });
|
|
1046
|
+
if (typeof id === "string" && id)
|
|
1047
|
+
q.set("id", id);
|
|
1048
|
+
else {
|
|
1049
|
+
q.set("limit", String(Math.min(Math.max(Number(limit) || 20, 1), 20)));
|
|
1050
|
+
if (typeof cursor === "string" && cursor)
|
|
1051
|
+
q.set("cursor", cursor);
|
|
1052
|
+
}
|
|
1053
|
+
// Backend envelope is { success, data: {...} }; unwrap so the assistant
|
|
1054
|
+
// sees the payload, not the wrapper (envelope-unwrap rule).
|
|
1055
|
+
const envelope = (await opeddFetch(creds, `/publishers-content?${q.toString()}`));
|
|
1056
|
+
const data = envelope.data ?? {};
|
|
1057
|
+
const MAX = 8_000;
|
|
1058
|
+
const trim = (a) => {
|
|
1059
|
+
const body = typeof a.content_body === "string" ? a.content_body : null;
|
|
1060
|
+
return body !== null && body.length > MAX
|
|
1061
|
+
? { ...a, content_body: body.slice(0, MAX), body_truncated: true, body_length: body.length }
|
|
1062
|
+
: { ...a, body_truncated: false, body_length: body?.length ?? 0 };
|
|
1063
|
+
};
|
|
1064
|
+
if (data.article)
|
|
1065
|
+
return ok({ article: { ...data.article, body_truncated: false, body_length: typeof data.article.content_body === "string" ? data.article.content_body.length : 0 } });
|
|
1066
|
+
return ok({ articles: (data.articles ?? []).map(trim), pagination: data.pagination ?? null });
|
|
1025
1067
|
}
|
|
1026
|
-
const { limit = 20, type, offset = 0 } = args;
|
|
1027
1068
|
const params = new URLSearchParams({ action: "articles" });
|
|
1028
1069
|
params.set("limit", String(Math.min(Number(limit), 100)));
|
|
1029
1070
|
params.set("offset", String(Number(offset)));
|
|
@@ -1035,7 +1076,7 @@ export async function dispatchTool(name, args, creds = ENV_CREDS) {
|
|
|
1035
1076
|
// ── push_content ───────────────────────────────────────────────────────
|
|
1036
1077
|
case "push_content": {
|
|
1037
1078
|
if (!creds.pubBearer && !creds.apiKey) {
|
|
1038
|
-
return credErr("A publisher key (
|
|
1079
|
+
return credErr("A publisher key (opedd_sk_*) is required for this tool", "OPEDD_PUB_BEARER", HOW_PUB_BEARER);
|
|
1039
1080
|
}
|
|
1040
1081
|
const { articles } = args;
|
|
1041
1082
|
if (!Array.isArray(articles) || articles.length === 0) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opedd-mcp",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Licensed, rights-cleared content for AI agents
|
|
3
|
+
"version": "0.7.0",
|
|
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.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"mcpName": "com.opedd/opedd-mcp",
|
|
@@ -60,4 +60,4 @@
|
|
|
60
60
|
"overrides": {
|
|
61
61
|
"esbuild": "^0.28.1"
|
|
62
62
|
}
|
|
63
|
-
}
|
|
63
|
+
}
|