objectives-search
Search and filter Shortcut objectives by ID, name, description, state, owner, team, or date criteria to find specific project goals.
Instructions
Find Shortcut objectives.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| nextPageToken | No | If a next_page_token was returned from the search result, pass it in to get the next page of results. Should be combined with the original search parameters. | |
| id | No | Find objectives matching the specified id | |
| name | No | Find objectives matching the specified name | |
| description | No | Find objectives matching the specified description | |
| state | No | Find objectives matching the specified state | |
| owner | No | Find entities where the owner match the specified user. This must either be the user's mention name or the keyword "me" for the current user. | |
| requester | No | Find entities where the requester match the specified user. This must either be the user's mention name or the keyword "me" for the current user. | |
| team | No | Find objectives matching the specified team. Should be a team mention name. | |
| isUnstarted | No | Find only entities that are unstarted when true, or only entities that are not unstarted when false. | |
| isStarted | No | Find only entities that are started when true, or only entities that are not started when false. | |
| isDone | No | Find only entities that are completed when true, or only entities that are not completed when false. | |
| isArchived | No | Find only entities that are archived when true, or only entities that are not archived when false. | |
| hasOwner | No | Find only entities that have an owner when true, or only entities that do not have an owner when false. Example: hasOwner: true will find stories with an owner, hasOwner: false will find stories without an owner. | |
| created | No | The date in "YYYY-MM-DD" format, or one of the keywords: "yesterday", "today", "tomorrow", or a date range in the format "YYYY-MM-DD..YYYY-MM-DD". The date range can also be open ended by using "*" for one of the bounds. Examples: "2023-01-01", "today", "2023-01-01..*" (from Jan 1, 2023 to any future date), "*.2023-01-31" (any date up to Jan 31, 2023), "today..*" (from today onwards), "*.yesterday" (any date up to yesterday). The keywords cannot be used to calculate relative dates (e.g. the following are not valid: "today-1" or "tomorrow+1"). | |
| updated | No | The date in "YYYY-MM-DD" format, or one of the keywords: "yesterday", "today", "tomorrow", or a date range in the format "YYYY-MM-DD..YYYY-MM-DD". The date range can also be open ended by using "*" for one of the bounds. Examples: "2023-01-01", "today", "2023-01-01..*" (from Jan 1, 2023 to any future date), "*.2023-01-31" (any date up to Jan 31, 2023), "today..*" (from today onwards), "*.yesterday" (any date up to yesterday). The keywords cannot be used to calculate relative dates (e.g. the following are not valid: "today-1" or "tomorrow+1"). | |
| completed | No | The date in "YYYY-MM-DD" format, or one of the keywords: "yesterday", "today", "tomorrow", or a date range in the format "YYYY-MM-DD..YYYY-MM-DD". The date range can also be open ended by using "*" for one of the bounds. Examples: "2023-01-01", "today", "2023-01-01..*" (from Jan 1, 2023 to any future date), "*.2023-01-31" (any date up to Jan 31, 2023), "today..*" (from today onwards), "*.yesterday" (any date up to yesterday). The keywords cannot be used to calculate relative dates (e.g. the following are not valid: "today-1" or "tomorrow+1"). |
Implementation Reference
- src/tools/objectives.ts:28-64 (registration)Registers the 'objectives-search' MCP tool using server.addToolWithReadAccess, including the tool name, description, input schema, and handler reference.server.addToolWithReadAccess( "objectives-search", "Find Shortcut objectives.", { nextPageToken: z .string() .optional() .describe( "If a next_page_token was returned from the search result, pass it in to get the next page of results. Should be combined with the original search parameters.", ), id: z.number().optional().describe("Find objectives matching the specified id"), name: z.string().optional().describe("Find objectives matching the specified name"), description: z .string() .optional() .describe("Find objectives matching the specified description"), state: z .enum(["unstarted", "started", "done"]) .optional() .describe("Find objectives matching the specified state"), owner: user("owner"), requester: user("requester"), team: z .string() .optional() .describe("Find objectives matching the specified team. Should be a team mention name."), isUnstarted: is("unstarted"), isStarted: is("started"), isDone: is("completed"), isArchived: is("archived"), hasOwner: has("an owner"), created: date(), updated: date(), completed: date(), }, async ({ nextPageToken, ...params }) => await tools.searchObjectives(params, nextPageToken), );
- src/tools/objectives.ts:69-86 (handler)Handler function that performs the objectives search: builds query, calls Shortcut client searchMilestones, formats results with pagination.async searchObjectives(params: QueryParams, nextToken?: string) { const currentUser = await this.client.getCurrentUser(); const query = await buildSearchQuery(params, currentUser); const { milestones, total, next_page_token } = await this.client.searchMilestones( query, nextToken, ); if (!milestones) throw new Error(`Failed to search for milestones matching your query: "${query}"`); if (!milestones.length) return this.toResult(`Result: No milestones found.`); return this.toResult( `Result (${milestones.length} shown of ${total} total milestones found):`, await this.entitiesWithRelatedEntities(milestones, "objectives"), next_page_token, ); }
- src/tools/objectives.ts:31-62 (schema)Input schema using Zod validators for the 'objectives-search' tool parameters, including pagination, filters by id, name, state, users, dates, etc.{ nextPageToken: z .string() .optional() .describe( "If a next_page_token was returned from the search result, pass it in to get the next page of results. Should be combined with the original search parameters.", ), id: z.number().optional().describe("Find objectives matching the specified id"), name: z.string().optional().describe("Find objectives matching the specified name"), description: z .string() .optional() .describe("Find objectives matching the specified description"), state: z .enum(["unstarted", "started", "done"]) .optional() .describe("Find objectives matching the specified state"), owner: user("owner"), requester: user("requester"), team: z .string() .optional() .describe("Find objectives matching the specified team. Should be a team mention name."), isUnstarted: is("unstarted"), isStarted: is("started"), isDone: is("completed"), isArchived: is("archived"), hasOwner: has("an owner"), created: date(), updated: date(), completed: date(), },