agentdocs-mcp
Advanced tools
| import type { Config } from "./config.js"; | ||
| export declare class ApiError extends Error { | ||
| readonly status: number; | ||
| readonly body: Record<string, unknown>; | ||
| constructor(status: number, body: Record<string, unknown>, message: string); | ||
| } | ||
| export declare class AgentDocsClient { | ||
| private readonly config; | ||
| constructor(config: Config); | ||
| get baseUrl(): string; | ||
| /** | ||
| * `authHeader` wins when present (the remote endpoint forwards the caller's | ||
| * own header, which may be `Bearer <jwt>`); otherwise fall back to the stdio | ||
| * server's single `Token <api_token>` credential. | ||
| */ | ||
| private get authorization(); | ||
| request<T = Record<string, unknown>>(method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE", path: string, body?: unknown, query?: Record<string, string>): Promise<T>; | ||
| private fetchWithColdStartRetry; | ||
| } |
| export interface Config { | ||
| baseUrl: string; | ||
| /** | ||
| * Raw credential, sent as `Authorization: Token <token>`. Required for the | ||
| * stdio server, which owns exactly one credential for its whole lifetime. | ||
| */ | ||
| token?: string; | ||
| /** | ||
| * Complete `Authorization` header value, used verbatim when present. | ||
| * | ||
| * The remote (Streamable HTTP) endpoint needs this: it serves many callers, | ||
| * each arriving with their own header, and that header may legitimately be | ||
| * `Bearer <jwt>` rather than `Token <api_token>`. Forwarding it unchanged | ||
| * avoids re-deriving a scheme the caller already chose. | ||
| */ | ||
| authHeader?: string; | ||
| } | ||
| export declare function loadConfig(): Config; |
| import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; | ||
| import type { AgentDocsClient } from "./client.js"; | ||
| import type { Resolver } from "./resolve.js"; | ||
| export interface CredentialInfo { | ||
| type: "account" | "space" | "jwt"; | ||
| userName?: string; | ||
| spaceId?: string; | ||
| spaceName?: string; | ||
| workspaceId?: string; | ||
| workspaceName?: string; | ||
| } | ||
| export interface ToolContext { | ||
| client: AgentDocsClient; | ||
| resolver: Resolver; | ||
| credential: CredentialInfo; | ||
| } | ||
| type ToolResult = { | ||
| content: Array<{ | ||
| type: "text"; | ||
| text: string; | ||
| }>; | ||
| isError?: boolean; | ||
| }; | ||
| export declare function textResult(data: unknown): ToolResult; | ||
| /** Wrap a tool handler so thrown errors surface as readable MCP tool errors. */ | ||
| export declare function safe<Args>(handler: (args: Args) => Promise<ToolResult>): (args: Args) => Promise<ToolResult>; | ||
| export type RegisterFn = (server: McpServer, ctx: ToolContext) => void; | ||
| export {}; |
| #!/usr/bin/env node | ||
| export {}; |
| /** | ||
| * Library entry point. | ||
| * | ||
| * The stdio binary (`src/index.ts`) is one consumer of this module; the other | ||
| * is AgentDocs' own backend, which mounts a remote Streamable HTTP endpoint at | ||
| * POST /mcp and registers these same tools per request. Keeping the tool | ||
| * definitions here — and exporting them rather than copying them — is what | ||
| * stops the stdio and remote surfaces from drifting apart. | ||
| */ | ||
| import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; | ||
| import type { ToolContext } from "./context.js"; | ||
| export { AgentDocsClient, ApiError } from "./client.js"; | ||
| export { Resolver, isUuid } from "./resolve.js"; | ||
| export type { Config } from "./config.js"; | ||
| export type { CredentialInfo, ToolContext } from "./context.js"; | ||
| /** Register the full AgentDocs tool set on an MCP server instance. */ | ||
| export declare function registerAllTools(server: McpServer, ctx: ToolContext): void; | ||
| /** | ||
| * Build a ready-to-serve MCP server for one caller. | ||
| * | ||
| * Remote callers MUST get their own instance per request: `Resolver` caches | ||
| * slug -> UUID with no user dimension (see resolve.ts), so a shared instance | ||
| * would let one tenant's resolutions answer another's lookups. | ||
| */ | ||
| export declare function createMcpServer(ctx: ToolContext, version: string): McpServer; |
+35
| /** | ||
| * Library entry point. | ||
| * | ||
| * The stdio binary (`src/index.ts`) is one consumer of this module; the other | ||
| * is AgentDocs' own backend, which mounts a remote Streamable HTTP endpoint at | ||
| * POST /mcp and registers these same tools per request. Keeping the tool | ||
| * definitions here — and exporting them rather than copying them — is what | ||
| * stops the stdio and remote surfaces from drifting apart. | ||
| */ | ||
| import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; | ||
| import { registerReadTools } from "./tools/read.js"; | ||
| import { registerWriteTools } from "./tools/write.js"; | ||
| import { registerShareTools } from "./tools/share.js"; | ||
| import { registerCommentTools } from "./tools/comments.js"; | ||
| export { AgentDocsClient, ApiError } from "./client.js"; | ||
| export { Resolver, isUuid } from "./resolve.js"; | ||
| /** Register the full AgentDocs tool set on an MCP server instance. */ | ||
| export function registerAllTools(server, ctx) { | ||
| registerReadTools(server, ctx); | ||
| registerWriteTools(server, ctx); | ||
| registerShareTools(server, ctx); | ||
| registerCommentTools(server, ctx); | ||
| } | ||
| /** | ||
| * Build a ready-to-serve MCP server for one caller. | ||
| * | ||
| * Remote callers MUST get their own instance per request: `Resolver` caches | ||
| * slug -> UUID with no user dimension (see resolve.ts), so a shared instance | ||
| * would let one tenant's resolutions answer another's lookups. | ||
| */ | ||
| export function createMcpServer(ctx, version) { | ||
| const server = new McpServer({ name: "agentdocs", version }); | ||
| registerAllTools(server, ctx); | ||
| return server; | ||
| } |
| import type { AgentDocsClient } from "./client.js"; | ||
| export declare function isUuid(value: string): boolean; | ||
| /** | ||
| * Resolves human-friendly slug paths ("workspace/space/page") to entity UUIDs | ||
| * via GET /api/resolve/..., with a small per-process cache. | ||
| * | ||
| * Space-scoped tokens cannot call /api/resolve (it is workspace-scoped), so | ||
| * when the credential is a space token we only accept UUIDs and fall back to | ||
| * the token's own space as the default. | ||
| */ | ||
| export declare class Resolver { | ||
| private readonly client; | ||
| private readonly slugResolutionAllowed; | ||
| private readonly defaultSpaceId?; | ||
| private cache; | ||
| constructor(client: AgentDocsClient, slugResolutionAllowed: boolean, defaultSpaceId?: string | undefined); | ||
| workspaceId(ref: string): Promise<string>; | ||
| spaceId(ref?: string): Promise<string>; | ||
| pageId(ref: string): Promise<string>; | ||
| private resolve; | ||
| } |
| import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; | ||
| import type { ToolContext } from "../context.js"; | ||
| export declare function registerCommentTools(server: McpServer, ctx: ToolContext): void; |
| import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; | ||
| import type { ToolContext } from "../context.js"; | ||
| export declare function registerReadTools(server: McpServer, ctx: ToolContext): void; |
| import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; | ||
| import type { ToolContext } from "../context.js"; | ||
| export declare function registerShareTools(server: McpServer, ctx: ToolContext): void; |
| import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; | ||
| import type { ToolContext } from "../context.js"; | ||
| export declare function registerWriteTools(server: McpServer, ctx: ToolContext): void; |
+25
-0
@@ -7,2 +7,27 @@ # Changelog | ||
| ## 0.7.0 — 2026-07-26 | ||
| ### Added | ||
| - The package is now importable as a **library**, not just runnable as a stdio | ||
| binary. New `exports` map with `registerAllTools(server, ctx)` and | ||
| `createMcpServer(ctx, version)` from `dist/lib.js`, plus `AgentDocsClient`, | ||
| `Resolver` and the `ToolContext` / `Config` types. TypeScript declarations | ||
| are now emitted. | ||
| This exists so AgentDocs' backend can mount a **remote (Streamable HTTP)** | ||
| MCP endpoint at `POST /mcp` that registers these exact tool definitions per | ||
| request. Exporting them — rather than copying them into the backend — is what | ||
| keeps the stdio and remote surfaces from drifting apart. | ||
| - `Config.authHeader`: a complete `Authorization` header value, used verbatim | ||
| when set. The remote endpoint serves many callers, each with their own header, | ||
| which may be `Bearer <jwt>` rather than `Token <api_token>`. `Config.token` | ||
| is now optional, and unchanged for stdio (still sent as `Token <token>`). | ||
| - `"./package.json"` is included in the `exports` map, so tooling that reads it | ||
| (a common pattern for version checks) doesn't hit `ERR_PACKAGE_PATH_NOT_EXPORTED`. | ||
| ### Changed | ||
| - No behavioural change to the stdio server. `src/index.ts` now builds its | ||
| server via the shared `createMcpServer()` instead of registering the four tool | ||
| groups inline; the 18 tools, their schemas and descriptions are identical. | ||
| ## 0.6.2 — 2026-07-11 | ||
@@ -9,0 +34,0 @@ |
+14
-1
@@ -50,2 +50,15 @@ /** | ||
| } | ||
| /** | ||
| * `authHeader` wins when present (the remote endpoint forwards the caller's | ||
| * own header, which may be `Bearer <jwt>`); otherwise fall back to the stdio | ||
| * server's single `Token <api_token>` credential. | ||
| */ | ||
| get authorization() { | ||
| if (this.config.authHeader) | ||
| return this.config.authHeader; | ||
| if (!this.config.token) { | ||
| throw new Error("AgentDocsClient requires either a token or an authHeader."); | ||
| } | ||
| return `Token ${this.config.token}`; | ||
| } | ||
| async request(method, path, body, query) { | ||
@@ -59,3 +72,3 @@ const url = new URL(`${this.config.baseUrl}${path}`); | ||
| headers: { | ||
| Authorization: `Token ${this.config.token}`, | ||
| Authorization: this.authorization, | ||
| ...(body !== undefined ? { "Content-Type": "application/json" } : {}), | ||
@@ -62,0 +75,0 @@ }, |
+2
-10
| #!/usr/bin/env node | ||
| import { createRequire } from "node:module"; | ||
| import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; | ||
| import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; | ||
@@ -8,6 +7,3 @@ import { loadConfig } from "./config.js"; | ||
| import { Resolver } from "./resolve.js"; | ||
| import { registerReadTools } from "./tools/read.js"; | ||
| import { registerWriteTools } from "./tools/write.js"; | ||
| import { registerShareTools } from "./tools/share.js"; | ||
| import { registerCommentTools } from "./tools/comments.js"; | ||
| import { createMcpServer } from "./lib.js"; | ||
| // Read from package.json rather than a literal: this is the version reported to | ||
@@ -52,7 +48,3 @@ // every client in the MCP initialize handshake, and a hand-maintained copy had | ||
| const ctx = { client, resolver, credential }; | ||
| const server = new McpServer({ name: "agentdocs", version: VERSION }); | ||
| registerReadTools(server, ctx); | ||
| registerWriteTools(server, ctx); | ||
| registerShareTools(server, ctx); | ||
| registerCommentTools(server, ctx); | ||
| const server = createMcpServer(ctx, VERSION); | ||
| await server.connect(new StdioServerTransport()); | ||
@@ -59,0 +51,0 @@ console.error("agentdocs-mcp: ready (stdio)"); |
+11
-1
| { | ||
| "name": "agentdocs-mcp", | ||
| "mcpName": "io.github.hoornet/agentdocs-mcp", | ||
| "version": "0.6.2", | ||
| "version": "0.7.0", | ||
| "description": "MCP server for AgentDocs (agentdocs.eu) — read, search, and write collaborative docs from any MCP client", | ||
@@ -18,2 +18,11 @@ "license": "MIT", | ||
| }, | ||
| "main": "dist/lib.js", | ||
| "types": "dist/lib.d.ts", | ||
| "exports": { | ||
| ".": { | ||
| "types": "./dist/lib.d.ts", | ||
| "default": "./dist/lib.js" | ||
| }, | ||
| "./package.json": "./package.json" | ||
| }, | ||
| "files": [ | ||
@@ -31,2 +40,3 @@ "dist", | ||
| "prepublishOnly": "npm run build", | ||
| "release": "npm run build && npm publish", | ||
| "watch": "tsc --watch" | ||
@@ -33,0 +43,0 @@ }, |
58691
17.61%24
84.62%852
24.02%