Skip to main content
Glama
jhliberty

Basecamp MCP Server

by jhliberty

create_card_step

Add a new step (sub-task) to a card in Basecamp 3 by specifying the project ID, card ID, step title, optional due date, and assignees. Streamlines task breakdown and assignment within projects.

Instructions

Create a new step (sub-task) for a card

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
assignee_idsNoArray of person IDs to assign to the step
card_idYesThe card ID
due_onNoOptional due date (ISO 8601 format)
project_idYesThe project ID
titleYesThe step title

Implementation Reference

  • Core handler function that executes the Basecamp API POST request to create a new card step (sub-task).
    async createCardStep(
      projectId: string,
      cardId: string,
      title: string,
      dueOn?: string,
      assigneeIds?: string[]
    ): Promise<CardStep> {
      const data: any = { title };
      if (dueOn) data.due_on = dueOn;
      if (assigneeIds) data.assignee_ids = assigneeIds;
    
      const response = await this.client.post(`/buckets/${projectId}/card_tables/cards/${cardId}/steps.json`, data);
      return response.data;
    }
  • MCP server tool handler switch case that receives tool call parameters and delegates to BasecampClient.createCardStep, then formats the response.
    case 'create_card_step': {
      const step = await client.createCardStep(
        typedArgs.project_id,
        typedArgs.card_id,
        typedArgs.title,
        typedArgs.due_on,
        typedArgs.assignee_ids
      );
      return {
        content: [{
          type: 'text',
          text: JSON.stringify({
            status: 'success',
            step,
            message: `Step '${typedArgs.title}' created successfully`
          }, null, 2)
        }]
      };
    }
  • Tool schema definition including inputSchema for validation and the tool name registration in the listTools response.
    {
      name: 'create_card_step',
      description: 'Create a new step (sub-task) for a card',
      inputSchema: {
        type: 'object',
        properties: {
          project_id: { type: 'string', description: 'The project ID' },
          card_id: { type: 'string', description: 'The card ID' },
          title: { type: 'string', description: 'The step title' },
          due_on: { type: 'string', description: 'Optional due date (ISO 8601 format)' },
          assignee_ids: { type: 'array', items: { type: 'string' }, description: 'Array of person IDs to assign to the step' },
        },
        required: ['project_id', 'card_id', 'title'],
      },
    },
  • src/index.ts:104-540 (registration)
    The listTools request handler where all tools including 'create_card_step' are registered and returned to MCP clients.
    this.server.setRequestHandler(ListToolsRequestSchema, async () => {
      return {
        tools: [
          // Core tools
          {
            name: 'get_projects',
            description: 'Get all Basecamp projects',
            inputSchema: {
              type: 'object',
              properties: {},
            },
          },
          {
            name: 'get_project',
            description: 'Get details for a specific project',
            inputSchema: {
              type: 'object',
              properties: {
                project_id: { type: 'string', description: 'The project ID' },
              },
              required: ['project_id'],
            },
          },
          {
            name: 'search_basecamp',
            description: 'Search across Basecamp projects, todos, and messages',
            inputSchema: {
              type: 'object',
              properties: {
                query: { type: 'string', description: 'Search query' },
                project_id: { type: 'string', description: 'Optional project ID to limit search scope' },
              },
              required: ['query'],
            },
          },
          {
            name: 'global_search',
            description: 'Search projects, todos and campfire messages across all projects',
            inputSchema: {
              type: 'object',
              properties: {
                query: { type: 'string', description: 'Search query' },
              },
              required: ['query'],
            },
          },
    
          // Todo tools
          {
            name: 'get_todolists',
            description: 'Get todo lists for a project',
            inputSchema: {
              type: 'object',
              properties: {
                project_id: { type: 'string', description: 'The project ID' },
              },
              required: ['project_id'],
            },
          },
          {
            name: 'get_todos',
            description: 'Get todos from a todo list',
            inputSchema: {
              type: 'object',
              properties: {
                project_id: { type: 'string', description: 'Project ID' },
                todolist_id: { type: 'string', description: 'The todo list ID' },
              },
              required: ['project_id', 'todolist_id'],
            },
          },
    
          // Card Table tools
          {
            name: 'get_card_table',
            description: 'Get the card table details for a project',
            inputSchema: {
              type: 'object',
              properties: {
                project_id: { type: 'string', description: 'The project ID' },
              },
              required: ['project_id'],
            },
          },
          {
            name: 'get_columns',
            description: 'Get all columns in a card table',
            inputSchema: {
              type: 'object',
              properties: {
                project_id: { type: 'string', description: 'The project ID' },
                card_table_id: { type: 'string', description: 'The card table ID' },
              },
              required: ['project_id', 'card_table_id'],
            },
          },
          {
            name: 'get_cards',
            description: 'Get all cards in a column',
            inputSchema: {
              type: 'object',
              properties: {
                project_id: { type: 'string', description: 'The project ID' },
                column_id: { type: 'string', description: 'The column ID' },
              },
              required: ['project_id', 'column_id'],
            },
          },
          {
            name: 'create_card',
            description: 'Create a new card in a column',
            inputSchema: {
              type: 'object',
              properties: {
                project_id: { type: 'string', description: 'The project ID' },
                column_id: { type: 'string', description: 'The column ID' },
                title: { type: 'string', description: 'The card title' },
                content: { type: 'string', description: 'Optional card content/description' },
                due_on: { type: 'string', description: 'Optional due date (ISO 8601 format)' },
                notify: { type: 'boolean', description: 'Whether to notify assignees (default: false)' },
              },
              required: ['project_id', 'column_id', 'title'],
            },
          },
    
          // Column Management tools
          {
            name: 'create_column',
            description: 'Create a new column in a card table',
            inputSchema: {
              type: 'object',
              properties: {
                project_id: { type: 'string', description: 'The project ID' },
                card_table_id: { type: 'string', description: 'The card table ID' },
                title: { type: 'string', description: 'The column title' },
              },
              required: ['project_id', 'card_table_id', 'title'],
            },
          },
          {
            name: 'update_column',
            description: 'Update a column title',
            inputSchema: {
              type: 'object',
              properties: {
                project_id: { type: 'string', description: 'The project ID' },
                column_id: { type: 'string', description: 'The column ID' },
                title: { type: 'string', description: 'The new column title' },
              },
              required: ['project_id', 'column_id', 'title'],
            },
          },
          {
            name: 'move_column',
            description: 'Move a column to a new position',
            inputSchema: {
              type: 'object',
              properties: {
                project_id: { type: 'string', description: 'The project ID' },
                card_table_id: { type: 'string', description: 'The card table ID' },
                column_id: { type: 'string', description: 'The column ID' },
                position: { type: 'number', description: 'The new 1-based position' },
              },
              required: ['project_id', 'card_table_id', 'column_id', 'position'],
            },
          },
          {
            name: 'update_column_color',
            description: 'Update a column color',
            inputSchema: {
              type: 'object',
              properties: {
                project_id: { type: 'string', description: 'The project ID' },
                column_id: { type: 'string', description: 'The column ID' },
                color: { type: 'string', description: 'The hex color code (e.g., #FF0000)' },
              },
              required: ['project_id', 'column_id', 'color'],
            },
          },
    
          // Card Management tools
          {
            name: 'get_card',
            description: 'Get details for a specific card',
            inputSchema: {
              type: 'object',
              properties: {
                project_id: { type: 'string', description: 'The project ID' },
                card_id: { type: 'string', description: 'The card ID' },
              },
              required: ['project_id', 'card_id'],
            },
          },
          {
            name: 'update_card',
            description: 'Update a card',
            inputSchema: {
              type: 'object',
              properties: {
                project_id: { type: 'string', description: 'The project ID' },
                card_id: { type: 'string', description: 'The card ID' },
                title: { type: 'string', description: 'The new card title' },
                content: { type: 'string', description: 'The new card content/description' },
                due_on: { type: 'string', description: 'Due date (ISO 8601 format)' },
                assignee_ids: { type: 'array', items: { type: 'string' }, description: 'Array of person IDs to assign to the card' },
              },
              required: ['project_id', 'card_id'],
            },
          },
          {
            name: 'move_card',
            description: 'Move a card to a new column',
            inputSchema: {
              type: 'object',
              properties: {
                project_id: { type: 'string', description: 'The project ID' },
                card_id: { type: 'string', description: 'The card ID' },
                column_id: { type: 'string', description: 'The destination column ID' },
              },
              required: ['project_id', 'card_id', 'column_id'],
            },
          },
          {
            name: 'complete_card',
            description: 'Mark a card as complete',
            inputSchema: {
              type: 'object',
              properties: {
                project_id: { type: 'string', description: 'The project ID' },
                card_id: { type: 'string', description: 'The card ID' },
              },
              required: ['project_id', 'card_id'],
            },
          },
    
          // Card Steps tools
          {
            name: 'get_card_steps',
            description: 'Get all steps (sub-tasks) for a card',
            inputSchema: {
              type: 'object',
              properties: {
                project_id: { type: 'string', description: 'The project ID' },
                card_id: { type: 'string', description: 'The card ID' },
              },
              required: ['project_id', 'card_id'],
            },
          },
          {
            name: 'create_card_step',
            description: 'Create a new step (sub-task) for a card',
            inputSchema: {
              type: 'object',
              properties: {
                project_id: { type: 'string', description: 'The project ID' },
                card_id: { type: 'string', description: 'The card ID' },
                title: { type: 'string', description: 'The step title' },
                due_on: { type: 'string', description: 'Optional due date (ISO 8601 format)' },
                assignee_ids: { type: 'array', items: { type: 'string' }, description: 'Array of person IDs to assign to the step' },
              },
              required: ['project_id', 'card_id', 'title'],
            },
          },
          {
            name: 'complete_card_step',
            description: 'Mark a card step as complete',
            inputSchema: {
              type: 'object',
              properties: {
                project_id: { type: 'string', description: 'The project ID' },
                step_id: { type: 'string', description: 'The step ID' },
              },
              required: ['project_id', 'step_id'],
            },
          },
    
          // Communication tools
          {
            name: 'get_campfire_lines',
            description: 'Get recent messages from a Basecamp campfire (chat room)',
            inputSchema: {
              type: 'object',
              properties: {
                project_id: { type: 'string', description: 'The project ID' },
                campfire_id: { type: 'string', description: 'The campfire/chat room ID' },
              },
              required: ['project_id', 'campfire_id'],
            },
          },
          {
            name: 'get_comments',
            description: 'Get comments for a Basecamp item',
            inputSchema: {
              type: 'object',
              properties: {
                recording_id: { type: 'string', description: 'The item ID' },
                project_id: { type: 'string', description: 'The project ID' },
              },
              required: ['recording_id', 'project_id'],
            },
          },
    
          // Document tools
          {
            name: 'get_documents',
            description: 'List documents in a vault',
            inputSchema: {
              type: 'object',
              properties: {
                project_id: { type: 'string', description: 'Project ID' },
                vault_id: { type: 'string', description: 'Vault ID' },
              },
              required: ['project_id', 'vault_id'],
            },
          },
          {
            name: 'create_document',
            description: 'Create a document in a vault',
            inputSchema: {
              type: 'object',
              properties: {
                project_id: { type: 'string', description: 'Project ID' },
                vault_id: { type: 'string', description: 'Vault ID' },
                title: { type: 'string', description: 'Document title' },
                content: { type: 'string', description: 'Document HTML content' },
              },
              required: ['project_id', 'vault_id', 'title', 'content'],
            },
          },
          {
            name: 'update_document',
            description: 'Update a document',
            inputSchema: {
              type: 'object',
              properties: {
                project_id: { type: 'string', description: 'Project ID' },
                document_id: { type: 'string', description: 'Document ID' },
                title: { type: 'string', description: 'New title' },
                content: { type: 'string', description: 'New HTML content' },
              },
              required: ['project_id', 'document_id'],
            },
          },
          {
            name: 'trash_document',
            description: 'Move a document to trash',
            inputSchema: {
              type: 'object',
              properties: {
                project_id: { type: 'string', description: 'Project ID' },
                document_id: { type: 'string', description: 'Document ID' },
              },
              required: ['project_id', 'document_id'],
            },
          },
    
          // File tools
          {
            name: 'get_uploads',
            description: 'List uploads in a project or vault',
            inputSchema: {
              type: 'object',
              properties: {
                project_id: { type: 'string', description: 'Project ID' },
                vault_id: { type: 'string', description: 'Optional vault ID to limit to specific vault' },
              },
              required: ['project_id'],
            },
          },
    
          // Webhook tools
          {
            name: 'get_webhooks',
            description: 'List webhooks for a project',
            inputSchema: {
              type: 'object',
              properties: {
                project_id: { type: 'string', description: 'Project ID' },
              },
              required: ['project_id'],
            },
          },
          {
            name: 'create_webhook',
            description: 'Create a webhook',
            inputSchema: {
              type: 'object',
              properties: {
                project_id: { type: 'string', description: 'Project ID' },
                payload_url: { type: 'string', description: 'Payload URL' },
                types: { type: 'array', items: { type: 'string' }, description: 'Event types' },
              },
              required: ['project_id', 'payload_url'],
            },
          },
          {
            name: 'delete_webhook',
            description: 'Delete a webhook',
            inputSchema: {
              type: 'object',
              properties: {
                project_id: { type: 'string', description: 'Project ID' },
                webhook_id: { type: 'string', description: 'Webhook ID' },
              },
              required: ['project_id', 'webhook_id'],
            },
          },
    
          // Check-in tools
          {
            name: 'get_daily_check_ins',
            description: "Get project's daily checking questionnaire",
            inputSchema: {
              type: 'object',
              properties: {
                project_id: { type: 'string', description: 'The project ID' },
                page: { type: 'number', description: 'Page number for paginated response' },
              },
              required: ['project_id'],
            },
          },
          {
            name: 'get_question_answers',
            description: 'Get answers on daily check-in question',
            inputSchema: {
              type: 'object',
              properties: {
                project_id: { type: 'string', description: 'The project ID' },
                question_id: { type: 'string', description: 'The question ID' },
                page: { type: 'number', description: 'Page number for paginated response' },
              },
              required: ['project_id', 'question_id'],
            },
          },
        ],
      };
    });
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden of behavioral disclosure. While 'create' implies a write operation, the description doesn't address critical behavioral aspects such as required permissions, whether the step is automatically saved, what happens on validation errors, or the response format. This leaves significant gaps for a mutation tool with no annotation coverage.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence that directly states the tool's purpose without unnecessary words. It's front-loaded with the core action and resource, making it easy to parse quickly. Every word earns its place, achieving optimal conciseness for this context.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given that this is a mutation tool with no annotations and no output schema, the description is incomplete. It lacks information about behavioral traits (e.g., error handling, permissions), usage context, and what the tool returns. While the schema covers parameters well, the overall context for safe and effective use is insufficient.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all 5 parameters thoroughly. The description adds no additional parameter information beyond what's in the schema (e.g., it doesn't clarify relationships between parameters like 'card_id' and 'project_id'). With high schema coverage, the baseline score of 3 is appropriate as the description doesn't enhance parameter understanding.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('create') and resource ('new step (sub-task) for a card'), making the purpose immediately understandable. It distinguishes this from sibling tools like 'create_card' (which creates cards) and 'complete_card_step' (which completes steps). However, it doesn't specify what a 'step' entails beyond 'sub-task', leaving some ambiguity about its exact function.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives. It doesn't mention prerequisites (e.g., needing an existing card), exclusions, or comparisons to similar tools like 'create_card' or 'update_card'. Without this context, users must infer usage from the tool name and parameters alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Related Tools

Latest Blog Posts

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/jhliberty/basecamp-mcp-server'

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