opedd-mcp 0.5.1 → 0.6.1

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Opedd Ltd
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -8,7 +8,7 @@ Lets AI assistants (Claude Desktop, Cursor, Windsurf, or any MCP-compatible host
8
8
 
9
9
  ## What it does
10
10
 
11
- Exposes up to 16 tools to any AI assistant (some are conditional on env vars):
11
+ Exposes up to 17 tools to any AI assistant (some are conditional on env vars):
12
12
 
13
13
  **Always available — discovery + per-article purchase + onboarding + rights signaling**
14
14
 
@@ -50,6 +50,7 @@ Exposes up to 16 tools to any AI assistant (some are conditional on env vars):
50
50
  | Tool | Description |
51
51
  |------|-------------|
52
52
  | `list_publisher_content` | List your own articles with pricing and stats |
53
+ | `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. |
53
54
 
54
55
  ### Regulatory framing (CDSM Article 4 vs EU AI Act Article 53 — never conflated)
55
56
 
@@ -83,8 +84,8 @@ Set environment variables to pre-configure the server:
83
84
  | `OPEDD_PAYMENT_METHOD_ID` | Recommended | Stripe `pm_...` ID — used for autonomous per-article purchasing |
84
85
  | `OPEDD_BUYER_TOKEN` | Optional | Buyer API token (`opedd_buyer_live_*` canonical; `opedd_buyer_test_*` for sandbox) — enables `get_content` |
85
86
  | `OPEDD_ACCESS_KEY` | Optional | Enterprise access key (`ent_*`) — enables `list_feed` + `stream_feed_ndjson` |
86
- | `OPEDD_BUYER_JWT` | Optional | Supabase session JWT from the buyer portal — enables `get_audit_events` + `get_compliance_dossier` |
87
- | `OPEDD_PUB_BEARER` | Optional | Canonical Publisher API Bearer key (`opedd_pub_<env>_<32-hex>`; issued via `POST /publishers-api-keys action=create_api_key`) — enables `list_publisher_content`. **v0.4.0 canonical.** |
87
+ | `OPEDD_BUYER_JWT` | Optional | Supabase session JWT from the buyer portal — enables `get_buyer_account` + `get_audit_events` + `get_compliance_dossier` + `article_53_attestation` |
88
+ | `OPEDD_PUB_BEARER` | Optional | Canonical Publisher API Bearer key (`opedd_pub_<env>_<32-hex>`; issued via `POST /publishers-api-keys action=create_api_key`) — enables `list_publisher_content` + `push_content`. **v0.4.0 canonical.** |
88
89
  | `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`. |
89
90
  | `OPEDD_API_URL` | Optional | Override the API base URL (default: Opedd production) |
90
91
  | `OPEDD_MCP_TELEMETRY` | Optional | Set to `0` to disable anonymous usage telemetry (see below) |
package/dist/index.js CHANGED
@@ -4,6 +4,7 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
4
4
  import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
5
5
  import { pathToFileURL } from "node:url";
6
6
  import { initTelemetry, captureToolCall, shutdownTelemetry } from "./telemetry.js";
7
+ import { SERVER_VERSION } from "./version.js";
7
8
  // ─── Configuration ────────────────────────────────────────────────────────────
8
9
  const API_BASE = process.env.OPEDD_API_URL ??
9
10
  "https://api.opedd.com";
@@ -565,9 +566,49 @@ if (PUB_BEARER || API_KEY) {
565
566
  },
566
567
  },
567
568
  });
569
+ // Supply-side push: onboard a back-catalogue or send new posts directly from
570
+ // the AI assistant — the native companion to the /publishers-content API.
571
+ TOOLS.push({
572
+ name: "push_content",
573
+ description: "Push your published articles to Opedd so they can be licensed to AI buyers (requires OPEDD_PUB_BEARER — your opedd_pub_ publisher key). " +
574
+ "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). " +
575
+ "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.",
576
+ inputSchema: {
577
+ type: "object",
578
+ required: ["articles"],
579
+ properties: {
580
+ articles: {
581
+ type: "array",
582
+ minItems: 1,
583
+ maxItems: 100,
584
+ description: "1–100 articles to push in this call.",
585
+ items: {
586
+ type: "object",
587
+ required: ["title", "url", "html_body"],
588
+ properties: {
589
+ title: { type: "string", description: "Article title (required, ≤500 chars)." },
590
+ url: { type: "string", description: "The article's canonical web address (required)." },
591
+ html_body: { type: "string", description: "Full article content, HTML or plain text (required, ≤200,000 chars)." },
592
+ published_at: { type: "string", description: "ISO-8601 datetime (e.g. 2026-01-15T09:30:00Z). Defaults to now if omitted." },
593
+ description: { type: "string", description: "Short summary (≤500 chars)." },
594
+ author: { type: "string", description: "Author name (≤200 chars)." },
595
+ language: { type: "string", description: "Language code, e.g. \"en\"." },
596
+ tags: { type: "array", items: { type: "string" }, description: "Up to 20 tags." },
597
+ image_urls: { type: "array", items: { type: "string" }, description: "Up to 10 body-image URLs." },
598
+ thumbnail_url: { type: "string", description: "https cover-image URL for the catalog." },
599
+ canonical_url: { type: "string", description: "Canonical URL if different from url." },
600
+ category: { type: "string", description: "Content category." },
601
+ is_paid: { type: "boolean", description: "Whether the article is behind a paywall." },
602
+ audience: { type: "string", enum: ["everyone", "only_free", "only_paid"], description: "Intended audience." },
603
+ },
604
+ },
605
+ },
606
+ },
607
+ },
608
+ });
568
609
  }
569
610
  // ─── MCP Server ───────────────────────────────────────────────────────────────
570
- const server = new Server({ name: "opedd-mcp", version: "0.3.0" }, { capabilities: { tools: {} } });
611
+ const server = new Server({ name: "opedd-mcp", version: SERVER_VERSION }, { capabilities: { tools: {} } });
571
612
  server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOLS }));
572
613
  server.setRequestHandler(CallToolRequestSchema, async (request) => {
573
614
  // Anonymous usage telemetry — captures only the tool name, duration, and
@@ -809,7 +850,12 @@ export async function dispatchTool(name, args) {
809
850
  params.set("window_start", window_start);
810
851
  if (window_end)
811
852
  params.set("window_end", window_end);
812
- const data = await opeddFetch(`/eu-ai-act/article-53-attestation?${params.toString()}`, { headers: { Authorization: `Bearer ${BUYER_JWT}` } });
853
+ // Function name is DASH-separated end to end: the api.opedd.com proxy
854
+ // rewrites /:path* verbatim into /functions/v1/:path*, so the prior
855
+ // slashed "/eu-ai-act/article-53-attestation" resolved to a
856
+ // nonexistent function named "eu-ai-act" and 404'd — this tool had
857
+ // NEVER worked in production until the 2026-07-10 fix (live-probed).
858
+ const data = await opeddFetch(`/eu-ai-act-article-53-attestation?${params.toString()}`, { headers: { Authorization: `Bearer ${BUYER_JWT}` } });
813
859
  return ok(data);
814
860
  }
815
861
  // ── get_compliance_dossier (Phase 11 M4) ───────────────────────────────
@@ -848,6 +894,26 @@ export async function dispatchTool(name, args) {
848
894
  const data = await opeddFetch(`/api?${params.toString()}`);
849
895
  return ok(data);
850
896
  }
897
+ // ── push_content ───────────────────────────────────────────────────────
898
+ case "push_content": {
899
+ if (!PUB_BEARER && !API_KEY) {
900
+ return err("OPEDD_PUB_BEARER env var is required for this tool (your opedd_pub_ publisher key).");
901
+ }
902
+ const { articles } = args;
903
+ if (!Array.isArray(articles) || articles.length === 0) {
904
+ return err("`articles` must be a non-empty array (1–100 items).");
905
+ }
906
+ if (articles.length > 100) {
907
+ return err(`Too many articles in one call (${articles.length}). Send at most 100 per call and batch the rest.`);
908
+ }
909
+ // Backend /publishers-content enforces the full strict schema + returns
910
+ // clear per-article errors; we pass through so the assistant can relay them.
911
+ const data = await opeddFetch("/publishers-content", {
912
+ method: "POST",
913
+ body: JSON.stringify({ articles }),
914
+ });
915
+ return ok(data);
916
+ }
851
917
  default:
852
918
  return err(`Unknown tool: ${name}`);
853
919
  }
package/dist/telemetry.js CHANGED
@@ -14,11 +14,13 @@
14
14
  // so telemetry can never affect a tool call or the server.
15
15
  import { PostHog } from "posthog-node";
16
16
  import { randomUUID } from "node:crypto";
17
+ // Version sourced from package.json (src/version.ts) — the previous hardcode
18
+ // drifted within one release (reported 0.5.1 while 0.6.0 shipped).
19
+ import { SERVER_VERSION } from "./version.js";
17
20
  // Public, write-only PostHog project key (EU cloud, project 218295). Safe to
18
21
  // embed — it can only send events, not read data.
19
22
  const POSTHOG_KEY = "phc_yfyXBNsf5nZncZBiZNQBBs5RWC3mtWNWpUJv5EfzfBir";
20
23
  const POSTHOG_HOST = "https://eu.i.posthog.com";
21
- const SERVER_VERSION = "0.5.1";
22
24
  /** Whether telemetry is allowed (respects OPEDD_MCP_TELEMETRY + DO_NOT_TRACK). Pure — exported for tests. */
23
25
  export function isTelemetryEnabled() {
24
26
  const t = process.env.OPEDD_MCP_TELEMETRY?.toLowerCase();
@@ -0,0 +1,6 @@
1
+ // Single source of truth for the server version: package.json. The prior
2
+ // pattern (hardcoded string in telemetry.ts) drifted within one release
3
+ // (0.5.1 reported while 0.6.0 shipped) — never hardcode the version again.
4
+ import { createRequire } from "node:module";
5
+ const require = createRequire(import.meta.url);
6
+ export const SERVER_VERSION = require("../package.json").version;
package/package.json CHANGED
@@ -1,9 +1,18 @@
1
1
  {
2
2
  "name": "opedd-mcp",
3
- "version": "0.5.1",
4
- "description": "MCP server for Opedd — discover, purchase, verify, and audit content licenses from AI assistants. Covers Phase 11 buyer-side surfaces + Phase 12 Wave 1 + 3 regulatory surfaces (CDSM Article 4(3) RSL + EU AI Act Article 53 attestation + platform onboarding helper).",
3
+ "version": "0.6.1",
4
+ "description": "Licensed content for AI agents \u2014 discover, purchase, verify, and retrieve rights-cleared expert analysis with a verifiable license key per article, on-chain proof, and EU AI Act Article 53 attestation. The alternative to unlicensed scraping for RAG, AI search, and training pipelines.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
+ "mcpName": "io.github.opedd/opedd-mcp",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/Opedd/opedd-mcp.git"
11
+ },
12
+ "homepage": "https://opedd.com/for-ai-agents",
13
+ "bugs": {
14
+ "url": "https://github.com/Opedd/opedd-mcp/issues"
15
+ },
7
16
  "bin": {
8
17
  "opedd-mcp": "dist/index.js"
9
18
  },
@@ -17,11 +26,17 @@
17
26
  },
18
27
  "keywords": [
19
28
  "mcp",
29
+ "model-context-protocol",
20
30
  "opedd",
21
- "licensing",
31
+ "content-licensing",
32
+ "licensed-content",
33
+ "rag",
34
+ "ai-agents",
35
+ "eu-ai-act",
36
+ "copyright",
37
+ "rights-management",
22
38
  "content",
23
- "ai",
24
- "model-context-protocol"
39
+ "ai"
25
40
  ],
26
41
  "author": "Opedd",
27
42
  "license": "MIT",
@@ -41,4 +56,4 @@
41
56
  "files": [
42
57
  "dist"
43
58
  ]
44
- }
59
+ }