opedd-mcp 0.12.14 → 0.12.16
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 +6 -12
- package/dist/index.d.ts +1 -1
- package/dist/index.js +15 -73
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -35,7 +35,7 @@ Then add it to your MCP host (see [Claude Desktop / Cursor / Windsurf setup](#cl
|
|
|
35
35
|
|
|
36
36
|
## Hosted endpoint — no install (mcp.opedd.com)
|
|
37
37
|
|
|
38
|
-
Prefer zero-install? The same
|
|
38
|
+
Prefer zero-install? The same 19 tools are served hosted at **`https://mcp.opedd.com/mcp`** (Streamable HTTP). Auth is an `Authorization: Bearer` header with any Opedd key — public discovery tools need no auth at all.
|
|
39
39
|
|
|
40
40
|
**Claude Messages API** (production agents):
|
|
41
41
|
|
|
@@ -82,7 +82,7 @@ Key routing: `opedd_sk_*` (legacy `opedd_pub_*`) → publisher tools · `opedd_b
|
|
|
82
82
|
|
|
83
83
|
## What it does
|
|
84
84
|
|
|
85
|
-
Exposes up to
|
|
85
|
+
Exposes up to 19 tools to any AI assistant (some are conditional on env vars):
|
|
86
86
|
|
|
87
87
|
Every tool carries a `title` and MCP annotations (`readOnlyHint`, `destructiveHint`, `idempotentHint`, `openWorldHint`) so an assistant can tell which tools only read and which spend money or write (v0.12.0).
|
|
88
88
|
|
|
@@ -114,7 +114,7 @@ Every tool carries a `title` and MCP annotations (`readOnlyHint`, `destructiveHi
|
|
|
114
114
|
| `list_feed` | List the articles a licence order covers, with `since` delta-feed support. AI training and Full catalogue orders carry full `content_body` (`content_access: "included"`); monthly orders are discovery-only (`content_access: "retrieval_per_article"`, fetch text via `get_content`); per-request orders are `"search_only"`. With a buyer key, pass `order_id` (optional when the account holds one active order) |
|
|
115
115
|
| `stream_feed_ndjson` | Bulk-export up to 1000 articles per call via NDJSON wire format. Same content contract and credentials as `list_feed` |
|
|
116
116
|
|
|
117
|
-
**Requires `OPEDD_BUYER_JWT` (Supabase JWT) — buyer account + audit + compliance
|
|
117
|
+
**Requires `OPEDD_BUYER_JWT` (Supabase JWT) — buyer account + audit + compliance surfaces**
|
|
118
118
|
|
|
119
119
|
| Tool | Description |
|
|
120
120
|
|------|-------------|
|
|
@@ -122,7 +122,6 @@ Every tool carries a `title` and MCP annotations (`readOnlyHint`, `destructiveHi
|
|
|
122
122
|
| `list_licence_orders` | The buyer's licence orders and lines; with `order_id`, each line's Schedule document and its SHA-256 (the fingerprint recorded on Tempo). Also works with an audit-scoped `OPEDD_BUYER_TOKEN` |
|
|
123
123
|
| `get_audit_events` | Per-event audit ledger with public-record (Tempo) inclusion proofs inline (Phase 9.x + 10 M5) |
|
|
124
124
|
| `get_compliance_dossier` | Procurement-defense compliance dossier mapping retrievals to license terms (Phase 11 M4) |
|
|
125
|
-
| `article_53_attestation` | Signed compliance attestation (JWT) for a license — the artifact a buyer hands to legal/procurement (Phase 12 W1.4) |
|
|
126
125
|
|
|
127
126
|
**Requires `OPEDD_PUB_BEARER` (opedd_sk_*; legacy opedd_pub_* still works) — publisher-side**
|
|
128
127
|
|
|
@@ -136,10 +135,7 @@ Every tool carries a `title` and MCP annotations (`readOnlyHint`, `destructiveHi
|
|
|
136
135
|
Per Opedd's platform invariants (W1.6 amendment):
|
|
137
136
|
|
|
138
137
|
- **`rsl_get(publisher_id, jsonld=true)`** → publisher-side **CDSM Article 4(3)** opt-out declaration (signed JSON-LD receipt over the reservation state).
|
|
139
|
-
- **`
|
|
140
|
-
- **`get_compliance_dossier(from, to)`** → comprehensive procurement-defense dossier covering BOTH sides (publisher CDSM reservation honored + buyer attestation evidence chain).
|
|
141
|
-
|
|
142
|
-
These serve different audit-defensibility modes and never share wire format. Tool descriptions cite the W1.6 invariant inline.
|
|
138
|
+
- **`get_compliance_dossier(from, to)`** → procurement-defense dossier: every licensed retrieval in a window, with its licence terms, the publisher's CDSM reservation status and public-record proof.
|
|
143
139
|
|
|
144
140
|
## Install
|
|
145
141
|
|
|
@@ -161,7 +157,7 @@ Set environment variables to pre-configure the server:
|
|
|
161
157
|
|----------|----------|-------------|
|
|
162
158
|
| `OPEDD_BUYER_TOKEN` | Optional | Buyer API key (`opedd_buyer_live_*`; `opedd_buyer_test_*` for sandbox) — enables `search_passages` (with the `search` scope), `get_content`, `list_feed` + `stream_feed_ndjson` (with `order_id`) |
|
|
163
159
|
| `OPEDD_ACCESS_KEY` | Optional | An order's enterprise access key (`ent_*`) — alternative credential for `list_feed` + `stream_feed_ndjson` |
|
|
164
|
-
| `OPEDD_BUYER_JWT` | Optional | Supabase session JWT from the buyer portal — enables `place_licence_order` + `list_licence_orders` + `get_buyer_account` + `get_audit_events` + `get_compliance_dossier`
|
|
160
|
+
| `OPEDD_BUYER_JWT` | Optional | Supabase session JWT from the buyer portal — enables `place_licence_order` + `list_licence_orders` + `get_buyer_account` + `get_audit_events` + `get_compliance_dossier` |
|
|
165
161
|
| `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`. |
|
|
166
162
|
| `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`. |
|
|
167
163
|
| `OPEDD_API_URL` | Optional | Override the API base URL (default: Opedd production) |
|
|
@@ -238,8 +234,6 @@ Once configured, you can ask your AI assistant:
|
|
|
238
234
|
|
|
239
235
|
> "Get me a CDSM Article 4(3) signed receipt for that publisher's reservation state — set `jsonld: true`." — uses `rsl_get` with content negotiation
|
|
240
236
|
|
|
241
|
-
> "Generate a signed compliance attestation for our license `11111111-...` covering the last 90 days. I need the artifact for our procurement audit committee." — uses `article_53_attestation` (requires `OPEDD_BUYER_JWT`)
|
|
242
|
-
|
|
243
237
|
> "This publisher just signed up: `https://noahpinion.substack.com`. Which onboarding workflow should we use?" — uses `detect_platform`
|
|
244
238
|
|
|
245
239
|
> "Browse the finance category in the Opedd catalog — show me publishers with at least 50 articles." — uses `publisher_directory`
|
|
@@ -273,7 +267,7 @@ npm run build # compiles to dist/
|
|
|
273
267
|
| **Content quality** | Curated publisher content (niche B2B newsletters, expert analysis) | Whatever's on the open web |
|
|
274
268
|
| **Rights** | Verifiable licence for every use, publisher-authorized | No rights clearance |
|
|
275
269
|
| **Proof** | Public record (Tempo) — independently verifiable | None |
|
|
276
|
-
| **Compliance** |
|
|
270
|
+
| **Compliance** | Audit log, compliance dossier and full provenance chain | No provenance |
|
|
277
271
|
| **Pricing** | Publisher sets their own prices | Platform decides |
|
|
278
272
|
| **Delivery modes** | Article API, bulk feed (JSON firehose), buyer webhooks (push) | Query-response only |
|
|
279
273
|
| **Protocol** | REST + MCP native | REST only |
|
package/dist/index.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ export interface Credentials {
|
|
|
10
10
|
buyerToken?: string;
|
|
11
11
|
/** enterprise access key (ent_*) — /enterprise-license GET feed */
|
|
12
12
|
accessKey?: string;
|
|
13
|
-
/** Supabase JWT — buyer-audit + compliance
|
|
13
|
+
/** Supabase JWT — buyer-audit + compliance surfaces */
|
|
14
14
|
buyerJwt?: string;
|
|
15
15
|
}
|
|
16
16
|
export declare function envCredentials(): Credentials;
|
package/dist/index.js
CHANGED
|
@@ -180,7 +180,7 @@ function feedCredential(creds, args) {
|
|
|
180
180
|
}
|
|
181
181
|
const HOW_ACCESS_KEY = "Enterprise access keys (ent_*) are delivered when an enterprise licence is issued — start at https://opedd.com/enterprise " +
|
|
182
182
|
"or place a licence order with the place_licence_order tool.";
|
|
183
|
-
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 →
|
|
183
|
+
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 → For developers.";
|
|
184
184
|
// ─── Tool definitions ─────────────────────────────────────────────────────────
|
|
185
185
|
function buildTools(has) {
|
|
186
186
|
const TOOLS = [
|
|
@@ -200,7 +200,7 @@ function buildTools(has) {
|
|
|
200
200
|
},
|
|
201
201
|
{
|
|
202
202
|
name: "request_publication",
|
|
203
|
-
description: "Asks Opedd to tell you when a publication it does not carry yet becomes available to license.
|
|
203
|
+
description: "Asks Opedd to tell you when a publication it does not carry yet becomes available to license. For an article that lookup_content reports is not on Opedd. Records the request against the email given; nothing is bought. If the publication is already on Opedd, returns its licensing page instead. Free; no key needed.",
|
|
204
204
|
inputSchema: {
|
|
205
205
|
type: "object",
|
|
206
206
|
required: ["url", "email"],
|
|
@@ -326,8 +326,7 @@ function buildTools(has) {
|
|
|
326
326
|
"CDSM Article 4(3) reservation state + `tdm:reservationSignedAt` timestamp — regulators can post-hoc " +
|
|
327
327
|
"verify the reservation was the claimed value at the claimed time. Default `jsonld: false` returns " +
|
|
328
328
|
"the raw RSL Standard JSON manifest. " +
|
|
329
|
-
"This is the publisher's own declaration
|
|
330
|
-
"(use article_53_attestation for that).",
|
|
329
|
+
"This is the publisher's own declaration, not a record of a buyer's use (get_compliance_dossier records that).",
|
|
331
330
|
inputSchema: {
|
|
332
331
|
type: "object",
|
|
333
332
|
required: ["publisher_id"],
|
|
@@ -432,7 +431,7 @@ function buildTools(has) {
|
|
|
432
431
|
"The publisher must have content delivery enabled and must have pushed content for the article. " +
|
|
433
432
|
"The response includes author, language, word_count, content_hash, image_urls, canonical_url and tags. " +
|
|
434
433
|
"On pre-2026-05-14 historical articles, optional fields (author/language/image_urls/canonical_url/tags) may be NULL. " +
|
|
435
|
-
"NULL means
|
|
434
|
+
"NULL means the data is unavailable for this article, not that it is empty.",
|
|
436
435
|
inputSchema: {
|
|
437
436
|
type: "object",
|
|
438
437
|
required: ["article_id"],
|
|
@@ -465,7 +464,7 @@ function buildTools(has) {
|
|
|
465
464
|
"Credentials: the order's enterprise access key (OPEDD_ACCESS_KEY, ent_*) OR your buyer API key " +
|
|
466
465
|
"(OPEDD_BUYER_TOKEN) with order_id — if your account holds exactly one active order, order_id may be omitted; " +
|
|
467
466
|
"with several, the error lists them. " +
|
|
468
|
-
"
|
|
467
|
+
"stream_feed_ndjson returns up to 1000 articles per call (200 here).",
|
|
469
468
|
inputSchema: {
|
|
470
469
|
type: "object",
|
|
471
470
|
properties: {
|
|
@@ -493,11 +492,11 @@ function buildTools(has) {
|
|
|
493
492
|
description: "Bulk-export the articles in a licence order you hold. " +
|
|
494
493
|
"Returns up to 1000 articles per call (collected from line-delimited JSON wire format). " +
|
|
495
494
|
"Same content contract as list_feed: full text for AI training orders only; every other order exports " +
|
|
496
|
-
"metadata (content_body null)
|
|
495
|
+
"metadata (content_body null); get_content returns article text. " +
|
|
497
496
|
"Each exported article is recorded for analytics; a bulk export is not billed per article. " +
|
|
498
|
-
"
|
|
497
|
+
"`since` (ISO 8601) returns a delta feed; `cursor` pages beyond 1000. " +
|
|
499
498
|
"Backend supports 5000 articles per call; the MCP cap is 1000 for transport reasonability. " +
|
|
500
|
-
"
|
|
499
|
+
"For bulk-ingest pipelines, the Python SDK (pip install opedd) reads the same feed without the MCP cap. " +
|
|
501
500
|
"Credentials as list_feed: OPEDD_ACCESS_KEY (ent_*) OR your buyer API key + order_id.",
|
|
502
501
|
inputSchema: {
|
|
503
502
|
type: "object",
|
|
@@ -584,42 +583,9 @@ function buildTools(has) {
|
|
|
584
583
|
properties: {},
|
|
585
584
|
},
|
|
586
585
|
});
|
|
587
|
-
TOOLS.push({
|
|
588
|
-
name: "article_53_attestation",
|
|
589
|
-
description: "Issue a signed compliance attestation (a JWT) for a licence you hold. " +
|
|
590
|
-
"Returns a freshly-signed HS256 JWT regulators can verify offline against the canonical signing key. " +
|
|
591
|
-
"Embeds: license context, usage-count over the attestation window, the most-recent Tempo Merkle root, " +
|
|
592
|
-
"and canonical claims (iss/sub/iat/exp/jti/aud). " +
|
|
593
|
-
"**The artifact a buyer hands to legal/procurement as evidence of where its content came from.** " +
|
|
594
|
-
"It attests how your licence was used; the publisher's own licensing declaration is rsl_get. " +
|
|
595
|
-
"Optional `content_id` scopes the attestation to one article; default is license-wide. " +
|
|
596
|
-
"Window cap: 365 days. Auth: an audit-scoped buyer API key (OPEDD_BUYER_TOKEN) or OPEDD_BUYER_JWT.",
|
|
597
|
-
inputSchema: {
|
|
598
|
-
type: "object",
|
|
599
|
-
required: ["license_id"],
|
|
600
|
-
properties: {
|
|
601
|
-
license_id: {
|
|
602
|
-
type: "string",
|
|
603
|
-
description: "UUID of the enterprise_license OR legacy individual license to attest. Buyer must own it.",
|
|
604
|
-
},
|
|
605
|
-
content_id: {
|
|
606
|
-
type: "string",
|
|
607
|
-
description: "Optional UUID of a specific article to scope the attestation. Default: license-wide.",
|
|
608
|
-
},
|
|
609
|
-
window_start: {
|
|
610
|
-
type: "string",
|
|
611
|
-
description: "ISO 8601 lower bound of the attestation window. Default: now - 90 days.",
|
|
612
|
-
},
|
|
613
|
-
window_end: {
|
|
614
|
-
type: "string",
|
|
615
|
-
description: "ISO 8601 upper bound. Default: now. Window may not exceed 365 days (hard cap).",
|
|
616
|
-
},
|
|
617
|
-
},
|
|
618
|
-
},
|
|
619
|
-
});
|
|
620
586
|
TOOLS.push({
|
|
621
587
|
name: "get_compliance_dossier",
|
|
622
|
-
description: "Returns the account's compliance dossier for a period: one row per licensed article, with article metadata, licence terms, public-record attestation and compliance flags (
|
|
588
|
+
description: "Returns the account's compliance dossier for a period: one row per licensed article, with article metadata, licence terms, public-record attestation and compliance flags (CDSM Article 4(3) and text-and-data-mining reservations). At most 90 days per call; longer periods are paginated with _meta.next_cursor. Each call is recorded in the account's audit log. Requires a buyer API key with the 'audit' scope, a buyer session, or the Opedd connector sign-in.",
|
|
623
589
|
inputSchema: {
|
|
624
590
|
type: "object",
|
|
625
591
|
required: ["from", "to"],
|
|
@@ -680,7 +646,7 @@ function buildTools(has) {
|
|
|
680
646
|
name: "push_content",
|
|
681
647
|
description: "Push your published articles to Opedd so they can be licensed to AI buyers (requires OPEDD_PUB_BEARER — your opedd_sk_ publisher key). " +
|
|
682
648
|
"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). " +
|
|
683
|
-
"This is the supply-side companion to list_publisher_content:
|
|
649
|
+
"This is the supply-side companion to list_publisher_content: it sends a back catalogue or new articles with no code, from an AI assistant.",
|
|
684
650
|
inputSchema: {
|
|
685
651
|
type: "object",
|
|
686
652
|
required: ["articles"],
|
|
@@ -737,7 +703,6 @@ export const TOOL_ANNOTATIONS = {
|
|
|
737
703
|
list_licence_orders: read("List your licence orders"),
|
|
738
704
|
get_audit_events: read("Read your audit log"),
|
|
739
705
|
get_buyer_account: read("Read your buyer account"),
|
|
740
|
-
article_53_attestation: read("Get a signed compliance attestation"),
|
|
741
706
|
get_compliance_dossier: read("Get your compliance dossier"),
|
|
742
707
|
list_publisher_content: read("List your published articles"),
|
|
743
708
|
// Upserts the publisher's own articles; an upsert can overwrite.
|
|
@@ -770,14 +735,14 @@ export const ALL_TOOLS = buildTools({
|
|
|
770
735
|
// at initialize — it was empty until 2026-08-26 while the pitch lived only in
|
|
771
736
|
// registry metadata agents never see at runtime. Exported so the hosted
|
|
772
737
|
// gateway (opedd-mcp-gateway) serves the identical text.
|
|
773
|
-
export const SERVER_INSTRUCTIONS = "Opedd is content licensing for the AI era, between expert publishers and AI products: discover,
|
|
738
|
+
export const SERVER_INSTRUCTIONS = "Opedd is content licensing for the AI era, between expert publishers and AI products: discover, license, verify and " +
|
|
774
739
|
"retrieve rights-cleared expert content — a verifiable licence for every use, a public record on " +
|
|
775
|
-
"Tempo, and compliance artifacts (audit ledger
|
|
776
|
-
"unlicensed scraping for RAG, AI search
|
|
740
|
+
"Tempo, and compliance artifacts (audit ledger and dossiers). A licensed alternative to " +
|
|
741
|
+
"unlicensed scraping for RAG, AI search and training corpora.\n\n" +
|
|
777
742
|
`No credentials needed: ${NO_AUTH_TOOLS}.\n` +
|
|
778
|
-
"Buyer tools (
|
|
743
|
+
"Buyer tools (licence orders, account, audit/compliance): free buyer signup at https://opedd.com/buyer/signup " +
|
|
779
744
|
"(~2 min; an API key is issued instantly). Publisher tools (content push): free publisher signup at " +
|
|
780
|
-
"https://opedd.com, key under Settings →
|
|
745
|
+
"https://opedd.com, key under Settings → For developers.\n" +
|
|
781
746
|
"Supply credentials as env vars (local/stdio) or an Authorization: Bearer header (hosted gateway, " +
|
|
782
747
|
"https://mcp.opedd.com/mcp).\n" +
|
|
783
748
|
"EU CDSM Art. 4(3) / TDM-reservation queries: rsl_get. Compliance evidence: get_compliance_dossier. " +
|
|
@@ -1119,29 +1084,6 @@ export async function dispatchTool(name, args, creds = ENV_CREDS) {
|
|
|
1119
1084
|
});
|
|
1120
1085
|
return ok(data);
|
|
1121
1086
|
}
|
|
1122
|
-
// ── article_53_attestation (Phase 12 Wave 1 W1.4) ──────────────────────
|
|
1123
|
-
case "article_53_attestation": {
|
|
1124
|
-
if (!auditCred(creds)) {
|
|
1125
|
-
return credErr("Buyer credentials are required for this tool", "OPEDD_BUYER_TOKEN (audit-scoped key) or OPEDD_BUYER_JWT", HOW_AUDIT_CRED);
|
|
1126
|
-
}
|
|
1127
|
-
const { license_id, content_id, window_start, window_end } = args;
|
|
1128
|
-
if (!license_id)
|
|
1129
|
-
return err("license_id is required");
|
|
1130
|
-
const params = new URLSearchParams({ license_id });
|
|
1131
|
-
if (content_id)
|
|
1132
|
-
params.set("content_id", content_id);
|
|
1133
|
-
if (window_start)
|
|
1134
|
-
params.set("window_start", window_start);
|
|
1135
|
-
if (window_end)
|
|
1136
|
-
params.set("window_end", window_end);
|
|
1137
|
-
// Function name is DASH-separated end to end: the api.opedd.com proxy
|
|
1138
|
-
// rewrites /:path* verbatim into /functions/v1/:path*, so the prior
|
|
1139
|
-
// slashed "/eu-ai-act/article-53-attestation" resolved to a
|
|
1140
|
-
// nonexistent function named "eu-ai-act" and 404'd — this tool had
|
|
1141
|
-
// NEVER worked in production until the 2026-07-10 fix (live-probed).
|
|
1142
|
-
const data = await opeddFetch(creds, `/eu-ai-act-article-53-attestation?${params.toString()}`, { headers: { Authorization: `Bearer ${auditCred(creds)}` } });
|
|
1143
|
-
return ok(data);
|
|
1144
|
-
}
|
|
1145
1087
|
// ── get_compliance_dossier (Phase 11 M4) ───────────────────────────────
|
|
1146
1088
|
case "get_compliance_dossier": {
|
|
1147
1089
|
if (!auditCred(creds)) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opedd-mcp",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.16",
|
|
4
4
|
"description": "Content licensing for the AI era. Licensed, rights-cleared content for AI agents, with a verifiable license key for every article. The MCP alternative to unlicensed scraping for RAG and AI search.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|