Skip to main content
Glama

Kanban MCP Server

by 0Thomas1
index.ts5.36 kB
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { z } from "zod"; import * as mongooseUtils from "./utils/mongoose"; import { CreateMessageResultSchema } from "@modelcontextprotocol/sdk/types.js"; const server = new McpServer({ name: "kanban-mcp", version: "1.0.0", capabilities: { resources: {}, tools: {}, prompts: {}, }, }); server.resource( "tasks", "tasks://all", { description: "Get all tasks from the database", title: "Tasks", mimeType: "application/json", }, async (uri) => { // Don't block on DB init here; getTasks will fall back to cache if needed let tasks = await mongooseUtils.getTasks(); return { contents: [ { uri: uri.href, text: JSON.stringify(tasks), mimeType: "application/json", }, ], }; } ); // Create a new task server.tool( "create-task", "create a new todo task", { task_title: z.string(), description: z.string(), }, { title: "create a todo task", readonlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true, }, async (params) => { try { await mongooseUtils.createTask(params); return { content: [ { type: "text", text: `Task "${params.task_title}" created successfully!`, }, ], }; } catch { return { content: [ { type: "text", text: "An error occurred while creating the task." }, ], }; } } ); // set status server.tool( "move-task", "move a task to a different status", { task_id: z.string(), new_status: z.enum(["todo", "inProgress", "done"]), }, { title: "move a task to a different status", readonlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true, }, async (params) => { try { await mongooseUtils.moveTask(params.task_id, params.new_status); return { content: [ { type: "text", text: `Task "${params.task_id}" moved to "${params.new_status}" successfully!`, }, ], }; } catch { return { content: [ { type: "text", text: `Failed to move task "${params.task_id}" to "${params.new_status}".`, }, ], }; } } ); // set priority server.tool( "set-prioity", "set a task to a different priority", { task_id: z.string(), new_priority: z.enum(["low", "medium", "high"]), }, { title: "set a task to a different priority", readonlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true, }, async (params) => { try { await mongooseUtils.setTaskPriority(params.task_id, params.new_priority); return { content: [ { type: "text", text: `Set task "${params.task_id}" Priority to "${params.new_priority}" successfully!`, }, ], }; } catch { return { content: [ { type: "text", text: `Failed to set task "${params.task_id}" priority to "${params.new_priority}".`, }, ], }; } } ); // show analytics server.prompt("tasks-analytics", "get analytics for users tasks", async () => { let tasks_stats = await getTasksStats(); const statsString = JSON.stringify(tasks_stats, null, 2); return { messages: [ { role: "user", content: { type: "text", text: `analize the lead time and current tasks status distribution from the given tasks stats and present them in a table:${statsString}`, }, }, ], }; }); //add tag server.tool("add-tag", "add tags to a tasks",{ task_tag: z.string(), task_id: z.string() },async (params)=>{ try { await mongooseUtils.addTaskTag(params.task_id,params.task_tag); return{ content: [ { type: "text", text: `Added tag "${params.task_tag}" to tasks"${params.task_id}" successfully.`, }, ], } } catch { return{ content: [ { type: "text", text: `Failed to add tag "${params.task_tag}" to tasks"${params.task_id}".`, }, ], } } }); // analytics async function getTasksStats() { const tasks = await mongooseUtils.getTasks(); const tasks_count = tasks.length; let inProgress_count = 0; let done_count = 0; tasks.forEach((task) => { if (task.taskStatus == "done") { done_count++; } if (task.taskStatus == "inProgress") { inProgress_count++; } }); return { all_tasks: tasks, tasks_count: tasks_count, inProgress_count: inProgress_count, todo_count: tasks_count - inProgress_count - done_count, done_count: done_count, }; } async function main() { const transport = new StdioServerTransport(); await server.connect(transport); // Initialize DB in the background so we don't block MCP initialize handshake mongooseUtils.initDb.catch((err) => { console.error("DB initialization failed:", err); }); } main();

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/0Thomas1/Kanban-MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server