trello: 96 tools, 18 apps, production-ready
This commit is contained in:
parent
2d0db0f147
commit
4c49c157c0
@ -1,10 +1,10 @@
|
|||||||
# Trello MCP Server
|
# 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
|
## 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
|
- **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
|
- **Full Trello API Coverage**: All major endpoints with proper error handling and rate limiting
|
||||||
- **Type-Safe**: Complete TypeScript types for all Trello objects
|
- **Type-Safe**: Complete TypeScript types for all Trello objects
|
||||||
|
|||||||
@ -15,7 +15,8 @@
|
|||||||
"dev": "tsx src/index.ts",
|
"dev": "tsx src/index.ts",
|
||||||
"start": "node dist/index.js",
|
"start": "node dist/index.js",
|
||||||
"clean": "rm -rf dist",
|
"clean": "rm -rf dist",
|
||||||
"prepare": "npm run build"
|
"prepare": "npm run build",
|
||||||
|
"prepublishOnly": "npm run build"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"mcp",
|
"mcp",
|
||||||
@ -34,9 +35,13 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^20.10.0",
|
"@types/node": "^20.10.0",
|
||||||
"@types/react": "^18.2.0",
|
"@types/react": "^18.2.0",
|
||||||
|
"@types/react-dom": "^18.2.0",
|
||||||
|
"@vitejs/plugin-react": "^4.2.0",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
|
"react-dom": "^18.2.0",
|
||||||
"tsx": "^4.7.0",
|
"tsx": "^4.7.0",
|
||||||
"typescript": "^5.3.0"
|
"typescript": "^5.3.0",
|
||||||
|
"vite": "^5.0.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.0.0"
|
"node": ">=18.0.0"
|
||||||
|
|||||||
@ -62,7 +62,7 @@ export class TrelloClient {
|
|||||||
if (reset) this.rateLimitReset = parseInt(reset, 10) * 1000;
|
if (reset) this.rateLimitReset = parseInt(reset, 10) * 1000;
|
||||||
|
|
||||||
if (!response.ok) {
|
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}`);
|
throw new Error(`Trello API Error: ${error.message || response.statusText}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
9
servers/trello/src/types/global.d.ts
vendored
Normal file
9
servers/trello/src/types/global.d.ts
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
declare global {
|
||||||
|
interface Window {
|
||||||
|
mcp?: {
|
||||||
|
callTool(name: string, args: any): Promise<any>;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export {};
|
||||||
@ -14,6 +14,7 @@ export default function BoardDashboard({ boardId }: { boardId: string }) {
|
|||||||
}, [boardId]);
|
}, [boardId]);
|
||||||
|
|
||||||
async function loadDashboard() {
|
async function loadDashboard() {
|
||||||
|
if (!window.mcp) return;
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
try {
|
try {
|
||||||
const [boardData, listsData, cardsData, membersData, labelsData, actionsData] = await Promise.all([
|
const [boardData, listsData, cardsData, membersData, labelsData, actionsData] = await Promise.all([
|
||||||
|
|||||||
@ -12,6 +12,7 @@ export default function BoardKanban({ boardId }: { boardId: string }) {
|
|||||||
}, [boardId]);
|
}, [boardId]);
|
||||||
|
|
||||||
async function loadBoard() {
|
async function loadBoard() {
|
||||||
|
if (!window.mcp) return;
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
try {
|
try {
|
||||||
const boardData = await window.mcp.callTool('trello_get_board', { board_id: boardId });
|
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) {
|
async function handleCardDrop(listId: string) {
|
||||||
if (!draggedCard) return;
|
if (!draggedCard || !window.mcp) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await window.mcp.callTool('trello_move_card', {
|
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) {
|
async function handleCreateCard(listId: string, name: string) {
|
||||||
if (!name.trim()) return;
|
if (!name.trim() || !window.mcp) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await window.mcp.callTool('trello_create_card', {
|
await window.mcp.callTool('trello_create_card', {
|
||||||
|
|||||||
@ -12,6 +12,7 @@ export default function BoardTable({ boardId }: { boardId: string }) {
|
|||||||
}, [boardId]);
|
}, [boardId]);
|
||||||
|
|
||||||
async function loadData() {
|
async function loadData() {
|
||||||
|
if (!window.mcp) return;
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
try {
|
try {
|
||||||
const [cardsData, listsData] = await Promise.all([
|
const [cardsData, listsData] = await Promise.all([
|
||||||
|
|||||||
@ -14,6 +14,7 @@ export default function CardDetail({ cardId }: { cardId: string }) {
|
|||||||
}, [cardId]);
|
}, [cardId]);
|
||||||
|
|
||||||
async function loadCard() {
|
async function loadCard() {
|
||||||
|
if (!window.mcp) return;
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
try {
|
try {
|
||||||
const [cardData, commentsData, checklistsData, attachmentsData, customFieldsData] = await Promise.all([
|
const [cardData, commentsData, checklistsData, attachmentsData, customFieldsData] = await Promise.all([
|
||||||
@ -37,7 +38,7 @@ export default function CardDetail({ cardId }: { cardId: string }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function addComment() {
|
async function addComment() {
|
||||||
if (!newComment.trim()) return;
|
if (!newComment.trim() || !window.mcp) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await window.mcp.callTool('trello_add_card_comment', {
|
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) {
|
async function toggleCheckItem(checklistId: string, itemId: string, currentState: string) {
|
||||||
|
if (!window.mcp) return;
|
||||||
try {
|
try {
|
||||||
await window.mcp.callTool('trello_update_check_item', {
|
await window.mcp.callTool('trello_update_check_item', {
|
||||||
card_id: cardId,
|
card_id: cardId,
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "ES2022",
|
"target": "ES2022",
|
||||||
"module": "ES2022",
|
"module": "ES2022",
|
||||||
"lib": ["ES2022"],
|
"lib": ["ES2022", "DOM"],
|
||||||
"outDir": "./dist",
|
"outDir": "./dist",
|
||||||
"rootDir": "./src",
|
"rootDir": "./src",
|
||||||
"strict": true,
|
"strict": true,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user