Skip to main content
Glama

motion_schedules

Retrieve weekly working hours and time zone schedules from Motion's AI-powered calendar platform to manage team availability and scheduling.

Instructions

Get all schedules showing weekly working hours and time zones. The Motion API returns all schedules with no filtering options.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
operationNoOperation to perform

Implementation Reference

  • The ScheduleHandler class implements the tool logic. The handle method receives MotionSchedulesArgs (unused since only 'list' operation is supported) and calls handleList() which retrieves schedules from the Motion API service and formats them using formatScheduleList.
    import { BaseHandler } from './base/BaseHandler';
    import { McpToolResponse } from '../types/mcp';
    import { MotionSchedulesArgs } from '../types/mcp-tool-args';
    import { formatScheduleList } from '../utils';
    
    export class ScheduleHandler extends BaseHandler {
      async handle(_args: MotionSchedulesArgs): Promise<McpToolResponse> {
        try {
          return await this.handleList();
        } catch (error: unknown) {
          return this.handleError(error);
        }
      }
    
      private async handleList(): Promise<McpToolResponse> {
        const schedules = await this.motionService.getSchedules();
        return formatScheduleList(schedules);
      }
    }
  • The getSchedules() method in MotionApiService fetches all schedules from the Motion API endpoint /schedules. It uses caching (scheduleCache), validates the response against SchedulesListResponseSchema, and handles both array and wrapped response formats.
    async getSchedules(): Promise<MotionSchedule[]> {
      const cacheKey = 'schedules:all';
    
      return this.scheduleCache.withCache(cacheKey, async () => {
        try {
          mcpLog(LOG_LEVELS.DEBUG, 'Fetching schedules from Motion API', {
            method: 'getSchedules'
          });
    
          const response: AxiosResponse<ListResponse<MotionSchedule>> = await this.requestWithRetry(() => this.client.get('/schedules'));
    
          // Validate response against schema
          const validatedResponse = this.validateResponse(
            response.data,
            SchedulesListResponseSchema,
            'getSchedules'
          );
    
          // Handle both wrapped and unwrapped responses
          const schedules = Array.isArray(validatedResponse)
            ? validatedResponse
            : validatedResponse.schedules || [];
          const schedulesArray = Array.isArray(schedules) ? schedules : [];
    
          mcpLog(LOG_LEVELS.INFO, 'Schedules fetched successfully', {
            method: 'getSchedules',
            count: schedulesArray.length
          });
    
          return schedulesArray;
        } catch (error: unknown) {
          mcpLog(LOG_LEVELS.ERROR, 'Failed to fetch schedules', {
            method: 'getSchedules',
            error: getErrorMessage(error),
            apiStatus: isAxiosError(error) ? error.response?.status : undefined,
            apiMessage: isAxiosError(error) ? error.response?.data?.message : undefined
          });
          throw this.formatApiError(error, 'fetch', 'schedule');
        }
      });
    }
  • The HandlerFactory.registerHandlers() method maps TOOL_NAMES.SCHEDULES (which is 'motion_schedules') to the ScheduleHandler class, enabling tool instantiation when requested.
    private registerHandlers(): void {
      this.handlers.set(TOOL_NAMES.TASKS, TaskHandler);
      this.handlers.set(TOOL_NAMES.PROJECTS, ProjectHandler);
      this.handlers.set(TOOL_NAMES.WORKSPACES, WorkspaceHandler);
      this.handlers.set(TOOL_NAMES.USERS, UserHandler);
      this.handlers.set(TOOL_NAMES.SEARCH, SearchHandler);
      this.handlers.set(TOOL_NAMES.COMMENTS, CommentHandler);
      this.handlers.set(TOOL_NAMES.CUSTOM_FIELDS, CustomFieldHandler);
      this.handlers.set(TOOL_NAMES.RECURRING_TASKS, RecurringTaskHandler);
      this.handlers.set(TOOL_NAMES.SCHEDULES, ScheduleHandler);
      this.handlers.set(TOOL_NAMES.STATUSES, StatusHandler);
    }
  • The schedulesToolDefinition defines the MCP tool interface with name 'motion_schedules', description, and input schema that accepts an 'operation' parameter (enum: ['list']).
    export const schedulesToolDefinition: McpToolDefinition = {
      name: TOOL_NAMES.SCHEDULES,
      description: "Get all schedules showing weekly working hours and time zones. The Motion API returns all schedules with no filtering options.",
      inputSchema: {
        type: "object",
        properties: {
          operation: {
            type: "string",
            enum: ["list"],
            description: "Operation to perform"
          }
        },
        additionalProperties: false
      }
    };
  • The formatScheduleList() helper function formats the array of MotionSchedule objects into a user-readable MCP response, displaying schedule name, timezone, and working days count.
    export function formatScheduleList(schedules: MotionSchedule[]): CallToolResult {
      // Add null safety check for the array itself
      if (!schedules || !Array.isArray(schedules) || schedules.length === 0) {
        return formatMcpSuccess("No schedules found.");
      }
      
      const scheduleFormatter = (schedule: MotionSchedule) => {
        // Defensive programming for nested schedule object
        if (!schedule) {
          return '- Invalid schedule entry';
        }
        
        const name = schedule.name || 'Unnamed';
        const timezone = schedule.timezone || 'Unknown timezone';
        
        // Count working days if schedule details are available
        let workingDays = '';
        if (schedule.schedule && typeof schedule.schedule === 'object') {
          const days = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday'];
          const activeDays = days.filter(day => 
            Array.isArray(schedule.schedule[day as keyof MotionScheduleDetails]) && 
            schedule.schedule[day as keyof MotionScheduleDetails]!.length > 0
          );
          workingDays = activeDays.length > 0 
            ? ` | Working days: ${activeDays.length}/7` 
            : ' | No working hours defined';
        } else {
          workingDays = ' | Schedule details unavailable';
        }
        
        return `- ${name} (${timezone})${workingDays}`;
      };
      
      return formatListResponse(schedules, `Found ${schedules.length} schedule${schedules.length === 1 ? '' : 's'}`, scheduleFormatter);
    }

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observedv2.6.0

TDQS

A3.8/5.0
Behavior3/5

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

With no annotations provided, the description carries the burden. It discloses that the API returns all schedules without filtering, which is useful. However, it does not explicitly confirm read-only safety, authentication needs, rate limits, or pagination, leaving modest gaps for a simple get-all tool.

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 short sentences effectively convey the purpose and a key limitation without redundancy. The description is front-loaded with the action and resource.

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

Completeness4/5

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

For a simple one-parameter list tool with no output schema, the description captures the essential return content and unfiltered behavior. It lacks explicit details on response structure or authentication, but given the simplicity, it is nearly complete.

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% for the single 'operation' parameter, which already has an enum and description. The tool description does not add extra parameter context, so the baseline 3 is appropriate.

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 uses a specific verb 'Get' with the resource 'schedules' and specifies the key data returned ('weekly working hours and time zones'). This clearly differentiates it from sibling tools like motion_tasks or motion_projects.

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

Usage Guidelines3/5

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

The description implies use for retrieving schedule data, but it does not explicitly state when to use this over alternatives or mention any exclusions. The note about 'no filtering options' gives some contextual limitation but lacks direct usage guidance.

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