Skip to content

Latest commit

 

History

History
89 lines (58 loc) · 3.49 KB

CLAUDE.md

File metadata and controls

89 lines (58 loc) · 3.49 KB

Todoist MCP Server - Development Guidelines

For repo structure, architecture, shared utilities, and where things live, read CODEBASE.md first. This file covers the rules; CODEBASE.md is the map.

Tool Schema Design Rules

Output schemas must never use .nullable()

structuredContent is sanitised with removeNullFields before it leaves the server, so a null can never reach a client. A nullable output field therefore declares a value the tool cannot deliver: the MCP SDK validates the sanitised payload against the declared outputSchema and fails the whole call with Output validation error the moment that field is stripped.

Declare the field .optional() instead and leave the key out of structuredContent (foo: value ?? undefined) when there is nothing to report. src/tools/output-schema-nullability.test.ts enforces this across every registered tool.

Removing/Clearing Optional Fields

When you need to support clearing an optional field:

  1. Use a special string value (not null - avoids LLM provider compatibility issues, with Gemini in particular)

    • For assignments: use "unassign"
    • For other fields: use "remove" or similar descriptive string
  2. Handle both legacy and new patterns in runtime logic for backward compatibility:

    if (fieldValue === null || fieldValue === 'remove') {
        // Convert to null for API call
        updateArgs = { ...updateArgs, fieldName: null }
    }
  3. Update schema description to document the special string value

Examples from Codebase

  • PR #181: Fixed responsibleUser field - changed from .nullable() to using "unassign" string
  • Latest commit: Fixed deadlineDate field - changed from .nullable() to using "remove" string

Why This Matters

  • Ensures compatibility with all LLM providers (OpenAI, Anthropic, Gemini, etc.)
  • Maintains backward compatibility through dual handling
  • Creates self-documenting APIs with explicit action strings

Testing Requirements

When adding new tool parameters:

  1. Add comprehensive test coverage for new fields
  2. Test setting values
  3. Test clearing values (if applicable)
  4. Verify build and type checking pass
  5. Run full test suite (all 333+ tests must pass)

Documentation Requirements

When adding new tool features:

  1. Update tool schema descriptions in the source file
  2. Update src/mcp-server.ts tool usage guidelines
  3. Add tests demonstrating the feature
  4. Include examples in descriptions where helpful

Keeping CODEBASE.md accurate

CODEBASE.md is a structural map, not a file index. Update it when structure changes — not on every new file. Triggers:

  • new top-level dir under src/, or a new tool-file category
  • a new broadly-reusable helper in src/utils/ (the "don't reimplement" list)
  • changes to the tool contract, registration flow, auth, or build/test/release tooling

Adding a single tool in an existing category or a narrowly-scoped helper used by one caller does not require an update.

Running Tools Directly

Use scripts/run-tool.ts to execute any tool without the MCP server:

npx tsx scripts/run-tool.ts <tool-name> '<json-args>'
npx tsx scripts/run-tool.ts --list  # list all tools

Examples:

npx tsx scripts/run-tool.ts add-tasks '{"tasks":[{"content":"Test task"}]}'
npx tsx scripts/run-tool.ts find-tasks '{"searchText":"meeting"}'
npx tsx scripts/run-tool.ts get-overview '{}'

Requires TODOIST_API_KEY in .env (and optionally TODOIST_BASE_URL).