diff --git a/servers/trello/README.md b/servers/trello/README.md index b2507c5..27bdbf6 100644 --- a/servers/trello/README.md +++ b/servers/trello/README.md @@ -1,10 +1,10 @@ # Trello MCP Server -Production-quality MCP server for [Trello](https://trello.com/) API integration with 57+ comprehensive tools and 18 interactive React apps. +Production-quality MCP server for [Trello](https://trello.com/) API integration with 96 comprehensive tools and 18 interactive React apps. ## Features -- **57+ Tools** across 14 domains: boards, lists, cards, checklists, members, organizations, labels, actions, custom fields, notifications, search, webhooks, power-ups, and tokens +- **96 Tools** across 14 domains: boards, lists, cards, checklists, members, organizations, labels, actions, custom fields, notifications, search, webhooks, power-ups, and tokens - **18 React Apps** for rich UI experiences: kanban boards, dashboards, calendars, analytics, and more - **Full Trello API Coverage**: All major endpoints with proper error handling and rate limiting - **Type-Safe**: Complete TypeScript types for all Trello objects diff --git a/servers/trello/package.json b/servers/trello/package.json index 2c538ce..139294a 100644 --- a/servers/trello/package.json +++ b/servers/trello/package.json @@ -15,7 +15,8 @@ "dev": "tsx src/index.ts", "start": "node dist/index.js", "clean": "rm -rf dist", - "prepare": "npm run build" + "prepare": "npm run build", + "prepublishOnly": "npm run build" }, "keywords": [ "mcp", @@ -34,9 +35,13 @@ "devDependencies": { "@types/node": "^20.10.0", "@types/react": "^18.2.0", + "@types/react-dom": "^18.2.0", + "@vitejs/plugin-react": "^4.2.0", "react": "^18.2.0", + "react-dom": "^18.2.0", "tsx": "^4.7.0", - "typescript": "^5.3.0" + "typescript": "^5.3.0", + "vite": "^5.0.0" }, "engines": { "node": ">=18.0.0" diff --git a/servers/trello/src/clients/trello.ts b/servers/trello/src/clients/trello.ts index 0ce92fd..afef919 100644 --- a/servers/trello/src/clients/trello.ts +++ b/servers/trello/src/clients/trello.ts @@ -62,7 +62,7 @@ export class TrelloClient { if (reset) this.rateLimitReset = parseInt(reset, 10) * 1000; if (!response.ok) { - const error = await response.json().catch(() => ({ message: response.statusText })); + const error: any = await response.json().catch(() => ({ message: response.statusText })); throw new Error(`Trello API Error: ${error.message || response.statusText}`); } diff --git a/servers/trello/src/types/global.d.ts b/servers/trello/src/types/global.d.ts new file mode 100644 index 0000000..2dafa23 --- /dev/null +++ b/servers/trello/src/types/global.d.ts @@ -0,0 +1,9 @@ +declare global { + interface Window { + mcp?: { + callTool(name: string, args: any): Promise; + }; + } +} + +export {}; diff --git a/servers/trello/src/ui/react-app/board-dashboard.tsx b/servers/trello/src/ui/react-app/board-dashboard.tsx index 11e12aa..af05e71 100644 --- a/servers/trello/src/ui/react-app/board-dashboard.tsx +++ b/servers/trello/src/ui/react-app/board-dashboard.tsx @@ -14,6 +14,7 @@ export default function BoardDashboard({ boardId }: { boardId: string }) { }, [boardId]); async function loadDashboard() { + if (!window.mcp) return; setLoading(true); try { const [boardData, listsData, cardsData, membersData, labelsData, actionsData] = await Promise.all([ diff --git a/servers/trello/src/ui/react-app/board-kanban.tsx b/servers/trello/src/ui/react-app/board-kanban.tsx index 55c27df..f1e0572 100644 --- a/servers/trello/src/ui/react-app/board-kanban.tsx +++ b/servers/trello/src/ui/react-app/board-kanban.tsx @@ -12,6 +12,7 @@ export default function BoardKanban({ boardId }: { boardId: string }) { }, [boardId]); async function loadBoard() { + if (!window.mcp) return; setLoading(true); try { const boardData = await window.mcp.callTool('trello_get_board', { board_id: boardId }); @@ -34,7 +35,7 @@ export default function BoardKanban({ boardId }: { boardId: string }) { } async function handleCardDrop(listId: string) { - if (!draggedCard) return; + if (!draggedCard || !window.mcp) return; try { await window.mcp.callTool('trello_move_card', { @@ -49,7 +50,7 @@ export default function BoardKanban({ boardId }: { boardId: string }) { } async function handleCreateCard(listId: string, name: string) { - if (!name.trim()) return; + if (!name.trim() || !window.mcp) return; try { await window.mcp.callTool('trello_create_card', { diff --git a/servers/trello/src/ui/react-app/board-table.tsx b/servers/trello/src/ui/react-app/board-table.tsx index 46c55aa..2b0e63d 100644 --- a/servers/trello/src/ui/react-app/board-table.tsx +++ b/servers/trello/src/ui/react-app/board-table.tsx @@ -12,6 +12,7 @@ export default function BoardTable({ boardId }: { boardId: string }) { }, [boardId]); async function loadData() { + if (!window.mcp) return; setLoading(true); try { const [cardsData, listsData] = await Promise.all([ diff --git a/servers/trello/src/ui/react-app/card-detail.tsx b/servers/trello/src/ui/react-app/card-detail.tsx index 4ce058e..ca69c27 100644 --- a/servers/trello/src/ui/react-app/card-detail.tsx +++ b/servers/trello/src/ui/react-app/card-detail.tsx @@ -14,6 +14,7 @@ export default function CardDetail({ cardId }: { cardId: string }) { }, [cardId]); async function loadCard() { + if (!window.mcp) return; setLoading(true); try { const [cardData, commentsData, checklistsData, attachmentsData, customFieldsData] = await Promise.all([ @@ -37,7 +38,7 @@ export default function CardDetail({ cardId }: { cardId: string }) { } async function addComment() { - if (!newComment.trim()) return; + if (!newComment.trim() || !window.mcp) return; try { await window.mcp.callTool('trello_add_card_comment', { @@ -52,6 +53,7 @@ export default function CardDetail({ cardId }: { cardId: string }) { } async function toggleCheckItem(checklistId: string, itemId: string, currentState: string) { + if (!window.mcp) return; try { await window.mcp.callTool('trello_update_check_item', { card_id: cardId, diff --git a/servers/trello/tsconfig.json b/servers/trello/tsconfig.json index 999a234..aaffba8 100644 --- a/servers/trello/tsconfig.json +++ b/servers/trello/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { "target": "ES2022", "module": "ES2022", - "lib": ["ES2022"], + "lib": ["ES2022", "DOM"], "outDir": "./dist", "rootDir": "./src", "strict": true,