productboard-mcp
Version:
Integrate the Productboard API into agentic workflows via MCP
157 lines (156 loc) • 6.68 kB
JavaScript
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);
});