opedd-mcp 0.12.6 → 0.12.8
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 +18 -17
- package/dist/index.d.ts +1 -1
- package/dist/index.js +66 -18
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -21,9 +21,9 @@
|
|
|
21
21
|
<a href="https://opedd.com/for-ai-agents?utm_source=github&utm_medium=readme&utm_campaign=mcp"><img src="https://img.shields.io/badge/Docs-opedd.com-111" alt="Docs"></a>
|
|
22
22
|
</p>
|
|
23
23
|
|
|
24
|
-
Lets AI assistants (Claude Desktop, Cursor, Windsurf, or any MCP-compatible host) discover, purchase, and verify content licenses autonomously — mid-conversation, without opening a browser. Every license is
|
|
24
|
+
Lets AI assistants (Claude Desktop, Cursor, Windsurf, or any MCP-compatible host) discover, purchase, and verify content licenses autonomously — mid-conversation, without opening a browser. Every license is recorded in a public registry on Tempo, with cryptographic proof.
|
|
25
25
|
|
|
26
|
-
**Unlike generic search APIs**, Opedd returns content with a verifiable license key —
|
|
26
|
+
**Unlike generic search APIs**, Opedd returns content with a verifiable license key — with the rights cleared and a record you can show your legal team.
|
|
27
27
|
|
|
28
28
|
## Quick start
|
|
29
29
|
|
|
@@ -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 21 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 21 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
|
|
|
@@ -92,9 +92,10 @@ Every tool carries a `title` and MCP annotations (`readOnlyHint`, `destructiveHi
|
|
|
92
92
|
|------|-------------|
|
|
93
93
|
| `search_content` | **Free discovery.** Full-text search across everything licensable (v0.8.0) — ranked matches with publisher, prices, word count and a description snippet; quotes for phrases, `-word` to exclude. Returns **no article text** — use `search_passages` to actually read |
|
|
94
94
|
| `search_passages` | **Paid per answer, or included in a monthly subscription.** Ask a question, get licensed passages that answer it, with citations. Per-question licences: charged once per publisher per question at that publisher's own price, capped at 300 words or 25% of the article, counted cumulatively. Monthly AI answers subscriptions (v0.12.0): included, not capped, from the subscription's start. Narrow with `publishers`, `published_after`, `published_before`, `max_results` (1–25). Needs a buyer key with the `search` scope. Re-asking within 24h is free |
|
|
95
|
-
| `lookup_content` | Look up an article by URL — returns title, publisher, pricing |
|
|
95
|
+
| `lookup_content` | Look up an article by URL — returns title, publisher, pricing, or that it is not on Opedd yet |
|
|
96
|
+
| `request_publication` | Ask to be told when a publication Opedd does not carry yet becomes available (url + email; no key) |
|
|
96
97
|
| `purchase_license` | Buy a Human republication licence for one article via Stripe — returns OP-XXXX-XXXX key. Requires `terms_accepted: true` (genuine buyer assent to opedd.com/terms; recorded with the licence) |
|
|
97
|
-
| `verify_license` | Verify a license key — returns validity, article, publisher,
|
|
98
|
+
| `verify_license` | Verify a license key — returns validity, article, publisher, public-record proof |
|
|
98
99
|
| `browse_registry` | Browse the public Opedd registry — lists issued LICENSES (use `publisher_directory` to browse publishers themselves) |
|
|
99
100
|
| `publisher_directory` | Browse the public Opedd publisher catalog — paginated publishers with article counts + pricing + sample articles (primary buyer-discovery surface for AI labs) |
|
|
100
101
|
| `place_licence_order` | Place a licence order for one or more publishers: AI answers (`monthly` full text, or `metered` pay-per-request snippets ≤300 words / 25%), Full catalogue (`archive`, `one_time`: everything published up to the order date, kept permanently, no AI training), AI training (`one_time`, back catalogue), client display (`monthly` × end clients). Optional `include_archive: true` on a monthly AI answers order adds each publisher's Full catalogue for complete access. Each publisher is its own Schedule at its own price; returns the order, lines, `unavailable` publishers and `hosted_invoice_url`. Needs `OPEDD_BUYER_JWT` and `terms_accepted: true` |
|
|
@@ -114,15 +115,15 @@ Every tool carries a `title` and MCP annotations (`readOnlyHint`, `destructiveHi
|
|
|
114
115
|
| `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
116
|
| `stream_feed_ndjson` | Bulk-export up to 1000 articles per call via NDJSON wire format. Same content contract and credentials as `list_feed` |
|
|
116
117
|
|
|
117
|
-
**Requires `OPEDD_BUYER_JWT` (Supabase JWT) — buyer account + audit + compliance +
|
|
118
|
+
**Requires `OPEDD_BUYER_JWT` (Supabase JWT) — buyer account + audit + compliance + attestation surfaces**
|
|
118
119
|
|
|
119
120
|
| Tool | Description |
|
|
120
121
|
|------|-------------|
|
|
121
122
|
| `get_buyer_account` | Fetch buyer profile + masked API key list — buyer-dashboard mental model |
|
|
122
123
|
| `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
|
-
| `get_audit_events` | Per-event audit ledger with
|
|
124
|
+
| `get_audit_events` | Per-event audit ledger with public-record (Tempo) inclusion proofs inline (Phase 9.x + 10 M5) |
|
|
124
125
|
| `get_compliance_dossier` | Procurement-defense compliance dossier mapping retrievals to license terms (Phase 11 M4) |
|
|
125
|
-
| `article_53_attestation` | Signed
|
|
126
|
+
| `article_53_attestation` | Signed compliance attestation (JWT) for a license — the artifact a buyer hands to legal/procurement (Phase 12 W1.4) |
|
|
126
127
|
|
|
127
128
|
**Requires `OPEDD_PUB_BEARER` (opedd_sk_*; legacy opedd_pub_* still works) — publisher-side**
|
|
128
129
|
|
|
@@ -131,13 +132,13 @@ Every tool carries a `title` and MCP annotations (`readOnlyHint`, `destructiveHi
|
|
|
131
132
|
| `list_publisher_content` | List your own articles with pricing and stats |
|
|
132
133
|
| `push_content` | Push your articles to Opedd so AI buyers can license them — 1–100 per call (`title`/`url`/`html_body` required, everything else optional). Onboard your back-catalogue or new posts with no code, straight from your AI assistant. |
|
|
133
134
|
|
|
134
|
-
###
|
|
135
|
+
### Compliance artifacts (publisher-side vs buyer-side — never conflated)
|
|
135
136
|
|
|
136
137
|
Per Opedd's platform invariants (W1.6 amendment):
|
|
137
138
|
|
|
138
139
|
- **`rsl_get(publisher_id, jsonld=true)`** → publisher-side **CDSM Article 4(3)** opt-out declaration (signed JSON-LD receipt over the reservation state).
|
|
139
|
-
- **`article_53_attestation(license_id)`** → buyer-side **
|
|
140
|
-
- **`get_compliance_dossier(from, to)`** → comprehensive procurement-defense dossier covering BOTH
|
|
140
|
+
- **`article_53_attestation(license_id)`** → buyer-side **signed compliance attestation** (HS256 JWT scoped to one license).
|
|
141
|
+
- **`get_compliance_dossier(from, to)`** → comprehensive procurement-defense dossier covering BOTH sides (publisher CDSM reservation honored + buyer attestation evidence chain).
|
|
141
142
|
|
|
142
143
|
These serve different audit-defensibility modes and never share wire format. Tool descriptions cite the W1.6 invariant inline.
|
|
143
144
|
|
|
@@ -242,7 +243,7 @@ Once configured, you can ask your AI assistant:
|
|
|
242
243
|
|
|
243
244
|
> "Get me a CDSM Article 4(3) signed receipt for that publisher's reservation state — set `jsonld: true`." — uses `rsl_get` with content negotiation
|
|
244
245
|
|
|
245
|
-
> "Generate
|
|
246
|
+
> "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`)
|
|
246
247
|
|
|
247
248
|
> "This publisher just signed up: `https://noahpinion.substack.com`. Which onboarding workflow should we use?" — uses `detect_platform`
|
|
248
249
|
|
|
@@ -270,12 +271,12 @@ npm run build # compiles to dist/
|
|
|
270
271
|
|
|
271
272
|
| | Opedd | Generic search APIs |
|
|
272
273
|
|---|---|---|
|
|
273
|
-
| **What you get** | Licensed content + license key +
|
|
274
|
+
| **What you get** | Licensed content + license key + public-record proof — all in one API call | Scraped web content, no rights |
|
|
274
275
|
| **Content delivery** | Full article text via API (JSON) — bulk on flat-fee licenses, per-call (metered) on filtered licenses; real-time feed via webhooks | Scraped snippets or full-page dumps |
|
|
275
276
|
| **Content quality** | Curated publisher content (niche B2B newsletters, expert analysis) | Whatever's on the open web |
|
|
276
277
|
| **Rights** | Verifiable license key per article, publisher-authorized | No rights clearance |
|
|
277
|
-
| **Proof** |
|
|
278
|
-
| **
|
|
278
|
+
| **Proof** | Public record (Tempo) — independently verifiable | None |
|
|
279
|
+
| **Compliance** | Signed attestation + full provenance chain | No provenance |
|
|
279
280
|
| **Pricing** | Publisher sets their own price per article | Platform decides |
|
|
280
281
|
| **Delivery modes** | Per-article API, bulk feed (JSON firehose), buyer webhooks (push) | Query-response only |
|
|
281
282
|
| **Protocol** | REST + MCP native | REST only |
|
|
@@ -286,7 +287,7 @@ Opedd is the **licensed content delivery layer** for AI — not just a licensing
|
|
|
286
287
|
|
|
287
288
|
- [Opedd for AI Agents](https://opedd.com/for-ai-agents?utm_source=github&utm_medium=readme&utm_campaign=mcp) — full documentation, code examples, endpoint reference
|
|
288
289
|
- [API Docs](https://docs.opedd.com) — OpenAPI spec with agent endpoints
|
|
289
|
-
- [
|
|
290
|
+
- [Verify a licence](https://opedd.com/verify?utm_source=github&utm_medium=readme&utm_campaign=mcp) — check any licence key in the public record
|
|
290
291
|
|
|
291
292
|
## License
|
|
292
293
|
|
package/dist/index.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ export interface Credentials {
|
|
|
12
12
|
buyerToken?: string;
|
|
13
13
|
/** enterprise access key (ent_*) — /enterprise-license GET feed */
|
|
14
14
|
accessKey?: string;
|
|
15
|
-
/** Supabase JWT — buyer-audit + compliance +
|
|
15
|
+
/** Supabase JWT — buyer-audit + compliance + attestation surfaces */
|
|
16
16
|
buyerJwt?: string;
|
|
17
17
|
}
|
|
18
18
|
export declare function envCredentials(): Credentials;
|
package/dist/index.js
CHANGED
|
@@ -68,7 +68,9 @@ async function opeddFetch(creds, path, options = {}) {
|
|
|
68
68
|
catch {
|
|
69
69
|
// non-JSON error body — keep the HTTP-status default
|
|
70
70
|
}
|
|
71
|
-
|
|
71
|
+
// The status rides on the error so a caller can treat one status as an
|
|
72
|
+
// answer (lookup_content: 404 = not on Opedd yet) without parsing text.
|
|
73
|
+
throw Object.assign(new Error(msg), { status: res.status });
|
|
72
74
|
}
|
|
73
75
|
return await res.json();
|
|
74
76
|
}
|
|
@@ -134,7 +136,7 @@ function err(msg) {
|
|
|
134
136
|
// Only the refusal text changed: what's missing, how to supply it on BOTH
|
|
135
137
|
// channels (env var locally, Authorization header on the hosted gateway),
|
|
136
138
|
// where credentials come from, and which tools need none.
|
|
137
|
-
const NO_AUTH_TOOLS = "lookup_content, publisher_directory, verify_license, browse_registry, rsl_get, detect_platform";
|
|
139
|
+
const NO_AUTH_TOOLS = "lookup_content, publisher_directory, verify_license, browse_registry, rsl_get, detect_platform, request_publication";
|
|
138
140
|
function credErr(missing, envVar, howToGet) {
|
|
139
141
|
return err(`${missing} — none was provided. ` +
|
|
140
142
|
`Supply it as the ${envVar} env var (local/stdio install) or as an "Authorization: Bearer <value>" header (hosted gateway, https://mcp.opedd.com/mcp). ` +
|
|
@@ -182,7 +184,7 @@ function buildTools(has) {
|
|
|
182
184
|
const TOOLS = [
|
|
183
185
|
{
|
|
184
186
|
name: "lookup_content",
|
|
185
|
-
description: "Looks up an article on Opedd by its web address. Returns the title, publication, available licence types and prices, or that
|
|
187
|
+
description: "Looks up an article on Opedd by its web address. Returns the title, publication, available licence types and prices, or that it is not on Opedd yet (then request_publication records the request).",
|
|
186
188
|
inputSchema: {
|
|
187
189
|
type: "object",
|
|
188
190
|
required: ["url"],
|
|
@@ -194,6 +196,21 @@ function buildTools(has) {
|
|
|
194
196
|
},
|
|
195
197
|
},
|
|
196
198
|
},
|
|
199
|
+
{
|
|
200
|
+
name: "request_publication",
|
|
201
|
+
description: "Asks Opedd to tell you when a publication it does not carry yet becomes available to license. Use it after lookup_content says an article 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.",
|
|
202
|
+
inputSchema: {
|
|
203
|
+
type: "object",
|
|
204
|
+
required: ["url", "email"],
|
|
205
|
+
properties: {
|
|
206
|
+
url: { type: "string", description: "The web address of the publication or of one of its articles." },
|
|
207
|
+
email: { type: "string", description: "Where Opedd should write when the publication is available (the user's email, with their consent)." },
|
|
208
|
+
name: { type: "string", description: "Optional: the requester's name." },
|
|
209
|
+
organization: { type: "string", description: "Optional: the requester's company or fund." },
|
|
210
|
+
note: { type: "string", description: "Optional: what the content is needed for (max 1000 characters)." },
|
|
211
|
+
},
|
|
212
|
+
},
|
|
213
|
+
},
|
|
197
214
|
{
|
|
198
215
|
name: "search_content",
|
|
199
216
|
description: "Full-text search of the articles licensable on Opedd. Returns matching articles with the publication, prices, word count and a short description; never article text. Supports quoted phrases and -word to exclude a word. Free; no key needed.",
|
|
@@ -263,7 +280,7 @@ function buildTools(has) {
|
|
|
263
280
|
},
|
|
264
281
|
{
|
|
265
282
|
name: "verify_license",
|
|
266
|
-
description: "Checks an Opedd licence key. Returns the licence details (article title, publication, licence type, issue date, amount paid, buyer and
|
|
283
|
+
description: "Checks an Opedd licence key. Returns the licence details (article title, publication, licence type, issue date, amount paid, buyer and public-record proof status), or that the key was not found.",
|
|
267
284
|
inputSchema: {
|
|
268
285
|
type: "object",
|
|
269
286
|
required: ["license_key"],
|
|
@@ -362,7 +379,7 @@ function buildTools(has) {
|
|
|
362
379
|
"verify the reservation was the claimed value at the claimed time. Default `jsonld: false` returns " +
|
|
363
380
|
"the raw RSL Standard JSON manifest. " +
|
|
364
381
|
"Per INVARIANTS.md W1.6: this is the PUBLISHER-side CDSM Article 4(3) declaration surface. It is NOT " +
|
|
365
|
-
"
|
|
382
|
+
"a signed compliance attestation (which is buyer-side, JWT-auth, via article_53_attestation tool).",
|
|
366
383
|
inputSchema: {
|
|
367
384
|
type: "object",
|
|
368
385
|
required: ["publisher_id"],
|
|
@@ -560,7 +577,7 @@ function buildTools(has) {
|
|
|
560
577
|
if (has.buyerJwt || has.buyerToken) {
|
|
561
578
|
TOOLS.push({
|
|
562
579
|
name: "list_licence_orders",
|
|
563
|
-
description: "Lists the account's licence orders, newest first, each with its lines (publication, licence, unit, price, quantity, status). With order_id, returns one order, each line with its Schedule text and the SHA-256 fingerprint recorded
|
|
580
|
+
description: "Lists the account's licence orders, newest first, each with its lines (publication, licence, unit, price, quantity, status). With order_id, returns one order, each line with its Schedule text and the SHA-256 fingerprint recorded in the public registry on Tempo when the line was issued. Read-only. Requires a buyer API key with the 'audit' scope, a buyer session, or the Opedd connector sign-in.",
|
|
564
581
|
inputSchema: {
|
|
565
582
|
type: "object",
|
|
566
583
|
properties: {
|
|
@@ -572,7 +589,7 @@ function buildTools(has) {
|
|
|
572
589
|
});
|
|
573
590
|
TOOLS.push({
|
|
574
591
|
name: "get_audit_events",
|
|
575
|
-
description: "Returns the account's audit records, one per licensed access, each with its licence terms and
|
|
592
|
+
description: "Returns the account's audit records, one per licensed access, each with its licence terms and public-record attestation (Merkle root and inclusion proof once confirmed). Filter: event_type ('content_access', 'bulk_content_access' or 'compliance_report_generated'). At most 30 days per call. Read-only. Requires a buyer API key with the 'audit' scope, a buyer session, or the Opedd connector sign-in.",
|
|
576
593
|
inputSchema: {
|
|
577
594
|
type: "object",
|
|
578
595
|
properties: {
|
|
@@ -617,14 +634,14 @@ function buildTools(has) {
|
|
|
617
634
|
});
|
|
618
635
|
TOOLS.push({
|
|
619
636
|
name: "article_53_attestation",
|
|
620
|
-
description: "Issue a signed
|
|
637
|
+
description: "Issue a signed compliance attestation (a JWT) for a specific license via " +
|
|
621
638
|
"GET /eu-ai-act/article-53-attestation (Phase 12 Wave 1 W1.4). " +
|
|
622
639
|
"Returns a freshly-signed HS256 JWT regulators can verify offline against the canonical signing key. " +
|
|
623
640
|
"Embeds: license context, usage-count over the attestation window, the most-recent Tempo Merkle root, " +
|
|
624
641
|
"and canonical claims (iss/sub/iat/exp/jti/aud). " +
|
|
625
|
-
"**The artifact
|
|
626
|
-
"Per INVARIANTS.md W1.6: this
|
|
627
|
-
"
|
|
642
|
+
"**The artifact a buyer hands to legal/procurement as evidence of where its content came from.** " +
|
|
643
|
+
"Per INVARIANTS.md W1.6: this is the buyer-side attestation ONLY (how a licence was used). " +
|
|
644
|
+
"It does NOT discharge a publisher's CDSM Article 4(3) reservation obligation — " +
|
|
628
645
|
"that lives on the rsl_get tool (jsonld=true variant). Never conflate. " +
|
|
629
646
|
"Optional `content_id` scopes the attestation to one article; default is license-wide. " +
|
|
630
647
|
"Window cap: 365 days. Auth: an audit-scoped buyer API key (OPEDD_BUYER_TOKEN) or OPEDD_BUYER_JWT.",
|
|
@@ -653,7 +670,7 @@ function buildTools(has) {
|
|
|
653
670
|
});
|
|
654
671
|
TOOLS.push({
|
|
655
672
|
name: "get_compliance_dossier",
|
|
656
|
-
description: "Returns the account's compliance dossier for a period: one row per licensed article, with article metadata, licence terms,
|
|
673
|
+
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 (the signed attestation, 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.",
|
|
657
674
|
inputSchema: {
|
|
658
675
|
type: "object",
|
|
659
676
|
required: ["from", "to"],
|
|
@@ -760,6 +777,8 @@ function buildTools(has) {
|
|
|
760
777
|
const read = (title) => ({ title, readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false });
|
|
761
778
|
export const TOOL_ANNOTATIONS = {
|
|
762
779
|
lookup_content: read("Look up an article's licence and price"),
|
|
780
|
+
// Writes one request row (a repeat for the same email writes nothing): not read-only, idempotent.
|
|
781
|
+
request_publication: { title: "Ask to be told when a publication is available", readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
763
782
|
search_content: read("Find who covers a topic (free, no text)"),
|
|
764
783
|
purchase_license: { title: "Buy an article licence", readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false },
|
|
765
784
|
verify_license: read("Verify a licence key"),
|
|
@@ -776,7 +795,7 @@ export const TOOL_ANNOTATIONS = {
|
|
|
776
795
|
list_licence_orders: read("List your licence orders"),
|
|
777
796
|
get_audit_events: read("Read your audit log"),
|
|
778
797
|
get_buyer_account: read("Read your buyer account"),
|
|
779
|
-
article_53_attestation: read("Get
|
|
798
|
+
article_53_attestation: read("Get a signed compliance attestation"),
|
|
780
799
|
get_compliance_dossier: read("Get your compliance dossier"),
|
|
781
800
|
list_publisher_content: read("List your published articles"),
|
|
782
801
|
// Upserts the publisher's own articles; an upsert can overwrite.
|
|
@@ -809,9 +828,9 @@ export const ALL_TOOLS = buildTools({
|
|
|
809
828
|
// at initialize — it was empty until 2026-08-26 while the pitch lived only in
|
|
810
829
|
// registry metadata agents never see at runtime. Exported so the hosted
|
|
811
830
|
// gateway (opedd-mcp-gateway) serves the identical text.
|
|
812
|
-
export const SERVER_INSTRUCTIONS = "Opedd is
|
|
813
|
-
"retrieve rights-cleared expert content — one verifiable license key per article,
|
|
814
|
-
"
|
|
831
|
+
export const SERVER_INSTRUCTIONS = "Opedd is content licensing for the AI era, between expert publishers and AI products: discover, purchase, verify and " +
|
|
832
|
+
"retrieve rights-cleared expert content — one verifiable license key per article, a public record on " +
|
|
833
|
+
"Tempo, and compliance artifacts (audit ledger, dossiers and signed attestations). Use it instead of " +
|
|
815
834
|
"unlicensed scraping for RAG, AI search, and training corpora.\n\n" +
|
|
816
835
|
`No credentials needed: ${NO_AUTH_TOOLS}.\n` +
|
|
817
836
|
"Buyer tools (purchase, account, audit/compliance): free buyer signup at https://opedd.com/buyer/signup " +
|
|
@@ -850,8 +869,37 @@ export async function dispatchTool(name, args, creds = ENV_CREDS) {
|
|
|
850
869
|
const { url } = args;
|
|
851
870
|
if (!url)
|
|
852
871
|
return err("url is required");
|
|
853
|
-
|
|
854
|
-
|
|
872
|
+
try {
|
|
873
|
+
const data = await opeddFetch(creds, `/lookup-article?url=${encodeURIComponent(url)}`);
|
|
874
|
+
return ok(data);
|
|
875
|
+
}
|
|
876
|
+
catch (e) {
|
|
877
|
+
// A miss is an answer, not a failure (2026-10-22). Directories score
|
|
878
|
+
// servers on error rates, and the honest reply is "not on Opedd yet"
|
|
879
|
+
// with a way to ask for it, never "coming soon".
|
|
880
|
+
if (e.status === 404) {
|
|
881
|
+
return ok({
|
|
882
|
+
on_opedd: false,
|
|
883
|
+
url,
|
|
884
|
+
message: "This article is not on Opedd yet. If you want to license this publication, call request_publication " +
|
|
885
|
+
"with this url and an email, and Opedd will write when it becomes available.",
|
|
886
|
+
});
|
|
887
|
+
}
|
|
888
|
+
throw e;
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
// ── request_publication ────────────────────────────────────────────────
|
|
892
|
+
case "request_publication": {
|
|
893
|
+
const { url, email, name, organization, note } = args;
|
|
894
|
+
if (!url)
|
|
895
|
+
return err("url is required");
|
|
896
|
+
if (!email)
|
|
897
|
+
return err("email is required: Opedd writes to it when the publication is available");
|
|
898
|
+
const envelope = (await opeddFetch(creds, "/publication-request", {
|
|
899
|
+
method: "POST",
|
|
900
|
+
body: JSON.stringify({ url, email, name, organization, note }),
|
|
901
|
+
}));
|
|
902
|
+
return ok(envelope.data ?? envelope);
|
|
855
903
|
}
|
|
856
904
|
// ── search_content ─────────────────────────────────────────────────────
|
|
857
905
|
case "search_content": {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opedd-mcp",
|
|
3
|
-
"version": "0.12.
|
|
4
|
-
"description": "Licensed, rights-cleared content for AI agents
|
|
3
|
+
"version": "0.12.8",
|
|
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",
|
|
7
7
|
"mcpName": "com.opedd/opedd-mcp",
|