Skip to main content
Glama

Advanced Trello MCP Server

cards.ts11.2 kB
import { z } from 'zod'; import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; import { TrelloCredentials } from '../types/common.js'; /** * Register all Cards API tools * Based on https://developer.atlassian.com/cloud/trello/rest/api-group-cards/ */ export function registerCardsTools(server: McpServer, credentials: TrelloCredentials) { // POST /cards - Create a new card server.tool( 'create-card', { name: z.string().describe('Name of the card'), description: z.string().optional().describe('Description of the card'), listId: z.string().describe('ID of the list to create the card in'), }, async ({ name, description, listId }) => { try { const response = await fetch( `https://api.trello.com/1/cards?key=${credentials.apiKey}&token=${credentials.apiToken}`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ name, desc: description || '', idList: listId, pos: 'bottom', }), } ); const data = await response.json(); return { content: [ { type: 'text', text: JSON.stringify(data), }, ], }; } catch (error) { return { content: [ { type: 'text', text: `Error creating card: ${error}`, }, ], isError: true, }; } } ); // POST /cards - Create multiple cards server.tool( 'create-cards', { cards: z.array( z.object({ name: z.string().describe('Name of the card'), description: z.string().optional().describe('Description of the card'), listId: z.string().describe('ID of the list to create the card in'), }) ), }, async ({ cards }) => { try { const results = await Promise.all( cards.map(async (card) => { const response = await fetch( `https://api.trello.com/1/cards?key=${credentials.apiKey}&token=${credentials.apiToken}`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ name: card.name, desc: card.description || '', idList: card.listId, pos: 'bottom', }), } ); return await response.json(); }) ); return { content: [ { type: 'text', text: JSON.stringify(results), }, ], }; } catch (error) { return { content: [ { type: 'text', text: `Error creating cards: ${error}`, }, ], isError: true, }; } } ); // PUT /cards/{id}/idList - Move card to another list server.tool( 'move-card', { cardId: z.string().describe('ID of the card to move'), listId: z.string().describe('ID of the destination list'), position: z.string().optional().describe('Position in the list (e.g. "top", "bottom")'), }, async ({ cardId, listId, position = 'bottom' }) => { try { if (!credentials.apiKey || !credentials.apiToken) { return { content: [ { type: 'text', text: 'Trello API credentials are not configured', }, ], isError: true, }; } const response = await fetch( `https://api.trello.com/1/cards/${cardId}?key=${credentials.apiKey}&token=${credentials.apiToken}`, { method: 'PUT', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ idList: listId, pos: position, }), } ); const data = await response.json(); return { content: [ { type: 'text', text: JSON.stringify(data), }, ], }; } catch (error) { return { content: [ { type: 'text', text: `Error moving card: ${error}`, }, ], isError: true, }; } } ); // PUT /cards - Move multiple cards server.tool( 'move-cards', { cards: z.array( z.object({ cardId: z.string().describe('ID of the card to move'), listId: z.string().describe('ID of the destination list'), position: z.string().optional().describe('Position in the list (e.g. "top", "bottom")'), }) ), }, async ({ cards }) => { try { if (!credentials.apiKey || !credentials.apiToken) { return { content: [ { type: 'text', text: 'Trello API credentials are not configured', }, ], isError: true, }; } const results = await Promise.all( cards.map(async (card) => { const response = await fetch( `https://api.trello.com/1/cards/${card.cardId}?key=${credentials.apiKey}&token=${credentials.apiToken}`, { method: 'PUT', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ idList: card.listId, pos: card.position || 'bottom', }), } ); return await response.json(); }) ); return { content: [ { type: 'text', text: JSON.stringify(results), }, ], }; } catch (error) { return { content: [ { type: 'text', text: `Error moving cards: ${error}`, }, ], isError: true, }; } } ); // POST /cards/{id}/actions/comments - Add comment to card server.tool( 'add-comment', { cardId: z.string().describe('ID of the card to comment on'), text: z.string().describe('Comment text'), }, async ({ cardId, text }) => { try { if (!credentials.apiKey || !credentials.apiToken) { return { content: [ { type: 'text', text: 'Trello API credentials are not configured', }, ], isError: true, }; } const response = await fetch( `https://api.trello.com/1/cards/${cardId}/actions/comments?key=${credentials.apiKey}&token=${credentials.apiToken}`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ text, }), } ); const data = await response.json(); return { content: [ { type: 'text', text: JSON.stringify(data), }, ], }; } catch (error) { return { content: [ { type: 'text', text: `Error adding comment: ${error}`, }, ], isError: true, }; } } ); // POST /cards/{id}/actions/comments - Add multiple comments server.tool( 'add-comments', { comments: z.array( z.object({ cardId: z.string().describe('ID of the card to comment on'), text: z.string().describe('Comment text'), }) ), }, async ({ comments }) => { try { if (!credentials.apiKey || !credentials.apiToken) { return { content: [ { type: 'text', text: 'Trello API credentials are not configured', }, ], isError: true, }; } const results = await Promise.all( comments.map(async (comment) => { const response = await fetch( `https://api.trello.com/1/cards/${comment.cardId}/actions/comments?key=${credentials.apiKey}&token=${credentials.apiToken}`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ text: comment.text, }), } ); return await response.json(); }) ); return { content: [ { type: 'text', text: JSON.stringify(results), }, ], }; } catch (error) { return { content: [ { type: 'text', text: `Error adding comments: ${error}`, }, ], isError: true, }; } } ); // GET /lists/{id}/cards - Get tickets by list (alias for get-list-cards) server.tool( 'get-tickets-by-list', { listId: z.string().describe('ID of the list to get tickets from'), limit: z.number().optional().describe('Maximum number of cards to return'), }, async ({ listId, limit }) => { try { if (!credentials.apiKey || !credentials.apiToken) { return { content: [ { type: 'text', text: 'Trello API credentials are not configured', }, ], isError: true, }; } const url = new URL(`https://api.trello.com/1/lists/${listId}/cards`); url.searchParams.append('key', credentials.apiKey); url.searchParams.append('token', credentials.apiToken); if (limit) url.searchParams.append('limit', limit.toString()); const response = await fetch(url.toString()); const data = await response.json(); return { content: [ { type: 'text', text: JSON.stringify(data), }, ], }; } catch (error) { return { content: [ { type: 'text', text: `Error getting tickets by list: ${error}`, }, ], isError: true, }; } } ); // PUT /cards/{id}/closed - Archive a card server.tool( 'archive-card', { cardId: z.string().describe('ID of the card to archive'), }, async ({ cardId }) => { try { if (!credentials.apiKey || !credentials.apiToken) { return { content: [ { type: 'text', text: 'Trello API credentials are not configured', }, ], isError: true, }; } const response = await fetch( `https://api.trello.com/1/cards/${cardId}?key=${credentials.apiKey}&token=${credentials.apiToken}`, { method: 'PUT', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ closed: true, }), } ); const data = await response.json(); return { content: [ { type: 'text', text: JSON.stringify(data), }, ], }; } catch (error) { return { content: [ { type: 'text', text: `Error archiving card: ${error}`, }, ], isError: true, }; } } ); // PUT /cards - Archive multiple cards server.tool( 'archive-cards', { cardIds: z.array(z.string()).describe('IDs of the cards to archive'), }, async ({ cardIds }) => { try { if (!credentials.apiKey || !credentials.apiToken) { return { content: [ { type: 'text', text: 'Trello API credentials are not configured', }, ], isError: true, }; } const results = await Promise.all( cardIds.map(async (cardId) => { const response = await fetch( `https://api.trello.com/1/cards/${cardId}?key=${credentials.apiKey}&token=${credentials.apiToken}`, { method: 'PUT', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ closed: true, }), } ); return await response.json(); }) ); return { content: [ { type: 'text', text: JSON.stringify(results), }, ], }; } catch (error) { return { content: [ { type: 'text', text: `Error archiving cards: ${error}`, }, ], isError: true, }; } } ); }

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/adriangrahldev/advanced-trello-mcp-server'

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