fix: apply all A-J improvements across MCP server

- A: fix get_user_profile URL (/api/user/profile → /api/users/:username)
- B: fix unban_user to use DELETE /api/mod/users/:id/ban (was POST .../unban)
- C: add check_duplicates tool (GET /api/news/:id/check-duplicates)
- D: add shadowban_user tool (PATCH /api/mod/users/:id/shadowban)
- E: add create_mod_user tool (POST /api/mod/users)
- F: extract handleTool helper in utils.ts; all 37 tools now use it for
     consistent isError:true error responses visible to the AI model
- G: only send Content-Type header when request has a body
- H: support BETTERNEWS_BASE_URL env var for local dev overrides
- I: fix get_news_item_stats description (accessible by own author, not Mod/Admin only)
- J: add .describe() to page/limit/status params in list_all_tickets and list_my_tickets

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Space-Banane
2026-06-17 22:07:21 +02:00
parent 81ac5973e6
commit a1d47d4819
10 changed files with 254 additions and 185 deletions
+10 -9
View File
@@ -1,6 +1,7 @@
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";
import type { BetterNewsClient } from "../client.js";
import { handleTool } from "../utils.js";
export function registerCommentTools(server: McpServer, client: BetterNewsClient) {
server.tool(
@@ -11,10 +12,10 @@ export function registerCommentTools(server: McpServer, client: BetterNewsClient
page: z.number().int().positive().optional().describe("Page number (default 1)"),
limit: z.number().int().min(1).max(100).optional().describe("Items per page (default 20)"),
},
async ({ newsItemId, page, limit }) => {
handleTool(async ({ newsItemId, page, limit }) => {
const data = await client.get<unknown>(`/api/news/${newsItemId}/comments`, { page, limit });
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
},
return JSON.stringify(data, null, 2);
}),
);
server.tool(
@@ -24,10 +25,10 @@ export function registerCommentTools(server: McpServer, client: BetterNewsClient
newsItemId: z.string().uuid().describe("News item UUID"),
content: z.string().min(1).max(2000).describe("Comment text"),
},
async ({ newsItemId, content }) => {
handleTool(async ({ newsItemId, content }) => {
const data = await client.post<unknown>(`/api/news/${newsItemId}/comments`, { content });
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
},
return JSON.stringify(data, null, 2);
}),
);
server.tool(
@@ -37,9 +38,9 @@ export function registerCommentTools(server: McpServer, client: BetterNewsClient
newsItemId: z.string().uuid().describe("News item UUID"),
commentId: z.string().uuid().describe("Comment UUID"),
},
async ({ newsItemId, commentId }) => {
handleTool(async ({ newsItemId, commentId }) => {
const data = await client.delete<unknown>(`/api/news/${newsItemId}/comments/${commentId}`);
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
},
return JSON.stringify(data, null, 2);
}),
);
}