opedd-mcp 0.1.0 → 0.1.2
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 +1 -1
- package/dist/index.js +46 -3
- package/package.json +1 -1
- package/src/index.ts +58 -3
package/README.md
CHANGED
|
@@ -90,7 +90,7 @@ The assistant will call the appropriate Opedd tools, show you the results, and
|
|
|
90
90
|
|
|
91
91
|
## Payment methods
|
|
92
92
|
|
|
93
|
-
Purchases use **Stripe** by default (via `pm_...` payment method IDs). USDC on
|
|
93
|
+
Purchases use **Stripe** by default (via `pm_...` payment method IDs). USDC on Tempo is also supported by the Opedd API — pass `payment: { method: 'usdc', tx_hash: '0x...' }` directly to `agent-purchase` if building a custom integration.
|
|
94
94
|
|
|
95
95
|
## Development
|
|
96
96
|
|
package/dist/index.js
CHANGED
|
@@ -4,10 +4,11 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
|
|
|
4
4
|
import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
5
5
|
// ─── Configuration ────────────────────────────────────────────────────────────
|
|
6
6
|
const API_BASE = process.env.OPEDD_API_URL ??
|
|
7
|
-
"https://
|
|
7
|
+
"https://api.opedd.com";
|
|
8
8
|
const BUYER_EMAIL = process.env.OPEDD_BUYER_EMAIL;
|
|
9
9
|
const PAYMENT_METHOD_ID = process.env.OPEDD_PAYMENT_METHOD_ID;
|
|
10
10
|
const API_KEY = process.env.OPEDD_API_KEY; // publisher API key (op_...)
|
|
11
|
+
const BUYER_TOKEN = process.env.OPEDD_BUYER_TOKEN; // buyer API token (bk_live_...)
|
|
11
12
|
// ─── HTTP helpers ─────────────────────────────────────────────────────────────
|
|
12
13
|
async function opeddFetch(path, options = {}) {
|
|
13
14
|
const url = `${API_BASE}${path}`;
|
|
@@ -17,7 +18,12 @@ async function opeddFetch(path, options = {}) {
|
|
|
17
18
|
...(options.headers ?? {}),
|
|
18
19
|
};
|
|
19
20
|
const res = await fetch(url, { ...options, headers });
|
|
20
|
-
|
|
21
|
+
const body = await res.json();
|
|
22
|
+
if (!res.ok) {
|
|
23
|
+
const msg = body?.error || body?.message || `HTTP ${res.status}`;
|
|
24
|
+
throw new Error(msg);
|
|
25
|
+
}
|
|
26
|
+
return body;
|
|
21
27
|
}
|
|
22
28
|
function ok(data) {
|
|
23
29
|
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
@@ -134,6 +140,30 @@ const TOOLS = [
|
|
|
134
140
|
},
|
|
135
141
|
},
|
|
136
142
|
];
|
|
143
|
+
// If a buyer token is configured, expose content delivery tooling
|
|
144
|
+
if (BUYER_TOKEN) {
|
|
145
|
+
TOOLS.push({
|
|
146
|
+
name: "get_content",
|
|
147
|
+
description: "Retrieve the full body of a licensed article using a buyer API token (bk_live_...). " +
|
|
148
|
+
"Requires OPEDD_BUYER_TOKEN env var (create one at opedd.com/licenses after purchasing). " +
|
|
149
|
+
"Works for per-article licenses (token scoped to that article) and archive licenses (token covers all publisher content). " +
|
|
150
|
+
"The publisher must have content delivery enabled and must have pushed content for the article.",
|
|
151
|
+
inputSchema: {
|
|
152
|
+
type: "object",
|
|
153
|
+
required: ["article_id"],
|
|
154
|
+
properties: {
|
|
155
|
+
article_id: {
|
|
156
|
+
type: "string",
|
|
157
|
+
description: "The Opedd article UUID to retrieve content for",
|
|
158
|
+
},
|
|
159
|
+
buyer_token: {
|
|
160
|
+
type: "string",
|
|
161
|
+
description: "Buyer API token (bk_live_...). Falls back to OPEDD_BUYER_TOKEN env var.",
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
});
|
|
166
|
+
}
|
|
137
167
|
// If a publisher API key is configured, expose publisher-specific tooling
|
|
138
168
|
if (API_KEY) {
|
|
139
169
|
TOOLS.push({
|
|
@@ -162,7 +192,7 @@ if (API_KEY) {
|
|
|
162
192
|
});
|
|
163
193
|
}
|
|
164
194
|
// ─── MCP Server ───────────────────────────────────────────────────────────────
|
|
165
|
-
const server = new Server({ name: "opedd-mcp", version: "0.1.
|
|
195
|
+
const server = new Server({ name: "opedd-mcp", version: "0.1.2" }, { capabilities: { tools: {} } });
|
|
166
196
|
server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOLS }));
|
|
167
197
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
168
198
|
const { name, arguments: args = {} } = request.params;
|
|
@@ -226,6 +256,19 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
226
256
|
const data = await opeddFetch(`/registry?${params.toString()}`);
|
|
227
257
|
return ok(data);
|
|
228
258
|
}
|
|
259
|
+
// ── get_content ────────────────────────────────────────────────────────
|
|
260
|
+
case "get_content": {
|
|
261
|
+
const { article_id, buyer_token: argToken } = args;
|
|
262
|
+
if (!article_id)
|
|
263
|
+
return err("article_id is required");
|
|
264
|
+
const token = argToken || BUYER_TOKEN;
|
|
265
|
+
if (!token) {
|
|
266
|
+
return err("buyer_token is required (or set the OPEDD_BUYER_TOKEN env var). " +
|
|
267
|
+
"Create a token at opedd.com/licenses after purchasing a license.");
|
|
268
|
+
}
|
|
269
|
+
const data = await opeddFetch(`/content-delivery?article_id=${encodeURIComponent(article_id)}`, { headers: { Authorization: `Bearer ${token}` } });
|
|
270
|
+
return ok(data);
|
|
271
|
+
}
|
|
229
272
|
// ── list_publisher_content ─────────────────────────────────────────────
|
|
230
273
|
case "list_publisher_content": {
|
|
231
274
|
if (!API_KEY) {
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -12,11 +12,12 @@ import {
|
|
|
12
12
|
|
|
13
13
|
const API_BASE =
|
|
14
14
|
process.env.OPEDD_API_URL ??
|
|
15
|
-
"https://
|
|
15
|
+
"https://api.opedd.com";
|
|
16
16
|
|
|
17
17
|
const BUYER_EMAIL = process.env.OPEDD_BUYER_EMAIL;
|
|
18
18
|
const PAYMENT_METHOD_ID = process.env.OPEDD_PAYMENT_METHOD_ID;
|
|
19
19
|
const API_KEY = process.env.OPEDD_API_KEY; // publisher API key (op_...)
|
|
20
|
+
const BUYER_TOKEN = process.env.OPEDD_BUYER_TOKEN; // buyer API token (bk_live_...)
|
|
20
21
|
|
|
21
22
|
// ─── HTTP helpers ─────────────────────────────────────────────────────────────
|
|
22
23
|
|
|
@@ -28,7 +29,12 @@ async function opeddFetch(path: string, options: RequestInit = {}): Promise<unkn
|
|
|
28
29
|
...(options.headers as Record<string, string> ?? {}),
|
|
29
30
|
};
|
|
30
31
|
const res = await fetch(url, { ...options, headers });
|
|
31
|
-
|
|
32
|
+
const body = await res.json();
|
|
33
|
+
if (!res.ok) {
|
|
34
|
+
const msg = (body as any)?.error || (body as any)?.message || `HTTP ${res.status}`;
|
|
35
|
+
throw new Error(msg);
|
|
36
|
+
}
|
|
37
|
+
return body;
|
|
32
38
|
}
|
|
33
39
|
|
|
34
40
|
// ─── MCP response helpers ─────────────────────────────────────────────────────
|
|
@@ -161,6 +167,32 @@ const TOOLS: Tool[] = [
|
|
|
161
167
|
},
|
|
162
168
|
];
|
|
163
169
|
|
|
170
|
+
// If a buyer token is configured, expose content delivery tooling
|
|
171
|
+
if (BUYER_TOKEN) {
|
|
172
|
+
TOOLS.push({
|
|
173
|
+
name: "get_content",
|
|
174
|
+
description:
|
|
175
|
+
"Retrieve the full body of a licensed article using a buyer API token (bk_live_...). " +
|
|
176
|
+
"Requires OPEDD_BUYER_TOKEN env var (create one at opedd.com/licenses after purchasing). " +
|
|
177
|
+
"Works for per-article licenses (token scoped to that article) and archive licenses (token covers all publisher content). " +
|
|
178
|
+
"The publisher must have content delivery enabled and must have pushed content for the article.",
|
|
179
|
+
inputSchema: {
|
|
180
|
+
type: "object",
|
|
181
|
+
required: ["article_id"],
|
|
182
|
+
properties: {
|
|
183
|
+
article_id: {
|
|
184
|
+
type: "string",
|
|
185
|
+
description: "The Opedd article UUID to retrieve content for",
|
|
186
|
+
},
|
|
187
|
+
buyer_token: {
|
|
188
|
+
type: "string",
|
|
189
|
+
description: "Buyer API token (bk_live_...). Falls back to OPEDD_BUYER_TOKEN env var.",
|
|
190
|
+
},
|
|
191
|
+
},
|
|
192
|
+
},
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
|
|
164
196
|
// If a publisher API key is configured, expose publisher-specific tooling
|
|
165
197
|
if (API_KEY) {
|
|
166
198
|
TOOLS.push({
|
|
@@ -193,7 +225,7 @@ if (API_KEY) {
|
|
|
193
225
|
// ─── MCP Server ───────────────────────────────────────────────────────────────
|
|
194
226
|
|
|
195
227
|
const server = new Server(
|
|
196
|
-
{ name: "opedd-mcp", version: "0.1.
|
|
228
|
+
{ name: "opedd-mcp", version: "0.1.2" },
|
|
197
229
|
{ capabilities: { tools: {} } }
|
|
198
230
|
);
|
|
199
231
|
|
|
@@ -299,6 +331,29 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
299
331
|
return ok(data);
|
|
300
332
|
}
|
|
301
333
|
|
|
334
|
+
// ── get_content ────────────────────────────────────────────────────────
|
|
335
|
+
case "get_content": {
|
|
336
|
+
const { article_id, buyer_token: argToken } = args as {
|
|
337
|
+
article_id: string;
|
|
338
|
+
buyer_token?: string;
|
|
339
|
+
};
|
|
340
|
+
if (!article_id) return err("article_id is required");
|
|
341
|
+
|
|
342
|
+
const token = argToken || BUYER_TOKEN;
|
|
343
|
+
if (!token) {
|
|
344
|
+
return err(
|
|
345
|
+
"buyer_token is required (or set the OPEDD_BUYER_TOKEN env var). " +
|
|
346
|
+
"Create a token at opedd.com/licenses after purchasing a license."
|
|
347
|
+
);
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
const data = await opeddFetch(
|
|
351
|
+
`/content-delivery?article_id=${encodeURIComponent(article_id)}`,
|
|
352
|
+
{ headers: { Authorization: `Bearer ${token}` } }
|
|
353
|
+
);
|
|
354
|
+
return ok(data);
|
|
355
|
+
}
|
|
356
|
+
|
|
302
357
|
// ── list_publisher_content ─────────────────────────────────────────────
|
|
303
358
|
case "list_publisher_content": {
|
|
304
359
|
if (!API_KEY) {
|