Build an MCP server that exposes AGNT wiki + graph
Ship a custom MCP server wrapping AGNT's wiki and knowledge graph endpoints.
AGNT's built-in MCP server at /mcp/sse surfaces venue search and memory. If you want to expose additional AGNT surfaces — the wiki vault, the graph API, custom metrics — you'll need a custom MCP server. This guide walks through building one in TypeScript with the official MCP SDK.
Prerequisites
- Node.js 20+.
- Familiarity with the MCP spec (https://modelcontextprotocol.io).
- An AGNT API key with `wiki.read` and `graph.read` scopes.
- Comfort with TypeScript and async HTTP clients.
Why roll your own
AGNT ships a default MCP server that covers the high-frequency surfaces — venue search, memory, knowledge graph. If your workflow needs something more specific (a single wiki cluster, a filtered graph view, custom aggregations), you want a thin custom server rather than overloading the built-in one.
The MCP spec makes this cheap. A server is a process that speaks MCP over stdio or SSE, declares tools, and handles tool calls. With the official SDK, you can have a custom server in ~100 lines of TypeScript.
Step 1 — Scaffold the project
Create a new directory and install the MCP SDK:
mkdir agnt-wiki-mcp && cd agnt-wiki-mcp
npm init -y
npm install @modelcontextprotocol/sdkThe SDK provides the transport layer, the JSON-RPC handling, and the tool registration API. You're only writing business logic.
Step 2 — Define your tools
Decide which AGNT surfaces you want to expose. For this guide, we'll expose two tools: `wiki_search` (full-text search against the wiki) and `graph_neighbors` (return direct neighbors of an entity in the knowledge graph).
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
const server = new Server({ name: "agnt-wiki", version: "1.0.0" });
server.setRequestHandler("tools/list", async () => ({
tools: [
{
name: "wiki_search",
description: "Full-text search the AGNT wiki vault",
inputSchema: {
type: "object",
properties: { query: { type: "string" } },
required: ["query"],
},
},
{
name: "graph_neighbors",
description: "Return direct neighbors of an entity in the AGNT knowledge graph",
inputSchema: {
type: "object",
properties: { entity: { type: "string" } },
required: ["entity"],
},
},
],
}));The `description` field is the single most important thing. LLMs route into tools based on description quality. Use the `/prompts/tool-description-tightener` discipline when writing these.
Step 3 — Implement the tool handlers
Each tool gets a handler that calls AGNT's REST API and returns a structured result:
server.setRequestHandler("tools/call", async (request) => {
const { name, arguments: args } = request.params;
const apiKey = process.env.AGNT_API_KEY;
const base = "https://api.agntdot.com";
if (name === "wiki_search") {
const res = await fetch(`${base}/wiki/search?q=${encodeURIComponent(args.query)}`, {
headers: { Authorization: `Bearer ${apiKey}` },
});
const data = await res.json();
return { content: [{ type: "text", text: JSON.stringify(data) }] };
}
if (name === "graph_neighbors") {
const res = await fetch(`${base}/graph/neighbors?entity=${encodeURIComponent(args.entity)}`, {
headers: { Authorization: `Bearer ${apiKey}` },
});
const data = await res.json();
return { content: [{ type: "text", text: JSON.stringify(data) }] };
}
throw new Error(`Unknown tool: ${name}`);
});Notice the response shape: `{ content: [{ type: "text", text: ... }] }`. This is MCP's standard tool response format. You can return multiple content items (text, images, etc.) — stick with text for JSON payloads.
Step 4 — Start the server
Add the stdio transport and start:
const transport = new StdioServerTransport();
await server.connect(transport);Compile with `npx tsc` (or `tsx` for dev). The server runs as a subprocess — MCP clients like Claude Code launch it, speak to it over stdio, and terminate it when the session ends.
Step 5 — Wire it into Claude Code
Add the server to your Claude Code MCP config:
{
"mcpServers": {
"agnt-wiki": {
"command": "node",
"args": ["/abs/path/to/agnt-wiki-mcp/dist/index.js"],
"env": {
"AGNT_API_KEY": "${AGNT_API_KEY}"
}
}
}
}Restart Claude Code. Ask: "what tools are available from agnt-wiki?" You should see `wiki_search` and `graph_neighbors`.
Tighten your tool descriptions
Before you ship, run the `tool-description-tightener` prompt against each tool description. LLM routing is extremely sensitive to description quality — a 10-character change in the description can flip whether a model routes into the tool or not. This is the single biggest lever for usability.
Rule of thumb: the first 10 words must contain the action verb and the primary object. "Full-text search the AGNT wiki vault" is good. "Helps you find things in the wiki" is bad.