feedbagel-mcp 0.1.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/dist/client.js ADDED
@@ -0,0 +1,42 @@
1
+ // Thin HTTP wrapper around the feedbagel v1 API.
2
+ //
3
+ // Every request goes out with the user's Bearer token. The server enforces
4
+ // auth, scopes, and rate limits; this client is intentionally dumb.
5
+ const DEFAULT_BASE = "https://api.feedbagel.com";
6
+ export class FeedbagelClient {
7
+ apiKey;
8
+ baseUrl;
9
+ constructor(opts) {
10
+ if (!opts.apiKey)
11
+ throw new Error("FEEDBAGEL_API_KEY is required");
12
+ this.apiKey = opts.apiKey;
13
+ this.baseUrl = (opts.baseUrl ?? DEFAULT_BASE).replace(/\/$/, "");
14
+ }
15
+ async request(method, path, body) {
16
+ const res = await fetch(`${this.baseUrl}${path}`, {
17
+ method,
18
+ headers: {
19
+ Authorization: `Bearer ${this.apiKey}`,
20
+ ...(body !== undefined ? { "content-type": "application/json" } : {}),
21
+ },
22
+ body: body !== undefined ? JSON.stringify(body) : undefined,
23
+ });
24
+ const text = await res.text();
25
+ let json = undefined;
26
+ try {
27
+ json = text ? JSON.parse(text) : undefined;
28
+ }
29
+ catch {
30
+ json = { raw: text };
31
+ }
32
+ if (!res.ok) {
33
+ // Surface 429 and 4xx details verbatim so the agent sees the cap info.
34
+ const err = new Error(`HTTP ${res.status} ${res.statusText}`);
35
+ err.status = res.status;
36
+ err.body = json;
37
+ throw err;
38
+ }
39
+ return json;
40
+ }
41
+ }
42
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,iDAAiD;AACjD,EAAE;AACF,2EAA2E;AAC3E,oEAAoE;AAEpE,MAAM,YAAY,GAAG,2BAA2B,CAAC;AAOjD,MAAM,OAAO,eAAe;IAClB,MAAM,CAAS;IACf,OAAO,CAAS;IAExB,YAAY,IAAmB;QAC7B,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;QACnE,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC1B,IAAI,CAAC,OAAO,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,YAAY,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACnE,CAAC;IAED,KAAK,CAAC,OAAO,CACX,MAAc,EACd,IAAY,EACZ,IAAc;QAEd,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,EAAE,EAAE;YAChD,MAAM;YACN,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,IAAI,CAAC,MAAM,EAAE;gBACtC,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACtE;YACD,IAAI,EAAE,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;SAC5D,CAAC,CAAC;QAEH,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QAC9B,IAAI,IAAI,GAAY,SAAS,CAAC;QAC9B,IAAI,CAAC;YACH,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC7C,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;QACvB,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,uEAAuE;YACvE,MAAM,GAAG,GAAgD,IAAI,KAAK,CAChE,QAAQ,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,UAAU,EAAE,CACvC,CAAC;YACF,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;YACxB,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC;YAChB,MAAM,GAAG,CAAC;QACZ,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;CACF"}
package/dist/index.js ADDED
@@ -0,0 +1,71 @@
1
+ #!/usr/bin/env node
2
+ // feedbagel-mcp — Model Context Protocol server for the feedbagel API.
3
+ //
4
+ // Reads FEEDBAGEL_API_KEY from env and exposes the v1 tool surface over
5
+ // stdio. Agents register this binary as an MCP server; their LLM can
6
+ // then invoke tools that hit api.feedbagel.com on the user's behalf.
7
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
8
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
9
+ import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
10
+ import { zodToJsonSchema } from "zod-to-json-schema";
11
+ import { FeedbagelClient } from "./client.js";
12
+ import { TOOLS } from "./tools.js";
13
+ const apiKey = process.env.FEEDBAGEL_API_KEY;
14
+ if (!apiKey) {
15
+ console.error("feedbagel-mcp: FEEDBAGEL_API_KEY is not set. Mint a key at https://feedbagel.com/dashboard/keys (pick 'Agent') and add it to your MCP server config.");
16
+ process.exit(1);
17
+ }
18
+ const client = new FeedbagelClient({
19
+ apiKey,
20
+ baseUrl: process.env.FEEDBAGEL_API_BASE,
21
+ });
22
+ const server = new Server({ name: "feedbagel-mcp", version: "0.1.0" }, { capabilities: { tools: {} } });
23
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({
24
+ tools: TOOLS.map((t) => ({
25
+ name: t.name,
26
+ description: `[${t.scope}] ${t.description}`,
27
+ inputSchema: zodToJsonSchema(t.inputSchema, { target: "openApi3" }),
28
+ })),
29
+ }));
30
+ server.setRequestHandler(CallToolRequestSchema, async (req) => {
31
+ const tool = TOOLS.find((t) => t.name === req.params.name);
32
+ if (!tool) {
33
+ return {
34
+ isError: true,
35
+ content: [{ type: "text", text: `Unknown tool: ${req.params.name}` }],
36
+ };
37
+ }
38
+ const parsed = tool.inputSchema.safeParse(req.params.arguments ?? {});
39
+ if (!parsed.success) {
40
+ return {
41
+ isError: true,
42
+ content: [
43
+ {
44
+ type: "text",
45
+ text: `Invalid arguments: ${parsed.error.message}`,
46
+ },
47
+ ],
48
+ };
49
+ }
50
+ try {
51
+ const result = await tool.handler(parsed.data, client);
52
+ return {
53
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
54
+ };
55
+ }
56
+ catch (err) {
57
+ const e = err;
58
+ return {
59
+ isError: true,
60
+ content: [
61
+ {
62
+ type: "text",
63
+ text: JSON.stringify({ error: e.message, status: e.status, body: e.body }, null, 2),
64
+ },
65
+ ],
66
+ };
67
+ }
68
+ });
69
+ const transport = new StdioServerTransport();
70
+ await server.connect(transport);
71
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/tools.js ADDED
@@ -0,0 +1,165 @@
1
+ // Tool definitions for the MCP server.
2
+ //
3
+ // Each entry is a JSON-schema'd input shape + an async handler that calls
4
+ // the v1 API. Scopes here are informational (the server enforces them);
5
+ // they're included so an agent inspecting the catalog knows which tools
6
+ // will hit write caps.
7
+ import { z } from "zod";
8
+ const FeedIdInput = z.object({
9
+ feed_id: z.number().int().positive().describe("Numeric feed id"),
10
+ });
11
+ const WebhookIdInput = z.object({
12
+ webhook_id: z.string().describe("Webhook subscriber UUID"),
13
+ });
14
+ export const TOOLS = [
15
+ {
16
+ name: "list_subscriptions",
17
+ description: "Unified list of the user's feed follows and webhook subscriptions. Each item is tagged kind: 'follow' or 'webhook'.",
18
+ scope: "read",
19
+ inputSchema: z.object({}),
20
+ handler: (_, c) => c.request("GET", "/api/v1/subscriptions"),
21
+ },
22
+ {
23
+ name: "follow_feed",
24
+ description: "Add a feed to the user's follow list. Idempotent. Counts against the subscription cap.",
25
+ scope: "write",
26
+ inputSchema: FeedIdInput,
27
+ handler: (input, c) => c.request("POST", "/api/v1/follow", input),
28
+ },
29
+ {
30
+ name: "unfollow_feed",
31
+ description: "Remove a feed from the user's follow list.",
32
+ scope: "write",
33
+ inputSchema: FeedIdInput,
34
+ handler: ({ feed_id }, c) => c.request("DELETE", `/api/v1/follow/${feed_id}`),
35
+ },
36
+ {
37
+ name: "list_webhooks",
38
+ description: "List all webhook subscriptions owned by the user.",
39
+ scope: "read",
40
+ inputSchema: z.object({}),
41
+ handler: (_, c) => c.request("GET", "/api/v1/webhooks"),
42
+ },
43
+ {
44
+ name: "create_webhook",
45
+ description: "Create a webhook subscription. The response includes webhook_secret ONCE; the bot must persist it for HMAC validation. Counts against the subscription cap.",
46
+ scope: "write",
47
+ inputSchema: z.object({
48
+ webhook_url: z.string().url(),
49
+ subscriber_name: z.string().max(120).optional(),
50
+ notes: z.string().max(500).optional(),
51
+ }),
52
+ handler: (input, c) => c.request("POST", "/api/v1/webhooks", input),
53
+ },
54
+ {
55
+ name: "delete_webhook",
56
+ description: "Delete a webhook subscription and all its feed attachments.",
57
+ scope: "write",
58
+ inputSchema: WebhookIdInput,
59
+ handler: ({ webhook_id }, c) => c.request("DELETE", `/api/v1/webhooks/${webhook_id}`),
60
+ },
61
+ {
62
+ name: "pause_webhook",
63
+ description: "Pause deliveries for a webhook subscription. Existing attachments stay; the poller skips this subscriber until resumed.",
64
+ scope: "write",
65
+ inputSchema: WebhookIdInput,
66
+ handler: ({ webhook_id }, c) => c.request("POST", `/api/v1/webhooks/${webhook_id}/pause`),
67
+ },
68
+ {
69
+ name: "resume_webhook",
70
+ description: "Resume deliveries for a paused webhook subscription.",
71
+ scope: "write",
72
+ inputSchema: WebhookIdInput,
73
+ handler: ({ webhook_id }, c) => c.request("POST", `/api/v1/webhooks/${webhook_id}/resume`),
74
+ },
75
+ {
76
+ name: "attach_feed_to_webhook",
77
+ description: "Attach a feed to a webhook subscription so its new entries get delivered.",
78
+ scope: "write",
79
+ inputSchema: WebhookIdInput.merge(FeedIdInput),
80
+ handler: ({ webhook_id, feed_id }, c) => c.request("POST", `/api/v1/webhooks/${webhook_id}/feeds`, {
81
+ feed_id,
82
+ }),
83
+ },
84
+ {
85
+ name: "detach_feed_from_webhook",
86
+ description: "Stop delivering a feed's entries to a webhook subscription.",
87
+ scope: "write",
88
+ inputSchema: WebhookIdInput.merge(FeedIdInput),
89
+ handler: ({ webhook_id, feed_id }, c) => c.request("DELETE", `/api/v1/webhooks/${webhook_id}/feeds/${feed_id}`),
90
+ },
91
+ {
92
+ name: "me",
93
+ description: "Return the authenticated account's email, plan, and status. Use as a smoke test before other calls.",
94
+ scope: "read",
95
+ inputSchema: z.object({}),
96
+ handler: (_, c) => c.request("GET", "/api/v1/me"),
97
+ },
98
+ // --- discovery (public reads, but the MCP still authenticates) -------
99
+ {
100
+ name: "search_feeds",
101
+ description: "Search the feed catalog by keyword. Matches feed titles, urls, and hostnames. Returns up to 20 results with recency stats.",
102
+ scope: "read",
103
+ inputSchema: z.object({
104
+ query: z.string().min(1).max(120),
105
+ }),
106
+ handler: ({ query }, c) => c.request("GET", `/api/v1/search-feeds/keyword/${encodeURIComponent(query)}`),
107
+ },
108
+ {
109
+ name: "search_feeds_by_url",
110
+ description: "Find feeds at a specific hostname or URL fragment. Use this when the user already knows the site (e.g. 'theverge.com') and wants its feeds.",
111
+ scope: "read",
112
+ inputSchema: z.object({
113
+ url_or_host: z.string().min(1).max(200),
114
+ }),
115
+ handler: ({ url_or_host }, c) => c.request("GET", `/api/v1/search-feeds/url/${encodeURIComponent(url_or_host)}`),
116
+ },
117
+ {
118
+ name: "get_host_metadata",
119
+ description: "Get metadata (title, description, favicon, feed list) for a host domain.",
120
+ scope: "read",
121
+ inputSchema: z.object({
122
+ host: z.string().min(1).max(200),
123
+ }),
124
+ handler: ({ host }, c) => c.request("GET", `/api/v1/host/${encodeURIComponent(host)}/metadata`),
125
+ },
126
+ {
127
+ name: "list_entries",
128
+ description: "List recent entries across all feeds, paginated. Use sort_by='published' (default) for newest first.",
129
+ scope: "read",
130
+ inputSchema: z.object({
131
+ page: z.number().int().positive().default(1),
132
+ per_page: z.number().int().min(1).max(100).default(20),
133
+ sort_by: z.enum(["published", "created"]).default("published"),
134
+ sort_order: z.enum(["asc", "desc"]).default("desc"),
135
+ }),
136
+ handler: (input, c) => {
137
+ const qs = new URLSearchParams({
138
+ page: String(input.page),
139
+ per_page: String(input.per_page),
140
+ sort_by: input.sort_by,
141
+ sort_order: input.sort_order,
142
+ }).toString();
143
+ return c.request("GET", `/api/v1/entries?${qs}`);
144
+ },
145
+ },
146
+ {
147
+ name: "get_entry",
148
+ description: "Fetch a single entry by numeric id.",
149
+ scope: "read",
150
+ inputSchema: z.object({
151
+ entry_id: z.number().int().positive(),
152
+ }),
153
+ handler: ({ entry_id }, c) => c.request("GET", `/api/v1/entry/${entry_id}`),
154
+ },
155
+ {
156
+ name: "get_entry_by_slug",
157
+ description: "Fetch a single entry by its URL slug (matches /post/<slug> on the site).",
158
+ scope: "read",
159
+ inputSchema: z.object({
160
+ slug: z.string().min(1).max(300),
161
+ }),
162
+ handler: ({ slug }, c) => c.request("GET", `/api/v1/entry/slug/${encodeURIComponent(slug)}`),
163
+ },
164
+ ];
165
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "feedbagel-mcp",
3
+ "version": "0.1.0",
4
+ "description": "MCP server that exposes the feedbagel API to agents",
5
+ "keywords": ["mcp", "model-context-protocol", "feedbagel", "rss", "agent"],
6
+ "homepage": "https://feedbagel.com/docs#mcp",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/Prototypr/feedbagel-mcp.git"
10
+ },
11
+ "bugs": "https://github.com/Prototypr/feedbagel-mcp/issues",
12
+ "license": "MIT",
13
+ "type": "module",
14
+ "bin": {
15
+ "feedbagel-mcp": "dist/index.js"
16
+ },
17
+ "files": ["dist"],
18
+ "scripts": {
19
+ "build": "tsc",
20
+ "dev": "tsc --watch",
21
+ "start": "node dist/index.js"
22
+ },
23
+ "dependencies": {
24
+ "@modelcontextprotocol/sdk": "^1.0.0",
25
+ "zod": "^3.23.0",
26
+ "zod-to-json-schema": "^3.23.0"
27
+ },
28
+ "devDependencies": {
29
+ "@types/node": "^22.0.0",
30
+ "typescript": "^5.5.0"
31
+ },
32
+ "engines": {
33
+ "node": ">=18"
34
+ }
35
+ }