mirror of
https://ghfast.top/https://github.com/discourse/discourse-mcp.git
synced 2026-07-15 11:36:36 +08:00
* FEATURE: add support for topic editing - supports tagging/categorising/changing title on an existing topic - added linting * version bump * avoid uses of any where possible no new features just consistency / maintainability * - simpler agents md - improved docs - better parsing for auth pairs - clear write access checks - better testing of tool lists
2.9 KiB
2.9 KiB
AGENTS.md — Discourse MCP
MCP server exposing Discourse forum capabilities as tools/resources for AI agents.
Entry: src/index.ts → dist/index.js (binary: discourse-mcp). Node >= 24.
SDLC Commands
pnpm build # Compile TypeScript to dist/
pnpm typecheck # Type-check only (no emit)
pnpm lint # Run ESLint on src/
pnpm test # Run tests (requires build first)
pnpm clean # Remove dist/
Source Map
| Area | Files |
|---|---|
| Entry/CLI | src/index.ts |
| HTTP client | src/http/client.ts |
| Tool registry | src/tools/registry.ts |
| Resource registry | src/resources/registry.ts |
| Built-in tools | src/tools/builtin/* |
| Remote tools | src/tools/remote/tool_exec_api.ts |
| Utilities | src/util/*.ts (logger, redact, json_response) |
Key Patterns
Tool Implementation
- Tools live in
src/tools/builtin/as individual files - Each tool exports a registration function called by
src/tools/registry.ts - All tools return strict JSON (no Markdown) with
isError: trueon failure - Write tools require
--allow_writesflag and matchingauth_pairsentry
Resources
- URI-addressable read-only data (categories, tags, groups, channels, drafts)
- Registered in
src/resources/registry.ts
HTTP Layer
- Client in
src/http/client.tshandles auth, retries (429/5xx), caching - User-Agent:
Discourse-MCP/0.x - Write tools enforce ~1 req/sec rate limit
Configuration
- CLI flags validated via Zod in
src/index.ts - Auth via
--auth_pairsJSON (API keys or User API keys) --site <url>tethers to single site, hidesdiscourse_select_sitetool
Testing
- Tests in
src/test/use Node's built-in test runner - Build before running tests:
pnpm build && pnpm test
Adding a New Tool
- Create
src/tools/builtin/<name>.ts - Export a
RegisterFnfunction - Import and call it in
src/tools/registry.ts
Minimal template:
import { z } from "zod";
import type { RegisterFn } from "../types.js";
import { jsonResponse, jsonError } from "../../util/json_response.js";
export const registerMyTool: RegisterFn = (server, ctx, opts) => {
if (!opts.allowWrites) return; // omit for read-only tools
server.registerTool(
"discourse_my_tool",
{
title: "My Tool",
description: "Does X. Returns JSON with Y.",
inputSchema: z.object({ id: z.number() }).shape,
},
async (args) => {
const { client } = ctx.siteState.ensureSelectedSite();
try {
const data = await client.get(`/endpoint.json`);
return jsonResponse(data);
} catch (e: any) {
return jsonError(`Failed: ${e?.message}`);
}
}
);
};
Key helpers:
jsonResponse(data)— success responsejsonError(msg)— error withisError: truepaginatedResponse(name, items, meta)— for listsrateLimit(key)— throttle writes (call before mutations)ctx.siteState.ensureSelectedSite()— get{ base, client }