Skip to main content
Glama

create_milestone

Create a new milestone in a board with a name, optional plain-text description, and due dates. Use edit_document_content to add rich content later.

Instructions

Create a new milestone in a board. The description field is a short plain-text summary (NOT Markdown). To add rich document content, use edit_document_content after creation.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
nameYes
boardIdYes
descriptionNoShort plain-text description of the milestone (metadata, not document content). Do NOT put Markdown here. To add rich document content, use edit_document_content tool after creation.
dueStartNo
dueEndNo

Implementation Reference

  • Input schema definition for 'create_milestone' tool. Defines name (required, max 128 chars), boardId (required), description (optional, max 1024 chars, plain-text only), dueStart (optional), and dueEnd (optional).
    {
      name: 'create_milestone',
      description:
        'Create a new milestone in a board. The description field is a short plain-text summary (NOT Markdown). To add rich document content, use edit_document_content after creation.',
      inputSchema: {
        type: 'object',
        properties: {
          name: { type: 'string', minLength: 1, maxLength: 128 },
          boardId: { type: 'string', minLength: 1 },
          description: {
            type: 'string',
            maxLength: 1024,
            description:
              'Short plain-text description of the milestone (metadata, not document content). Do NOT put Markdown here. To add rich document content, use edit_document_content tool after creation.',
          },
          dueStart: { type: 'string' },
          dueEnd: { type: 'string' },
        },
        required: ['name', 'boardId'],
        additionalProperties: false,
      },
  • src/tools.ts:8-562 (registration)
    The 'create_milestone' tool is registered in the VAIZ_TOOLS array exported from src/tools.ts. This array is imported by proxy-server.ts and merged with remotely fetched tool definitions at runtime.
    export const VAIZ_TOOLS: Tool[] = [
      {
        name: 'search',
        description:
          'Search for entities in YOUR workspace (tasks, projects, users, comments, boards, USER documents). NOT system documentation!',
        inputSchema: {
          type: 'object',
          properties: {
            entityType: {
              type: 'string',
              enum: ['task', 'project', 'user', 'comment', 'board', 'document'],
              default: 'task',
            },
            query: { type: 'string', minLength: 1 },
            limit: { type: 'number', minimum: 1, maximum: 50, default: 10 },
          },
          required: ['query'],
          additionalProperties: false,
        },
      },
      {
        name: 'get_tasks',
        description: `Get a filtered list of tasks with pagination. Supports filtering by board, project, assignees, completion status, priorities, milestones, types, and creator.
    
    Examples:
    - My tasks: get_tasks(assignees: [myMemberId])
    - All uncompleted: get_tasks(completed: false)
    - High priority: get_tasks(priorities: ["3"])
    - Specific board: get_tasks(boardId: "...")
    - By type: get_tasks(types: ["typeId1", "typeId2"])
    - By group: get_tasks(boardId: "...", groupId: "...")
    - Created by member: get_tasks(createdBy: "memberId")
    - Next page: get_tasks(skip: 50, limit: 50)`,
        inputSchema: {
          type: 'object',
          properties: {
            boardId: { type: 'string' },
            projectId: { type: 'string' },
            assignees: { type: 'array', items: { type: 'string' } },
            completed: { type: 'boolean' },
            priorities: {
              type: 'array',
              items: { type: 'string', enum: ['0', '1', '2', '3'] },
            },
            milestones: { type: 'array', items: { type: 'string' } },
            types: { type: 'array', items: { type: 'string' } },
            groupId: { type: 'string' },
            createdBy: { type: 'string' },
            limit: { type: 'number', minimum: 1, maximum: 100, default: 50 },
            skip: { type: 'number', minimum: 0, default: 0 },
          },
          additionalProperties: false,
        },
      },
      {
        name: 'get_task',
        description:
          'Get detailed information about a specific task by database ID or HRID (e.g., "PRJ-123")',
        inputSchema: {
          type: 'object',
          properties: {
            taskId: { type: 'string', minLength: 1 },
          },
          required: ['taskId'],
          additionalProperties: false,
        },
      },
      {
        name: 'create_task',
        description: 'Create a new task in the Vaiz workspace',
        inputSchema: {
          type: 'object',
          properties: {
            data: {
              type: 'object',
              properties: {
                name: { type: 'string', minLength: 1 },
                boardId: { type: 'string', minLength: 1 },
                groupId: { type: 'string' },
                description: {
                  type: 'string',
                  description:
                    'Task document content in Markdown format. Supports headings, lists, code blocks, tables, etc. Converted to rich document content automatically.',
                },
                priority: {
                  type: 'string',
                  enum: ['0', '1', '2', '3'],
                  default: '1',
                },
                assignees: { type: 'array', items: { type: 'string' } },
                followers: {
                  type: 'object',
                  additionalProperties: { type: 'string' },
                },
                dueStart: { type: 'string' },
                dueEnd: { type: 'string' },
                parentTask: { type: 'string' },
                milestones: { type: 'array', items: { type: 'string' } },
                types: { type: 'array', items: { type: 'string' } },
              },
              required: ['name', 'boardId'],
              additionalProperties: false,
            },
          },
          required: ['data'],
          additionalProperties: false,
        },
      },
      {
        name: 'edit_task',
        description: 'Edit an existing task in the Vaiz workspace',
        inputSchema: {
          type: 'object',
          properties: {
            data: {
              type: 'object',
              properties: {
                taskId: { type: 'string', minLength: 1 },
                name: { type: 'string' },
                assignees: { type: 'array', items: { type: 'string' } },
                completed: { type: 'boolean' },
                dueStart: { type: 'string' },
                dueEnd: { type: 'string' },
                priority: {
                  type: 'string',
                  enum: ['0', '1', '2', '3'],
                },
                coverUrl: { type: 'string' },
                types: { type: 'array', items: { type: 'string' } },
                milestones: { type: 'array', items: { type: 'string' } },
                group: { type: 'string' },
              },
              required: ['taskId'],
              additionalProperties: false,
            },
          },
          required: ['data'],
          additionalProperties: false,
        },
      },
      {
        name: 'get_task_comments',
        description: 'Get all comments for a specific task',
        inputSchema: {
          type: 'object',
          properties: {
            taskId: { type: 'string', minLength: 1 },
          },
          required: ['taskId'],
          additionalProperties: false,
        },
      },
      {
        name: 'create_task_comment',
        description: 'Create a new comment on a task',
        inputSchema: {
          type: 'object',
          properties: {
            taskId: { type: 'string', minLength: 1 },
            content: { type: 'string', minLength: 1 },
            replyTo: { type: 'string' },
          },
          required: ['taskId', 'content'],
          additionalProperties: false,
        },
      },
      {
        name: 'get_task_history',
        description: 'Get history of changes for a specific task',
        inputSchema: {
          type: 'object',
          properties: {
            limit: { type: 'number', minimum: 1, maximum: 100, default: 50 },
            keys: { type: 'array', items: { type: 'string' } },
            excludeKeys: { type: 'array', items: { type: 'string' } },
            dateRangeStart: { type: 'string' },
            dateRangeEnd: { type: 'string' },
            createdBy: { type: 'array', items: { type: 'string' } },
            taskId: { type: 'string', minLength: 1 },
          },
          required: ['taskId'],
          additionalProperties: false,
        },
      },
      {
        name: 'set_task_blocker',
        description:
          'Toggle a blocker relationship between two tasks. Direction is relative to taskId: "blockers" = tasks that block taskId, "blocking" = tasks that taskId blocks. Note: taskId and blockerTaskId require database IDs (use search to find tasks by HRID like "PRJ-21" to get their database IDs)',
        inputSchema: {
          type: 'object',
          properties: {
            taskId: { type: 'string' },
            blockerTaskId: { type: 'string' },
            direction: { type: 'string', enum: ['blockers', 'blocking'] },
          },
          required: ['taskId', 'blockerTaskId', 'direction'],
          additionalProperties: false,
        },
      },
      {
        name: 'list_projects',
        description: 'List all projects in the current space',
        inputSchema: {
          type: 'object',
          properties: {},
        },
      },
      {
        name: 'get_project',
        description: 'Get detailed information about a specific project by ID',
        inputSchema: {
          type: 'object',
          properties: {
            projectId: { type: 'string', minLength: 1 },
          },
          required: ['projectId'],
          additionalProperties: false,
        },
      },
      {
        name: 'get_project_history',
        description:
          'Get history of all activities in a specific project across the workspace',
        inputSchema: {
          type: 'object',
          properties: {
            limit: { type: 'number', minimum: 1, maximum: 100, default: 50 },
            keys: { type: 'array', items: { type: 'string' } },
            excludeKeys: { type: 'array', items: { type: 'string' } },
            dateRangeStart: { type: 'string' },
            dateRangeEnd: { type: 'string' },
            createdBy: { type: 'array', items: { type: 'string' } },
            projectId: { type: 'string', minLength: 1 },
            entityTypes: {
              type: 'array',
              items: {
                type: 'string',
                enum: ['task', 'project', 'board', 'document', 'milestone'],
              },
            },
            taskIds: { type: 'array', items: { type: 'string' } },
            boardIds: { type: 'array', items: { type: 'string' } },
          },
          required: ['projectId'],
          additionalProperties: false,
        },
      },
      {
        name: 'list_boards',
        description: `List all accessible boards in the current space, optionally filtered by project.
    
    Examples:
    - All boards: list_boards()
    - Boards in project: list_boards(projectId: "...")`,
        inputSchema: {
          type: 'object',
          properties: {
            projectId: { type: 'string' },
          },
          additionalProperties: false,
        },
      },
      {
        name: 'get_board',
        description: 'Get detailed information about a specific board by ID',
        inputSchema: {
          type: 'object',
          properties: {
            boardId: { type: 'string', minLength: 1 },
          },
          required: ['boardId'],
          additionalProperties: false,
        },
      },
      {
        name: 'get_document',
        description:
          'Get detailed information about a USER document in workspace. For SYSTEM help, use read_resource!',
        inputSchema: {
          type: 'object',
          properties: {
            documentId: { type: 'string', minLength: 1 },
          },
          required: ['documentId'],
          additionalProperties: false,
        },
      },
      {
        name: 'get_document_comments',
        description: 'Get all comments for a specific document',
        inputSchema: {
          type: 'object',
          properties: {
            documentId: { type: 'string', minLength: 1 },
          },
          required: ['documentId'],
          additionalProperties: false,
        },
      },
      {
        name: 'get_document_history',
        description: 'Get history of changes for a specific document',
        inputSchema: {
          type: 'object',
          properties: {
            limit: { type: 'number', minimum: 1, maximum: 100, default: 50 },
            keys: { type: 'array', items: { type: 'string' } },
            excludeKeys: { type: 'array', items: { type: 'string' } },
            dateRangeStart: { type: 'string' },
            dateRangeEnd: { type: 'string' },
            createdBy: { type: 'array', items: { type: 'string' } },
            documentId: { type: 'string', minLength: 1 },
          },
          required: ['documentId'],
          additionalProperties: false,
        },
      },
      {
        name: 'edit_document_content',
        description:
          'Edit the document content (description) of a task, milestone, or standalone document. Can append to existing content or replace it entirely.',
        inputSchema: {
          type: 'object',
          properties: {
            data: {
              type: 'object',
              properties: {
                documentId: { type: 'string', minLength: 1 },
                description: { type: 'string', minLength: 1, maxLength: 50000 },
                replace: {
                  type: 'boolean',
                  default: false,
                  description:
                    'If true, replaces the entire document content. If false (default), appends to existing content.',
                },
              },
              required: ['documentId', 'description'],
              additionalProperties: false,
            },
          },
          required: ['data'],
          additionalProperties: false,
        },
      },
      {
        name: 'list_milestones',
        description:
          'List all milestones in the current space, optionally filtered by board or project',
        inputSchema: {
          type: 'object',
          properties: {
            boardId: { type: 'string' },
            projectId: { type: 'string' },
          },
          additionalProperties: false,
        },
      },
      {
        name: 'get_milestone',
        description:
          'Get detailed information about a specific milestone by ID',
        inputSchema: {
          type: 'object',
          properties: {
            milestoneId: { type: 'string', minLength: 1 },
          },
          required: ['milestoneId'],
          additionalProperties: false,
        },
      },
      {
        name: 'create_milestone',
        description:
          'Create a new milestone in a board. The description field is a short plain-text summary (NOT Markdown). To add rich document content, use edit_document_content after creation.',
        inputSchema: {
          type: 'object',
          properties: {
            name: { type: 'string', minLength: 1, maxLength: 128 },
            boardId: { type: 'string', minLength: 1 },
            description: {
              type: 'string',
              maxLength: 1024,
              description:
                'Short plain-text description of the milestone (metadata, not document content). Do NOT put Markdown here. To add rich document content, use edit_document_content tool after creation.',
            },
            dueStart: { type: 'string' },
            dueEnd: { type: 'string' },
          },
          required: ['name', 'boardId'],
          additionalProperties: false,
        },
      },
      {
        name: 'list_spaces',
        description:
          'List all available spaces (spaces) for the current user',
        inputSchema: {
          type: 'object',
          properties: {},
        },
      },
      {
        name: 'space_info',
        description:
          'Get detailed information about current space and user permissions',
        inputSchema: {
          type: 'object',
          properties: {},
        },
      },
      {
        name: 'select_space',
        description: 'Select a space to work with',
        inputSchema: {
          type: 'object',
          properties: {
            spaceId: { type: 'string', minLength: 1 },
          },
          required: ['spaceId'],
          additionalProperties: false,
        },
      },
      {
        name: 'current_user',
        description:
          'Get detailed information about current authenticated user',
        inputSchema: {
          type: 'object',
          properties: {},
        },
      },
      {
        name: 'list_members',
        description: 'List all members in the current space',
        inputSchema: {
          type: 'object',
          properties: {},
        },
      },
      {
        name: 'get_member',
        description:
          'Get detailed information about a specific workspace member by ID',
        inputSchema: {
          type: 'object',
          properties: {
            memberId: { type: 'string', minLength: 1 },
          },
          required: ['memberId'],
          additionalProperties: false,
        },
      },
      {
        name: 'get_user_history',
        description:
          'Get history of all activities performed by a specific user in the current workspace',
        inputSchema: {
          type: 'object',
          properties: {
            limit: { type: 'number', minimum: 1, maximum: 100, default: 50 },
            keys: { type: 'array', items: { type: 'string' } },
            excludeKeys: { type: 'array', items: { type: 'string' } },
            dateRangeStart: { type: 'string' },
            dateRangeEnd: { type: 'string' },
            createdBy: { type: 'array', items: { type: 'string' } },
            memberId: { type: 'string', minLength: 1 },
            entityTypes: {
              type: 'array',
              items: {
                type: 'string',
                enum: ['task', 'project', 'board', 'document', 'milestone'],
              },
            },
            taskIds: { type: 'array', items: { type: 'string' } },
            boardIds: { type: 'array', items: { type: 'string' } },
            projectIds: { type: 'array', items: { type: 'string' } },
          },
          required: ['memberId'],
          additionalProperties: false,
        },
      },
      {
        name: 'get_notifications',
        description:
          'Get user notifications with filtering and pagination support',
        inputSchema: {
          type: 'object',
          properties: {
            limit: { type: 'number', minimum: 1, maximum: 100, default: 20 },
            lastLoadedDate: { type: 'number', default: 0 },
            readStatus: { type: 'string', enum: ['All', 'Read', 'Unread'] },
            groups: {
              type: 'array',
              items: {
                type: 'string',
                enum: [
                  'Comments',
                  'DocumentChanges',
                  'Mentions',
                  'Security',
                  'Space',
                  'TaskChanges',
                  'Team',
                  'Import',
                ],
              },
            },
            pinned: { type: 'boolean' },
          },
          additionalProperties: false,
        },
      },
      {
        name: 'get_automations',
        description: 'Get all automations (workflows) for a specific board',
        inputSchema: {
          type: 'object',
          properties: {
            boardId: { type: 'string', minLength: 1 },
          },
          required: ['boardId'],
          additionalProperties: false,
        },
      },
      {
        name: 'list_resources',
        description:
          'List all available MCP resources (dictionaries, workspace data, etc.)',
        inputSchema: {
          type: 'object',
          properties: {},
        },
      },
      {
        name: 'read_resource',
        description:
          'Read content of a specific MCP resource by name. For knowledge base articles, use "vaiz-help-" prefix + article name from the index.',
        inputSchema: {
          type: 'object',
          properties: {
            resourceName: { type: 'string', minLength: 1 },
          },
          required: ['resourceName'],
          additionalProperties: false,
        },
      },
      {
        name: 'ping',
        description: 'Simple ping tool for testing',
        inputSchema: {
          type: 'object',
          properties: {},
        },
      },
    ];
  • Handler registration in the proxy server. When a tools/call request is received, proxyToRemote forwards it to the Vaiz HTTP API. No client-side handler logic exists for create_milestone specifically — the tool is proxied as-is.
      private registerHandlers(): void {
        const lowLevel = this.mcpServer.server;
    
        lowLevel.setRequestHandler(ListToolsRequestSchema, async () => {
          this.log('← tools/list');
          try {
            const result = (await this.proxyToRemote('tools/list')) as {
              tools?: Tool[];
            };
            const remoteTools = result?.tools ?? [];
            return { tools: mergeByName(VAIZ_TOOLS, remoteTools) };
          } catch {
            const cached = this.responseCache.get('tools/list') as {
              tools?: Tool[];
            } | undefined;
            return {
              tools: mergeByName(VAIZ_TOOLS, cached?.tools ?? []),
            };
          }
        });
    
        lowLevel.setRequestHandler(CallToolRequestSchema, async (request) => {
          this.log(`← tools/call ${request.params.name}`);
          const result = await this.proxyToRemote('tools/call', request.params);
          return result as { content: Array<{ type: string; text: string }> };
        });
    
        lowLevel.setRequestHandler(ListPromptsRequestSchema, async () => {
          this.log('← prompts/list');
          try {
            const result = (await this.proxyToRemote('prompts/list')) as {
              prompts?: Prompt[];
            };
            const remotePrompts = result?.prompts ?? [];
            return { prompts: mergeByName(VAIZ_PROMPTS, remotePrompts) };
          } catch {
            const cached = this.responseCache.get('prompts/list') as {
              prompts?: Prompt[];
            } | undefined;
            return {
              prompts: mergeByName(VAIZ_PROMPTS, cached?.prompts ?? []),
            };
          }
        });
    
        lowLevel.setRequestHandler(GetPromptRequestSchema, async (request) => {
          this.log(`← prompts/get ${request.params.name}`);
          const result = await this.proxyToRemote('prompts/get', request.params);
          return result as {
            description?: string;
            messages: Array<{
              role: 'user' | 'assistant';
              content: { type: string; text: string };
            }>;
          };
        });
    
        lowLevel.setRequestHandler(
          ListResourcesRequestSchema,
          async () => {
            this.log('← resources/list');
            try {
              const result = (await this.proxyToRemote('resources/list')) as {
                resources?: Resource[];
              };
              const remoteResources = result?.resources ?? [];
              return { resources: mergeByUri(VAIZ_RESOURCES, remoteResources) };
            } catch {
              const cached = this.responseCache.get('resources/list') as {
                resources?: Resource[];
              } | undefined;
              return {
                resources: mergeByUri(VAIZ_RESOURCES, cached?.resources ?? []),
              };
            }
          },
        );
    
        lowLevel.setRequestHandler(
          ReadResourceRequestSchema,
          async (request) => {
            this.log(`← resources/read ${request.params.uri}`);
            const result = await this.proxyToRemote(
              'resources/read',
              request.params,
            );
            return result as {
              contents: Array<{ uri: string; text?: string; mimeType?: string }>;
            };
          },
        );
      }
    
      // ── lifecycle ────────────────────────────────────────────
    
      async start(): Promise<void> {
        this.log('Starting Vaiz MCP proxy server');
        this.log(`API URL: ${this.apiUrl}`);
        this.log(`Space ID: ${this.spaceId ?? '(not set)'}`);
    
        this.transport = new StdioServerTransport();
        await this.mcpServer.connect(this.transport);
    
        this.log('Server connected via stdio transport');
    
        process.on('SIGINT', async () => {
          this.log('Received SIGINT, shutting down');
          await this.stop();
          process.exit(0);
        });
    
        process.on('SIGTERM', async () => {
          this.log('Received SIGTERM, shutting down');
          await this.stop();
          process.exit(0);
        });
      }
    
      async stop(): Promise<void> {
        await this.mcpServer.close();
      }
    }
    
    export function createVaizMCPProxyServer(
      config?: VaizConfig & { debug?: boolean },
    ): VaizMCPProxyServer {
      return new VaizMCPProxyServer(config);
    }
Behavior2/5

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

No annotations are provided, so the description must carry the burden. It only clarifies that the description field is plain-text and not Markdown. It fails to disclose return behavior, side effects, permissions, or any other runtime effects beyond creation.

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?

Two sentences: the first states the primary action, and the second clarifies a critical constraint on the description parameter. No extraneous information; every word earns its place.

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

Completeness3/5

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

The description covers the core purpose and a key parameter detail but lacks information on return values (e.g., does it return the milestone ID?), prerequisites (e.g., board must exist), and any implicit constraints on due dates. Given the tool's simplicity, it is somewhat complete but has clear gaps.

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

Parameters2/5

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

The schema description coverage is only 20% (only the description parameter has a description). The tool description adds meaning only for the description parameter, stating it should be plain-text and not Markdown. The other four parameters (name, boardId, dueStart, dueEnd) receive no additional explanation, so the description does not compensate for the low coverage.

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

Purpose5/5

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

The description clearly states the tool's purpose: 'Create a new milestone in a board.' It also distinguishes from the sibling tool edit_document_content by specifying that the description field is plain-text and to use edit_document_content for rich content.

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

Usage Guidelines4/5

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

The description implicitly says when to use this tool (to create a milestone) and provides an explicit alternative for rich document content, which helps the agent decide. However, it does not explicitly state when not to use this tool or mention other alternatives.

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

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/vaizcom/vaiz-mcp'

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