UNPKG

productboard-mcp

Version:

Integrate the Productboard API into agentic workflows via MCP

157 lines (156 loc) 6.68 kB
#!/usr/bin/env node import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js"; import { getProductsTool, getProducts } from "./product/get_products.js"; import { getProductDetailTool, getProductDetail } from "./product/get_product_detail.js"; import { getFeaturesTool, getFeatures } from "./feature/get_features.js"; import { getFeatureDetailTool, getFeatureDetail } from "./feature/get_feature_detail.js"; import { getComponentsTool, getComponents } from "./component/get_components.js"; import { getComponentDetailTool, getComponentDetail } from "./component/get_component_detail.js"; import { getFeatureStatusesTool, getFeatureStatuses } from "./feature_status/get_feature_statuses.js"; import { getNotesTool, getNotes } from "./note/get_notes.js"; import { getNoteDetailTool, getNoteDetail } from "./note/get_note_detail.js"; import { getCompaniesTool, getCompanies } from "./company/get_companies.js"; import { getCompanyDetailTool, getCompanyDetail } from "./company/get_company_detail.js"; async function main() { const productboardAccessToken = process.env.PRODUCTBOARD_ACCESS_TOKEN; if (!productboardAccessToken) { console.error("Please set PRODUCTBOARD_ACCESS_TOKEN environment variable"); process.exit(1); } const server = new Server({ name: "Productboard MCP Server", version: "1.0.0", }, { capabilities: { tools: {}, }, }); server.setRequestHandler(CallToolRequestSchema, async (request) => { console.info("Received CallToolRequest: ", request); try { const { name, arguments: args } = request.params; switch (name) { case getProductsTool.name: { const request = args; const result = await getProducts(request); return { content: [{ type: "text", text: JSON.stringify(result) }], }; } case getProductDetailTool.name: { const request = args; const result = await getProductDetail(request); return { content: [{ type: "text", text: JSON.stringify(result) }], }; } case getFeaturesTool.name: { const request = args; const result = await getFeatures(request); return { content: [{ type: "text", text: JSON.stringify(result) }], }; } case getFeatureDetailTool.name: { const request = args; const result = await getFeatureDetail(request); return { content: [{ type: "text", text: JSON.stringify(result) }], }; } case getComponentsTool.name: { const request = args; const result = await getComponents(request); return { content: [{ type: "text", text: JSON.stringify(result) }], }; } case getComponentDetailTool.name: { const request = args; const result = await getComponentDetail(request); return { content: [{ type: "text", text: JSON.stringify(result) }], }; } case getFeatureStatusesTool.name: { const request = args; const result = await getFeatureStatuses(request); return { content: [{ type: "text", text: JSON.stringify(result) }], }; } case getNotesTool.name: { const request = args; const result = await getNotes(request); return { content: [{ type: "text", text: JSON.stringify(result) }], }; } case getNoteDetailTool.name: { const request = args; const result = await getNoteDetail(request); return { content: [{ type: "text", text: JSON.stringify(result) }], }; } case getCompaniesTool.name: { const request = args; const result = await getCompanies(request); return { content: [{ type: "text", text: JSON.stringify(result) }], }; } case getCompanyDetailTool.name: { const request = args; const result = await getCompanyDetail(request); return { content: [{ type: "text", text: JSON.stringify(result) }], }; } default: throw new Error(`Unknown tool: ${name}`); } } catch (error) { console.error("Error executing tool: ", error); return { content: [ { type: "text", text: JSON.stringify({ error: error instanceof Error ? error.message : String(error), }), }, ], }; } }); server.setRequestHandler(ListToolsRequestSchema, async () => { console.info("Received ListToolsRequest"); return { tools: [ getProductsTool, getProductDetailTool, getFeaturesTool, getFeatureDetailTool, getComponentsTool, getComponentDetailTool, getFeatureStatusesTool, getNotesTool, getNoteDetailTool, getCompaniesTool, getCompanyDetailTool ], }; }); const transport = new StdioServerTransport(); console.log("Connecting server to transport..."); await server.connect(transport); console.log("Productboard MCP Server running on stdio"); } main().catch((error) => { console.error("Fatal error in main():", error); process.exit(1); });