@tobiashochguertel/taskbook-mcp-server 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/transport/stdio.ts", "../src/client/crypto.ts", "../src/client/api.ts", "../src/config.ts", "../src/server.ts", "../src/tools/tasks.ts", "../src/tools/notes.ts", "../src/tools/boards.ts", "../src/tools/general.ts", "../src/resources/index.ts", "../src/transport/http.ts", "../src/index.ts"],
4
+ "sourcesContent": [
5
+ "import { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { TaskbookClient } from \"../client/api.js\";\nimport { loadTaskbookConfig } from \"../config.js\";\nimport { createMcpServer } from \"../server.js\";\n\n/**\n * Start the MCP server with stdio transport.\n * Reads credentials from ~/.taskbook.json or environment variables.\n * Single-client: one process per MCP client connection.\n */\nexport async function startStdioTransport(): Promise<void> {\n const config = loadTaskbookConfig();\n const client = new TaskbookClient(config);\n const server = createMcpServer(() => client);\n\n const transport = new StdioServerTransport();\n await server.connect(transport);\n\n process.stderr.write(\n `[taskbook-mcp] stdio transport connected (server: ${config.serverUrl})\\n`,\n );\n}\n",
6
+ "/** AES-256-GCM encryption/decryption compatible with the Rust CLI and WebUI */\n\nconst HEX_RE = /^[0-9a-fA-F]+$/;\n\nfunction hexToBytes(hex: string): Uint8Array {\n const bytes = new Uint8Array(hex.length / 2);\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = Number.parseInt(hex.substring(i * 2, i * 2 + 2), 16);\n }\n return bytes;\n}\n\nfunction base64Encode(data: Uint8Array): string {\n let binary = \"\";\n for (const byte of data) {\n binary += String.fromCharCode(byte);\n }\n return btoa(binary);\n}\n\nfunction base64Decode(b64: string): Uint8Array {\n const binary = atob(b64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes;\n}\n\n/** Parse a key string (hex 64 chars or base64 44 chars) into 32 raw bytes. */\nfunction parseKeyBytes(key: string): Uint8Array {\n const trimmed = key.trim();\n if (trimmed.length === 64 && HEX_RE.test(trimmed)) {\n return hexToBytes(trimmed);\n }\n return base64Decode(trimmed);\n}\n\nexport async function deriveKey(encryptionKey: string): Promise<CryptoKey> {\n const keyData = parseKeyBytes(encryptionKey);\n if (keyData.length !== 32) {\n throw new Error(\n `Invalid key length: expected 32 bytes, got ${keyData.length}`,\n );\n }\n return crypto.subtle.importKey(\n \"raw\",\n keyData.buffer as ArrayBuffer,\n \"AES-GCM\",\n false,\n [\"encrypt\", \"decrypt\"],\n );\n}\n\nexport async function encrypt(\n plaintext: string,\n key: CryptoKey,\n): Promise<{ data: string; nonce: string }> {\n const iv = crypto.getRandomValues(new Uint8Array(12));\n const encoded = new TextEncoder().encode(plaintext);\n const ciphertext = await crypto.subtle.encrypt(\n { name: \"AES-GCM\", iv: iv as BufferSource },\n key,\n encoded,\n );\n return {\n data: base64Encode(new Uint8Array(ciphertext)),\n nonce: base64Encode(iv),\n };\n}\n\nexport async function decrypt(\n data: string,\n nonce: string,\n key: CryptoKey,\n): Promise<string> {\n const ciphertext = base64Decode(data);\n const iv = base64Decode(nonce);\n const plaintext = await crypto.subtle.decrypt(\n { name: \"AES-GCM\", iv: iv as BufferSource },\n key,\n ciphertext.buffer as ArrayBuffer,\n );\n return new TextDecoder().decode(plaintext);\n}\n",
7
+ "import type { TaskbookConfig } from \"../config.js\";\nimport { decrypt, deriveKey, encrypt } from \"./crypto.js\";\n\n// --- Domain types ---\n\nexport interface Task {\n _id: number;\n _date: string;\n _timestamp: number;\n _isTask: true;\n description: string;\n isStarred: boolean;\n isComplete: boolean;\n inProgress: boolean;\n priority: number;\n boards: string[];\n tags: string[];\n}\n\nexport interface Note {\n _id: number;\n _date: string;\n _timestamp: number;\n _isTask: false;\n description: string;\n body?: string;\n isStarred: boolean;\n boards: string[];\n tags: string[];\n}\n\nexport type StorageItem = Task | Note;\n\nexport interface EncryptedItem {\n data: string;\n nonce: string;\n}\n\ninterface ItemsResponse {\n items: Record<string, EncryptedItem>;\n}\n\ninterface HealthResponse {\n status: string;\n message?: string;\n}\n\ninterface MeResponse {\n username: string;\n email: string;\n}\n\n// --- API Client ---\n\nexport class TaskbookClient {\n private baseUrl: string;\n private token: string;\n private cryptoKey: CryptoKey | null = null;\n private encryptionKeyRaw: string;\n\n constructor(config: TaskbookConfig) {\n this.baseUrl = config.serverUrl.replace(/\\/+$/, \"\");\n this.token = config.token;\n this.encryptionKeyRaw = config.encryptionKey;\n }\n\n private async getKey(): Promise<CryptoKey> {\n if (!this.cryptoKey) {\n this.cryptoKey = await deriveKey(this.encryptionKeyRaw);\n }\n return this.cryptoKey;\n }\n\n private async request<T>(\n method: string,\n path: string,\n body?: unknown,\n ): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n const headers: Record<string, string> = {\n Authorization: `Bearer ${this.token}`,\n \"Content-Type\": \"application/json\",\n };\n\n const resp = await fetch(url, {\n method,\n headers,\n body: body ? JSON.stringify(body) : undefined,\n });\n\n if (!resp.ok) {\n const text = await resp.text();\n throw new Error(`Taskbook API ${method} ${path}: ${resp.status} ${text}`);\n }\n\n const contentType = resp.headers.get(\"content-type\") ?? \"\";\n if (contentType.includes(\"application/json\")) {\n return (await resp.json()) as T;\n }\n return {} as T;\n }\n\n // --- Decryption helpers ---\n\n private async decryptItems(\n encrypted: Record<string, EncryptedItem>,\n ): Promise<Record<string, StorageItem>> {\n const key = await this.getKey();\n const result: Record<string, StorageItem> = {};\n\n for (const [id, item] of Object.entries(encrypted)) {\n try {\n const json = await decrypt(item.data, item.nonce, key);\n result[id] = JSON.parse(json) as StorageItem;\n } catch {\n // Skip items that fail decryption (wrong key, corrupted data)\n }\n }\n return result;\n }\n\n private async encryptItem(\n item: StorageItem,\n ): Promise<EncryptedItem> {\n const key = await this.getKey();\n return encrypt(JSON.stringify(item), key);\n }\n\n // --- Public API ---\n\n async health(): Promise<HealthResponse> {\n return this.request<HealthResponse>(\"GET\", \"/api/v1/health\");\n }\n\n async me(): Promise<MeResponse> {\n return this.request<MeResponse>(\"GET\", \"/api/v1/me\");\n }\n\n async getItems(): Promise<Record<string, StorageItem>> {\n const resp = await this.request<ItemsResponse>(\"GET\", \"/api/v1/items\");\n return this.decryptItems(resp.items);\n }\n\n async getArchive(): Promise<Record<string, StorageItem>> {\n const resp = await this.request<ItemsResponse>(\n \"GET\",\n \"/api/v1/items/archive\",\n );\n return this.decryptItems(resp.items);\n }\n\n async putItems(items: Record<string, StorageItem>): Promise<void> {\n const encrypted: Record<string, EncryptedItem> = {};\n for (const [id, item] of Object.entries(items)) {\n encrypted[id] = await this.encryptItem(item);\n }\n await this.request(\"PUT\", \"/api/v1/items\", { items: encrypted });\n }\n\n async putArchive(items: Record<string, StorageItem>): Promise<void> {\n const encrypted: Record<string, EncryptedItem> = {};\n for (const [id, item] of Object.entries(items)) {\n encrypted[id] = await this.encryptItem(item);\n }\n await this.request(\"PUT\", \"/api/v1/items/archive\", { items: encrypted });\n }\n\n // --- High-level operations ---\n\n async listTasks(board?: string): Promise<Task[]> {\n const items = await this.getItems();\n const tasks = Object.values(items).filter(\n (i): i is Task => i._isTask,\n );\n if (board) {\n return tasks.filter((t) => t.boards.includes(board));\n }\n return tasks;\n }\n\n async listNotes(board?: string): Promise<Note[]> {\n const items = await this.getItems();\n const notes = Object.values(items).filter(\n (i): i is Note => !i._isTask,\n );\n if (board) {\n return notes.filter((n) => n.boards.includes(board));\n }\n return notes;\n }\n\n async listBoards(): Promise<string[]> {\n const items = await this.getItems();\n const boardSet = new Set<string>();\n for (const item of Object.values(items)) {\n for (const b of item.boards) boardSet.add(b);\n }\n return [...boardSet].sort();\n }\n\n async createTask(\n description: string,\n board: string = \"My Board\",\n priority: number = 1,\n tags: string[] = [],\n ): Promise<Task> {\n const items = await this.getItems();\n const maxId = Math.max(0, ...Object.values(items).map((i) => i._id));\n const now = new Date();\n const task: Task = {\n _id: maxId + 1,\n _date: now.toDateString().slice(0, 10),\n _timestamp: now.getTime(),\n _isTask: true,\n description,\n isStarred: false,\n isComplete: false,\n inProgress: false,\n priority: Math.min(3, Math.max(1, priority)),\n boards: [board.replace(/^@+/, \"\")],\n tags: tags.map((t) => t.replace(/^\\++/, \"\").toLowerCase()),\n };\n items[String(task._id)] = task;\n await this.putItems(items);\n return task;\n }\n\n async createNote(\n description: string,\n board: string = \"My Board\",\n body?: string,\n tags: string[] = [],\n ): Promise<Note> {\n const items = await this.getItems();\n const maxId = Math.max(0, ...Object.values(items).map((i) => i._id));\n const now = new Date();\n const note: Note = {\n _id: maxId + 1,\n _date: now.toDateString().slice(0, 10),\n _timestamp: now.getTime(),\n _isTask: false,\n description,\n body,\n isStarred: false,\n boards: [board.replace(/^@+/, \"\")],\n tags: tags.map((t) => t.replace(/^\\++/, \"\").toLowerCase()),\n };\n items[String(note._id)] = note;\n await this.putItems(items);\n return note;\n }\n\n async completeTask(taskId: number): Promise<Task> {\n const items = await this.getItems();\n const item = items[String(taskId)];\n if (!item || !item._isTask) {\n throw new Error(`Task ${taskId} not found`);\n }\n const task = item as Task;\n task.isComplete = !task.isComplete;\n task.inProgress = false;\n items[String(taskId)] = task;\n await this.putItems(items);\n return task;\n }\n\n async beginTask(taskId: number): Promise<Task> {\n const items = await this.getItems();\n const item = items[String(taskId)];\n if (!item || !item._isTask) {\n throw new Error(`Task ${taskId} not found`);\n }\n const task = item as Task;\n task.inProgress = !task.inProgress;\n items[String(taskId)] = task;\n await this.putItems(items);\n return task;\n }\n\n async starItem(itemId: number): Promise<StorageItem> {\n const items = await this.getItems();\n const item = items[String(itemId)];\n if (!item) throw new Error(`Item ${itemId} not found`);\n item.isStarred = !item.isStarred;\n items[String(itemId)] = item;\n await this.putItems(items);\n return item;\n }\n\n async deleteItem(itemId: number): Promise<void> {\n const items = await this.getItems();\n if (!items[String(itemId)]) {\n throw new Error(`Item ${itemId} not found`);\n }\n delete items[String(itemId)];\n await this.putItems(items);\n }\n\n async archiveItem(itemId: number): Promise<void> {\n const items = await this.getItems();\n const item = items[String(itemId)];\n if (!item) throw new Error(`Item ${itemId} not found`);\n\n delete items[String(itemId)];\n const archive = await this.getArchive();\n archive[String(itemId)] = item;\n\n await this.putItems(items);\n await this.putArchive(archive);\n }\n\n async moveToBoard(itemId: number, targetBoard: string): Promise<StorageItem> {\n const items = await this.getItems();\n const item = items[String(itemId)];\n if (!item) throw new Error(`Item ${itemId} not found`);\n item.boards = [targetBoard.replace(/^@+/, \"\")];\n items[String(itemId)] = item;\n await this.putItems(items);\n return item;\n }\n\n async editItem(\n itemId: number,\n description: string,\n ): Promise<StorageItem> {\n const items = await this.getItems();\n const item = items[String(itemId)];\n if (!item) throw new Error(`Item ${itemId} not found`);\n item.description = description;\n items[String(itemId)] = item;\n await this.putItems(items);\n return item;\n }\n\n async searchItems(query: string): Promise<StorageItem[]> {\n const items = await this.getItems();\n const lower = query.toLowerCase();\n return Object.values(items).filter(\n (item) =>\n item.description.toLowerCase().includes(lower) ||\n item.tags.some((t) => t.includes(lower)) ||\n item.boards.some((b) => b.toLowerCase().includes(lower)),\n );\n }\n}\n",
8
+ "import { readFileSync, existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\n\nexport interface TaskbookConfig {\n serverUrl: string;\n token: string;\n encryptionKey: string;\n}\n\nexport interface McpServerConfig {\n taskbook: TaskbookConfig;\n port: number;\n host: string;\n transport: \"stdio\" | \"http\";\n}\n\ninterface TaskbookJsonFile {\n sync?: {\n server_url?: string;\n token?: string;\n };\n encryption_key?: string;\n}\n\n/**\n * Load taskbook config from ~/.taskbook.json (same file the CLI uses).\n * Falls back to environment variables.\n */\nexport function loadTaskbookConfig(): TaskbookConfig {\n const envUrl = process.env.TB_SERVER_URL;\n const envToken = process.env.TB_TOKEN;\n const envKey = process.env.TB_ENCRYPTION_KEY;\n\n if (envUrl && envToken && envKey) {\n return { serverUrl: envUrl, token: envToken, encryptionKey: envKey };\n }\n\n const configPath =\n process.env.TB_CONFIG_PATH ?? join(homedir(), \".taskbook.json\");\n\n if (!existsSync(configPath)) {\n throw new Error(\n `Taskbook config not found at ${configPath}. ` +\n \"Run 'tb --login' or set TB_SERVER_URL, TB_TOKEN, TB_ENCRYPTION_KEY env vars.\",\n );\n }\n\n const raw = readFileSync(configPath, \"utf-8\");\n const config: TaskbookJsonFile = JSON.parse(raw);\n\n const serverUrl = envUrl ?? config.sync?.server_url;\n const token = envToken ?? config.sync?.token;\n const encryptionKey = envKey ?? config.encryption_key;\n\n if (!serverUrl) throw new Error(\"Missing server URL in taskbook config\");\n if (!token) throw new Error(\"Missing auth token in taskbook config\");\n if (!encryptionKey)\n throw new Error(\"Missing encryption key in taskbook config\");\n\n return { serverUrl, token, encryptionKey };\n}\n\nexport function loadMcpConfig(): Omit<McpServerConfig, \"taskbook\"> & {\n taskbook?: TaskbookConfig;\n} {\n const transport =\n (process.env.TB_MCP_TRANSPORT as \"stdio\" | \"http\") ?? \"stdio\";\n const port = Number.parseInt(process.env.TB_MCP_PORT ?? \"3100\", 10);\n const host = process.env.TB_MCP_HOST ?? \"127.0.0.1\";\n\n return { port, host, transport };\n}\n",
9
+ "import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { TaskbookClient } from \"./client/api.js\";\nimport { registerTaskTools } from \"./tools/tasks.js\";\nimport { registerNoteTools } from \"./tools/notes.js\";\nimport { registerBoardTools } from \"./tools/boards.js\";\nimport { registerGeneralTools } from \"./tools/general.js\";\nimport { registerResources } from \"./resources/index.js\";\n\nexport const SERVER_NAME = \"taskbook-mcp\";\nexport const SERVER_VERSION = \"1.0.0\";\n\n/**\n * Create a fully configured MCP server with all tools and resources.\n * The `getClient` callback is called per-request so that different\n * transports can provide per-session TaskbookClient instances.\n */\nexport function createMcpServer(\n getClient: () => TaskbookClient,\n): McpServer {\n const server = new McpServer(\n {\n name: SERVER_NAME,\n version: SERVER_VERSION,\n },\n {\n capabilities: {\n logging: {},\n },\n },\n );\n\n registerTaskTools(server, getClient);\n registerNoteTools(server, getClient);\n registerBoardTools(server, getClient);\n registerGeneralTools(server, getClient);\n registerResources(server, getClient);\n\n return server;\n}\n",
10
+ "import { z } from \"zod\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { TaskbookClient, Task } from \"../client/api.js\";\n\nfunction formatTask(t: Task): string {\n const status = t.isComplete ? \"✔\" : t.inProgress ? \"…\" : \"☐\";\n const star = t.isStarred ? \"★ \" : \"\";\n const pri = t.priority > 1 ? ` [P${t.priority}]` : \"\";\n const tags = t.tags.length > 0 ? ` +${t.tags.join(\" +\")}` : \"\";\n const boards = t.boards.map((b) => `@${b}`).join(\" \");\n return `${status} ${t._id}. ${star}${t.description}${pri}${tags} (${boards})`;\n}\n\nexport function registerTaskTools(\n server: McpServer,\n getClient: () => TaskbookClient,\n) {\n server.tool(\n \"list_tasks\",\n \"List all tasks, optionally filtered by board name\",\n { board: z.string().optional().describe(\"Board name to filter by\") },\n async ({ board }) => {\n const tasks = await getClient().listTasks(board);\n if (tasks.length === 0) {\n return {\n content: [\n {\n type: \"text\",\n text: board\n ? `No tasks found on board @${board}.`\n : \"No tasks found.\",\n },\n ],\n };\n }\n const pending = tasks.filter((t) => !t.isComplete);\n const done = tasks.filter((t) => t.isComplete);\n const lines = [\n `**Tasks** (${pending.length} pending, ${done.length} done)`,\n \"\",\n ...pending.map(formatTask),\n ...(done.length > 0 ? [\"\", \"--- Completed ---\", ...done.map(formatTask)] : []),\n ];\n return { content: [{ type: \"text\", text: lines.join(\"\\n\") }] };\n },\n );\n\n server.tool(\n \"create_task\",\n \"Create a new task on a board\",\n {\n description: z.string().describe(\"Task description\"),\n board: z.string().optional().describe(\"Board name (default: My Board)\"),\n priority: z\n .number()\n .min(1)\n .max(3)\n .optional()\n .describe(\"Priority 1-3 (1=normal, 2=medium, 3=high)\"),\n tags: z\n .array(z.string())\n .optional()\n .describe(\"Tags to attach to the task\"),\n },\n async ({ description, board, priority, tags }) => {\n const task = await getClient().createTask(\n description,\n board ?? \"My Board\",\n priority ?? 1,\n tags ?? [],\n );\n return {\n content: [\n {\n type: \"text\",\n text: `Created task #${task._id}: ${task.description} on @${task.boards[0]}`,\n },\n ],\n };\n },\n );\n\n server.tool(\n \"complete_task\",\n \"Toggle a task's completion status\",\n {\n task_id: z.number().describe(\"The task ID number\"),\n },\n async ({ task_id }) => {\n const task = await getClient().completeTask(task_id);\n const status = task.isComplete ? \"completed\" : \"uncompleted\";\n return {\n content: [\n {\n type: \"text\",\n text: `Task #${task._id} marked as ${status}: ${task.description}`,\n },\n ],\n };\n },\n );\n\n server.tool(\n \"begin_task\",\n \"Toggle a task's in-progress status\",\n {\n task_id: z.number().describe(\"The task ID number\"),\n },\n async ({ task_id }) => {\n const task = await getClient().beginTask(task_id);\n const status = task.inProgress ? \"in-progress\" : \"paused\";\n return {\n content: [\n {\n type: \"text\",\n text: `Task #${task._id} marked as ${status}: ${task.description}`,\n },\n ],\n };\n },\n );\n\n server.tool(\n \"set_task_priority\",\n \"Set a task's priority level (1=normal, 2=medium, 3=high)\",\n {\n task_id: z.number().describe(\"The task ID number\"),\n priority: z.number().min(1).max(3).describe(\"Priority level 1-3\"),\n },\n async ({ task_id, priority }) => {\n const client = getClient();\n const items = await client.getItems();\n const item = items[String(task_id)];\n if (!item || !item._isTask) throw new Error(`Task ${task_id} not found`);\n (item as Task).priority = priority;\n items[String(task_id)] = item;\n await client.putItems(items);\n return {\n content: [\n {\n type: \"text\",\n text: `Task #${task_id} priority set to P${priority}`,\n },\n ],\n };\n },\n );\n}\n",
11
+ "import { z } from \"zod\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { TaskbookClient, Note } from \"../client/api.js\";\n\nfunction formatNote(n: Note): string {\n const star = n.isStarred ? \"★ \" : \"\";\n const tags = n.tags.length > 0 ? ` +${n.tags.join(\" +\")}` : \"\";\n const boards = n.boards.map((b) => `@${b}`).join(\" \");\n const body = n.body ? `\\n ${n.body}` : \"\";\n return `📝 ${n._id}. ${star}${n.description}${tags} (${boards})${body}`;\n}\n\nexport function registerNoteTools(\n server: McpServer,\n getClient: () => TaskbookClient,\n) {\n server.tool(\n \"list_notes\",\n \"List all notes, optionally filtered by board\",\n { board: z.string().optional().describe(\"Board name to filter by\") },\n async ({ board }) => {\n const notes = await getClient().listNotes(board);\n if (notes.length === 0) {\n return {\n content: [\n {\n type: \"text\",\n text: board\n ? `No notes found on board @${board}.`\n : \"No notes found.\",\n },\n ],\n };\n }\n const lines = [\n `**Notes** (${notes.length})`,\n \"\",\n ...notes.map(formatNote),\n ];\n return { content: [{ type: \"text\", text: lines.join(\"\\n\") }] };\n },\n );\n\n server.tool(\n \"create_note\",\n \"Create a new note on a board\",\n {\n description: z.string().describe(\"Note title/description\"),\n board: z.string().optional().describe(\"Board name (default: My Board)\"),\n body: z.string().optional().describe(\"Note body content\"),\n tags: z\n .array(z.string())\n .optional()\n .describe(\"Tags to attach to the note\"),\n },\n async ({ description, board, body, tags }) => {\n const note = await getClient().createNote(\n description,\n board ?? \"My Board\",\n body,\n tags ?? [],\n );\n return {\n content: [\n {\n type: \"text\",\n text: `Created note #${note._id}: ${note.description} on @${note.boards[0]}`,\n },\n ],\n };\n },\n );\n}\n",
12
+ "import { z } from \"zod\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { TaskbookClient } from \"../client/api.js\";\n\nexport function registerBoardTools(\n server: McpServer,\n getClient: () => TaskbookClient,\n) {\n server.tool(\n \"list_boards\",\n \"List all boards with item counts\",\n {},\n async () => {\n const items = await getClient().getItems();\n const boardCounts = new Map<string, { tasks: number; notes: number }>();\n\n for (const item of Object.values(items)) {\n for (const board of item.boards) {\n const counts = boardCounts.get(board) ?? { tasks: 0, notes: 0 };\n if (item._isTask) counts.tasks++;\n else counts.notes++;\n boardCounts.set(board, counts);\n }\n }\n\n if (boardCounts.size === 0) {\n return {\n content: [{ type: \"text\", text: \"No boards found.\" }],\n };\n }\n\n const lines = [\n \"**Boards**\",\n \"\",\n ...[...boardCounts.entries()]\n .sort(([a], [b]) => a.localeCompare(b))\n .map(\n ([name, counts]) =>\n `📋 @${name} (${counts.tasks} tasks, ${counts.notes} notes)`,\n ),\n ];\n return { content: [{ type: \"text\", text: lines.join(\"\\n\") }] };\n },\n );\n\n server.tool(\n \"move_item\",\n \"Move a task or note to a different board\",\n {\n item_id: z.number().describe(\"The item ID to move\"),\n target_board: z.string().describe(\"The target board name\"),\n },\n async ({ item_id, target_board }) => {\n const item = await getClient().moveToBoard(item_id, target_board);\n return {\n content: [\n {\n type: \"text\",\n text: `Moved item #${item._id} to @${item.boards[0]}`,\n },\n ],\n };\n },\n );\n}\n",
13
+ "import { z } from \"zod\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { TaskbookClient } from \"../client/api.js\";\n\nexport function registerGeneralTools(\n server: McpServer,\n getClient: () => TaskbookClient,\n) {\n server.tool(\n \"search_items\",\n \"Search tasks and notes by description, tag, or board name\",\n {\n query: z.string().describe(\"Search query text\"),\n },\n async ({ query }) => {\n const results = await getClient().searchItems(query);\n if (results.length === 0) {\n return {\n content: [\n { type: \"text\", text: `No items matching \"${query}\".` },\n ],\n };\n }\n const lines = results.map((item) => {\n const type = item._isTask ? (item.isComplete ? \"✔\" : \"☐\") : \"📝\";\n return `${type} ${item._id}. ${item.description} (@${item.boards.join(\", @\")})`;\n });\n return {\n content: [\n {\n type: \"text\",\n text: [`**Search results for \"${query}\"** (${results.length})`, \"\", ...lines].join(\"\\n\"),\n },\n ],\n };\n },\n );\n\n server.tool(\n \"edit_item\",\n \"Edit an item's description\",\n {\n item_id: z.number().describe(\"The item ID to edit\"),\n description: z.string().describe(\"New description text\"),\n },\n async ({ item_id, description }) => {\n const item = await getClient().editItem(item_id, description);\n return {\n content: [\n {\n type: \"text\",\n text: `Updated item #${item._id}: ${item.description}`,\n },\n ],\n };\n },\n );\n\n server.tool(\n \"delete_item\",\n \"Permanently delete a task or note\",\n {\n item_id: z.number().describe(\"The item ID to delete\"),\n },\n async ({ item_id }) => {\n await getClient().deleteItem(item_id);\n return {\n content: [{ type: \"text\", text: `Deleted item #${item_id}` }],\n };\n },\n );\n\n server.tool(\n \"archive_item\",\n \"Move an item to the archive\",\n {\n item_id: z.number().describe(\"The item ID to archive\"),\n },\n async ({ item_id }) => {\n await getClient().archiveItem(item_id);\n return {\n content: [{ type: \"text\", text: `Archived item #${item_id}` }],\n };\n },\n );\n\n server.tool(\n \"star_item\",\n \"Toggle the star/bookmark on a task or note\",\n {\n item_id: z.number().describe(\"The item ID to star/unstar\"),\n },\n async ({ item_id }) => {\n const item = await getClient().starItem(item_id);\n const status = item.isStarred ? \"starred\" : \"unstarred\";\n return {\n content: [\n {\n type: \"text\",\n text: `Item #${item._id} ${status}: ${item.description}`,\n },\n ],\n };\n },\n );\n\n server.tool(\n \"get_status\",\n \"Check taskbook server health and current user info\",\n {},\n async () => {\n const client = getClient();\n const [health, me] = await Promise.all([client.health(), client.me()]);\n const items = await client.getItems();\n const tasks = Object.values(items).filter((i) => i._isTask);\n const done = tasks.filter((t) => t._isTask && t.isComplete).length;\n const pending = tasks.length - done;\n const notes = Object.values(items).filter((i) => !i._isTask).length;\n const boards = await client.listBoards();\n\n const lines = [\n `**Taskbook Status**`,\n `Server: ${health.status}`,\n `User: ${me.username} (${me.email})`,\n `Boards: ${boards.length} (${boards.map((b) => `@${b}`).join(\", \")})`,\n `Tasks: ${tasks.length} total (${done} done, ${pending} pending)`,\n `Notes: ${notes}`,\n ];\n return { content: [{ type: \"text\", text: lines.join(\"\\n\") }] };\n },\n );\n}\n",
14
+ "import { ResourceTemplate } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { ReadResourceResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport type { TaskbookClient } from \"../client/api.js\";\n\nexport function registerResources(\n server: McpServer,\n getClient: () => TaskbookClient,\n) {\n // Static resource: server status\n server.resource(\n \"status\",\n \"taskbook://status\",\n { description: \"Taskbook server status and user info\", mimeType: \"application/json\" },\n async (uri): Promise<ReadResourceResult> => {\n const client = getClient();\n const [health, me] = await Promise.all([client.health(), client.me()]);\n return {\n contents: [\n {\n uri: uri.href,\n text: JSON.stringify({ health, user: me }, null, 2),\n },\n ],\n };\n },\n );\n\n // Dynamic resource: board contents\n server.resource(\n \"board\",\n new ResourceTemplate(\"taskbook://boards/{boardName}\", {\n list: async () => {\n const boards = await getClient().listBoards();\n return {\n resources: boards.map((b) => ({\n uri: `taskbook://boards/${encodeURIComponent(b)}`,\n name: `@${b}`,\n description: `Tasks and notes on board @${b}`,\n })),\n };\n },\n }),\n { description: \"Tasks and notes on a specific board\", mimeType: \"application/json\" },\n async (uri, { boardName }): Promise<ReadResourceResult> => {\n const board = decodeURIComponent(boardName as string);\n const client = getClient();\n const [tasks, notes] = await Promise.all([\n client.listTasks(board),\n client.listNotes(board),\n ]);\n return {\n contents: [\n {\n uri: uri.href,\n text: JSON.stringify({ board, tasks, notes }, null, 2),\n },\n ],\n };\n },\n );\n\n // Static resource: all items (overview)\n server.resource(\n \"all-items\",\n \"taskbook://items\",\n { description: \"All tasks and notes across all boards\", mimeType: \"application/json\" },\n async (uri): Promise<ReadResourceResult> => {\n const items = await getClient().getItems();\n return {\n contents: [\n {\n uri: uri.href,\n text: JSON.stringify(Object.values(items), null, 2),\n },\n ],\n };\n },\n );\n\n // Static resource: archive\n server.resource(\n \"archive\",\n \"taskbook://archive\",\n { description: \"Archived tasks and notes\", mimeType: \"application/json\" },\n async (uri): Promise<ReadResourceResult> => {\n const archive = await getClient().getArchive();\n return {\n contents: [\n {\n uri: uri.href,\n text: JSON.stringify(Object.values(archive), null, 2),\n },\n ],\n };\n },\n );\n}\n",
15
+ "import { randomUUID } from \"node:crypto\";\nimport { WebStandardStreamableHTTPServerTransport } from \"@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js\";\nimport { isInitializeRequest } from \"@modelcontextprotocol/sdk/types.js\";\nimport { TaskbookClient } from \"../client/api.js\";\nimport { loadTaskbookConfig } from \"../config.js\";\nimport { createMcpServer, SERVER_NAME, SERVER_VERSION } from \"../server.js\";\nimport type { McpServerConfig } from \"../config.js\";\n\n// Accept just transport-level config\ntype HttpConfig = Pick<McpServerConfig, \"port\" | \"host\">;\n\ninterface SessionInfo {\n transport: WebStandardStreamableHTTPServerTransport;\n client: TaskbookClient;\n}\n\n/**\n * Start the MCP server with HTTP Streamable transport (Web Standard API).\n * Supports concurrent clients with session management.\n * Each session gets its own TaskbookClient instance.\n *\n * Authentication: Optionally validates a Bearer token via TB_MCP_ACCESS_TOKEN.\n * For OIDC, clients obtain a token from the identity provider and pass it\n * as the taskbook API token in env or config.\n */\nexport async function startHttpTransport(config: HttpConfig): Promise<void> {\n const sessions = new Map<string, SessionInfo>();\n\n const { port, host } = config;\n\n const requiredToken = process.env.TB_MCP_ACCESS_TOKEN;\n\n function verifyAuth(req: Request): boolean {\n if (!requiredToken) return true;\n const auth = req.headers.get(\"authorization\");\n if (!auth) return false;\n const [scheme, token] = auth.split(\" \", 2);\n return scheme?.toLowerCase() === \"bearer\" && token === requiredToken;\n }\n\n function corsHeaders(): Record<string, string> {\n return {\n \"Access-Control-Allow-Origin\": \"*\",\n \"Access-Control-Allow-Methods\": \"GET, POST, DELETE, OPTIONS\",\n \"Access-Control-Allow-Headers\":\n \"Content-Type, Authorization, mcp-session-id, MCP-Protocol-Version\",\n \"Access-Control-Expose-Headers\": \"mcp-session-id\",\n };\n }\n\n Bun.serve({\n port,\n hostname: host,\n async fetch(req): Promise<Response> {\n const url = new URL(req.url);\n\n // Health check\n if (url.pathname === \"/health\") {\n return Response.json({\n status: \"ok\",\n server: SERVER_NAME,\n version: SERVER_VERSION,\n });\n }\n\n if (url.pathname !== \"/mcp\") {\n return new Response(\"Not Found\", { status: 404 });\n }\n\n if (req.method === \"OPTIONS\") {\n return new Response(null, { status: 204, headers: corsHeaders() });\n }\n\n if (!verifyAuth(req)) {\n return Response.json(\n {\n jsonrpc: \"2.0\",\n error: { code: -32001, message: \"Unauthorized\" },\n id: null,\n },\n { status: 401, headers: corsHeaders() },\n );\n }\n\n if (req.method === \"POST\") {\n const sessionId = req.headers.get(\"mcp-session-id\");\n\n // Existing session\n if (sessionId && sessions.has(sessionId)) {\n const session = sessions.get(sessionId)!;\n return session.transport.handleRequest(req);\n }\n\n // New session — parse body to check for initialize request\n const body = await req.json();\n if (isInitializeRequest(body)) {\n const tbConfig = loadTaskbookConfig();\n const client = new TaskbookClient(tbConfig);\n\n const transport = new WebStandardStreamableHTTPServerTransport({\n sessionIdGenerator: () => randomUUID(),\n onsessioninitialized: (id) => {\n sessions.set(id, { transport, client });\n console.log(`[taskbook-mcp] HTTP session created: ${id}`);\n },\n });\n\n transport.onclose = () => {\n if (transport.sessionId) {\n sessions.delete(transport.sessionId);\n console.log(\n `[taskbook-mcp] HTTP session closed: ${transport.sessionId}`,\n );\n }\n };\n\n const mcpServer = createMcpServer(() => client);\n await mcpServer.connect(transport);\n return transport.handleRequest(req, { parsedBody: body });\n }\n\n return Response.json(\n {\n jsonrpc: \"2.0\",\n error: { code: -32000, message: \"Invalid or missing session\" },\n id: null,\n },\n { status: 400, headers: corsHeaders() },\n );\n }\n\n if (req.method === \"GET\") {\n const sessionId = req.headers.get(\"mcp-session-id\");\n if (sessionId && sessions.has(sessionId)) {\n return sessions.get(sessionId)!.transport.handleRequest(req);\n }\n return new Response(\"Invalid session\", {\n status: 400,\n headers: corsHeaders(),\n });\n }\n\n if (req.method === \"DELETE\") {\n const sessionId = req.headers.get(\"mcp-session-id\");\n if (sessionId && sessions.has(sessionId)) {\n const session = sessions.get(sessionId)!;\n await session.transport.close();\n sessions.delete(sessionId);\n return new Response(null, { status: 204, headers: corsHeaders() });\n }\n return new Response(\"Invalid session\", {\n status: 400,\n headers: corsHeaders(),\n });\n }\n\n return new Response(\"Method Not Allowed\", { status: 405 });\n },\n });\n\n console.log(\n `[taskbook-mcp] HTTP transport listening on http://${host}:${port}/mcp`,\n );\n console.log(\n `[taskbook-mcp] Health check: http://${host}:${port}/health`,\n );\n}\n",
16
+ "#!/usr/bin/env bun\n/**\n * Taskbook MCP Server — Model Context Protocol server for Taskbook\n *\n * Exposes task management tools (create, complete, delete, search, etc.)\n * and resources (boards, items, archive) to LLM clients via MCP.\n *\n * Transports:\n * stdio — single client, reads config from ~/.taskbook.json\n * http — multi-client with session management, Streamable HTTP\n *\n * Usage:\n * bun run src/index.ts # stdio (default)\n * TB_MCP_TRANSPORT=http bun run src/index.ts # HTTP on port 3100\n * TB_MCP_TRANSPORT=http TB_MCP_PORT=8080 bun run src/index.ts\n */\n\nimport { startStdioTransport } from \"./transport/stdio.js\";\nimport { startHttpTransport } from \"./transport/http.js\";\nimport { loadMcpConfig } from \"./config.js\";\n\nasync function main() {\n const args = process.argv.slice(2);\n\n // CLI argument override: --transport=http|stdio\n let transportOverride: string | undefined;\n for (const arg of args) {\n if (arg.startsWith(\"--transport=\")) {\n transportOverride = arg.split(\"=\")[1];\n }\n if (arg === \"--help\" || arg === \"-h\") {\n console.log(`Taskbook MCP Server\n\nUsage:\n taskbook-mcp [--transport=stdio|http] [--port=PORT] [--host=HOST]\n\nEnvironment variables:\n TB_MCP_TRANSPORT Transport type: stdio (default) or http\n TB_MCP_PORT HTTP port (default: 3100)\n TB_MCP_HOST HTTP bind address (default: 127.0.0.1)\n TB_MCP_ACCESS_TOKEN Optional: require this token for HTTP connections\n TB_SERVER_URL Taskbook server URL (overrides ~/.taskbook.json)\n TB_TOKEN Taskbook session token (overrides ~/.taskbook.json)\n TB_ENCRYPTION_KEY Encryption key (overrides ~/.taskbook.json)\n TB_CONFIG_PATH Path to taskbook config (default: ~/.taskbook.json)\n`);\n process.exit(0);\n }\n }\n\n if (transportOverride) {\n process.env.TB_MCP_TRANSPORT = transportOverride;\n }\n for (const arg of args) {\n if (arg.startsWith(\"--port=\")) {\n process.env.TB_MCP_PORT = arg.split(\"=\")[1];\n }\n if (arg.startsWith(\"--host=\")) {\n process.env.TB_MCP_HOST = arg.split(\"=\")[1];\n }\n }\n\n const config = loadMcpConfig();\n\n if (config.transport === \"http\") {\n await startHttpTransport(config);\n } else {\n await startStdioTransport();\n }\n}\n\nmain().catch((err) => {\n console.error(\"[taskbook-mcp] Fatal error:\", err.message ?? err);\n process.exit(1);\n});\n"
17
+ ],
18
+ "mappings": "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",
19
+ "debugId": "A2D3326EC19207DD64756E2164756E21",
20
+ "names": []
21
+ }
package/package.json ADDED
@@ -0,0 +1,65 @@
1
+ {
2
+ "name": "@tobiashochguertel/taskbook-mcp-server",
3
+ "version": "1.9.0",
4
+ "description": "MCP (Model Context Protocol) server for Taskbook — exposes task management tools and resources to LLM clients",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "taskbook-mcp": "dist/index.js"
9
+ },
10
+ "scripts": {
11
+ "build": "bun build src/index.ts --outdir dist --target bun --sourcemap",
12
+ "build:npm": "bun build src/index.ts --outdir dist --target bun --packages external --sourcemap",
13
+ "build:standalone": "bun build src/index.ts --compile --outfile dist/taskbook-mcp",
14
+ "dev": "bun run --watch src/index.ts",
15
+ "test": "bun test",
16
+ "typecheck": "tsc --noEmit",
17
+ "lint": "bunx biome check src/ tests/",
18
+ "clean": "rm -rf dist",
19
+ "prepublishOnly": "bun run build:npm"
20
+ },
21
+ "dependencies": {
22
+ "@modelcontextprotocol/sdk": "^1.14.0",
23
+ "zod": "^3.25.67"
24
+ },
25
+ "devDependencies": {
26
+ "@types/bun": "latest",
27
+ "typescript": "^5.8.3"
28
+ },
29
+ "files": [
30
+ "dist/index.js",
31
+ "dist/index.js.map",
32
+ "README.md",
33
+ "LICENSE"
34
+ ],
35
+ "repository": {
36
+ "type": "git",
37
+ "url": "https://github.com/tobiashochguertel/taskbook.git",
38
+ "directory": "packages/taskbook-mcp-server"
39
+ },
40
+ "homepage": "https://github.com/tobiashochguertel/taskbook/tree/master/packages/taskbook-mcp-server",
41
+ "bugs": {
42
+ "url": "https://github.com/tobiashochguertel/taskbook/issues"
43
+ },
44
+ "author": "Tobias Hochgürtel <tobias.hochguertel@googlemail.com>",
45
+ "license": "MIT",
46
+ "keywords": [
47
+ "mcp",
48
+ "model-context-protocol",
49
+ "taskbook",
50
+ "task-management",
51
+ "ai",
52
+ "llm",
53
+ "copilot",
54
+ "claude",
55
+ "cursor"
56
+ ],
57
+ "engines": {
58
+ "node": ">=18.0.0",
59
+ "bun": ">=1.0.0"
60
+ },
61
+ "publishConfig": {
62
+ "access": "public",
63
+ "registry": "https://registry.npmjs.org/"
64
+ }
65
+ }