get_entry
Fetch a single RSS feed entry by its numeric ID. Get the complete details of that entry.
Instructions
[read] Fetch a single entry by numeric id.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| entry_id | Yes |
Implementation Reference
- src/tools.ts:192-201 (handler)The get_entry tool handler: takes an entry_id, makes a GET request to /api/v1/entry/{entry_id}.
{ name: "get_entry", description: "Fetch a single entry by numeric id.", scope: "read", inputSchema: z.object({ entry_id: z.number().int().positive(), }), handler: ({ entry_id }: any, c) => c.request("GET", `/api/v1/entry/${entry_id}`), }, - src/tools.ts:196-198 (schema)Input schema for get_entry: requires a positive integer 'entry_id'.
inputSchema: z.object({ entry_id: z.number().int().positive(), }), - src/index.ts:37-43 (registration)Tools are registered with the MCP server via ListToolsRequestSchema handler, mapping TOOLS array to name/description/inputSchema.
server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOLS.map((t) => ({ name: t.name, description: `[${t.scope}] ${t.description}`, inputSchema: zodToJsonSchema(t.inputSchema, { target: "openApi3" }), })), })); - src/index.ts:45-86 (registration)CallToolRequestSchema handler: finds the tool by name from TOOLS array (including get_entry), validates input, and invokes handler.
server.setRequestHandler(CallToolRequestSchema, async (req) => { const tool = TOOLS.find((t) => t.name === req.params.name); if (!tool) { return { isError: true, content: [{ type: "text", text: `Unknown tool: ${req.params.name}` }], }; } const parsed = tool.inputSchema.safeParse(req.params.arguments ?? {}); if (!parsed.success) { return { isError: true, content: [ { type: "text", text: `Invalid arguments: ${parsed.error.message}`, }, ], }; } try { const result = await tool.handler(parsed.data, client); return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }], }; } catch (err) { const e = err as Error & { status?: number; body?: unknown }; return { isError: true, content: [ { type: "text", text: JSON.stringify( { error: e.message, status: e.status, body: e.body }, null, 2, ), }, ], }; } }); - src/client.ts:13-56 (helper)FeedbagelClient class with the request() method that the get_entry handler calls (GET /api/v1/entry/{entry_id}).
export class FeedbagelClient { private apiKey: string; private baseUrl: string; constructor(opts: ClientOptions) { if (!opts.apiKey) throw new Error("FEEDBAGEL_API_KEY is required"); this.apiKey = opts.apiKey; this.baseUrl = (opts.baseUrl ?? DEFAULT_BASE).replace(/\/$/, ""); } async request( method: string, path: string, body?: unknown, ): Promise<unknown> { const res = await fetch(`${this.baseUrl}${path}`, { method, headers: { Authorization: `Bearer ${this.apiKey}`, ...(body !== undefined ? { "content-type": "application/json" } : {}), }, body: body !== undefined ? JSON.stringify(body) : undefined, }); const text = await res.text(); let json: unknown = undefined; try { json = text ? JSON.parse(text) : undefined; } catch { json = { raw: text }; } if (!res.ok) { // Surface 429 and 4xx details verbatim so the agent sees the cap info. const err: Error & { status?: number; body?: unknown } = new Error( `HTTP ${res.status} ${res.statusText}`, ); err.status = res.status; err.body = json; throw err; } return json; } }