search-epics
Find and filter Shortcut epics by ID, name, state, owner, team, dates, and other criteria to locate specific project initiatives.
Instructions
Find Shortcut epics.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | Find only epics with the specified public ID | |
| name | No | Find only epics matching the specified name | |
| description | No | Find only epics matching the specified description | |
| state | No | Find only epics matching the specified state | |
| objective | No | Find only epics matching the specified objective | |
| 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 only epics matching the specified team. Should be a team's mention name. | |
| comment | No | Find only epics matching the specified comment | |
| 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. | |
| isOverdue | No | Find only entities that are overdue when true, or only entities that are not overdue 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. | |
| hasComment | No | Find only entities that have a comment when true, or only entities that do not have a comment when false. Example: hasOwner: true will find stories with an owner, hasOwner: false will find stories without an owner. | |
| hasDeadline | No | Find only entities that have a deadline when true, or only entities that do not have a deadline when false. Example: hasOwner: true will find stories with an owner, hasOwner: false will find stories without an owner. | |
| hasLabel | No | Find only entities that have a label when true, or only entities that do not have a label 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"). | |
| due | 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"). |
Input Schema (JSON Schema)
{
"properties": {
"comment": {
"description": "Find only epics matching the specified comment",
"type": "string"
},
"completed": {
"description": "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\").",
"pattern": "^(today|tomorrow|yesterday|\\d{4}-\\d{2}-\\d{2}|today\\.\\.\\*|\\*\\.\\.today|yesterday\\.\\.\\*|\\*\\.\\.yesterday|tomorrow\\.\\.\\*|\\*\\.\\.tomorrow|\\d{4}-\\d{2}-\\d{2}\\.\\.\\*|\\*\\.\\.\\d{4}-\\d{2}-\\d{2}|\\d{4}-\\d{2}-\\d{2}\\.\\.\\d{4}-\\d{2}-\\d{2})$",
"type": "string"
},
"created": {
"description": "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\").",
"pattern": "^(today|tomorrow|yesterday|\\d{4}-\\d{2}-\\d{2}|today\\.\\.\\*|\\*\\.\\.today|yesterday\\.\\.\\*|\\*\\.\\.yesterday|tomorrow\\.\\.\\*|\\*\\.\\.tomorrow|\\d{4}-\\d{2}-\\d{2}\\.\\.\\*|\\*\\.\\.\\d{4}-\\d{2}-\\d{2}|\\d{4}-\\d{2}-\\d{2}\\.\\.\\d{4}-\\d{2}-\\d{2})$",
"type": "string"
},
"description": {
"description": "Find only epics matching the specified description",
"type": "string"
},
"due": {
"description": "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\").",
"pattern": "^(today|tomorrow|yesterday|\\d{4}-\\d{2}-\\d{2}|today\\.\\.\\*|\\*\\.\\.today|yesterday\\.\\.\\*|\\*\\.\\.yesterday|tomorrow\\.\\.\\*|\\*\\.\\.tomorrow|\\d{4}-\\d{2}-\\d{2}\\.\\.\\*|\\*\\.\\.\\d{4}-\\d{2}-\\d{2}|\\d{4}-\\d{2}-\\d{2}\\.\\.\\d{4}-\\d{2}-\\d{2})$",
"type": "string"
},
"hasComment": {
"description": "Find only entities that have a comment when true, or only entities that do not have a comment when false. Example: hasOwner: true will find stories with an owner, hasOwner: false will find stories without an owner.",
"type": "boolean"
},
"hasDeadline": {
"description": "Find only entities that have a deadline when true, or only entities that do not have a deadline when false. Example: hasOwner: true will find stories with an owner, hasOwner: false will find stories without an owner.",
"type": "boolean"
},
"hasLabel": {
"description": "Find only entities that have a label when true, or only entities that do not have a label when false. Example: hasOwner: true will find stories with an owner, hasOwner: false will find stories without an owner.",
"type": "boolean"
},
"hasOwner": {
"description": "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.",
"type": "boolean"
},
"id": {
"description": "Find only epics with the specified public ID",
"type": "number"
},
"isArchived": {
"default": false,
"description": "Find only entities that are archived when true, or only entities that are not archived when false.",
"type": "boolean"
},
"isDone": {
"description": "Find only entities that are completed when true, or only entities that are not completed when false.",
"type": "boolean"
},
"isOverdue": {
"description": "Find only entities that are overdue when true, or only entities that are not overdue when false.",
"type": "boolean"
},
"isStarted": {
"description": "Find only entities that are started when true, or only entities that are not started when false.",
"type": "boolean"
},
"isUnstarted": {
"description": "Find only entities that are unstarted when true, or only entities that are not unstarted when false.",
"type": "boolean"
},
"name": {
"description": "Find only epics matching the specified name",
"type": "string"
},
"objective": {
"description": "Find only epics matching the specified objective",
"type": "number"
},
"owner": {
"description": "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.",
"type": "string"
},
"requester": {
"description": "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.",
"type": "string"
},
"state": {
"description": "Find only epics matching the specified state",
"enum": [
"unstarted",
"started",
"done"
],
"type": "string"
},
"team": {
"description": "Find only epics matching the specified team. Should be a team's mention name.",
"type": "string"
},
"updated": {
"description": "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\").",
"pattern": "^(today|tomorrow|yesterday|\\d{4}-\\d{2}-\\d{2}|today\\.\\.\\*|\\*\\.\\.today|yesterday\\.\\.\\*|\\*\\.\\.yesterday|tomorrow\\.\\.\\*|\\*\\.\\.tomorrow|\\d{4}-\\d{2}-\\d{2}\\.\\.\\*|\\*\\.\\.\\d{4}-\\d{2}-\\d{2}|\\d{4}-\\d{2}-\\d{2}\\.\\.\\d{4}-\\d{2}-\\d{2})$",
"type": "string"
}
},
"type": "object"
}
Implementation Reference
- src/tools/epics.ts:79-91 (handler)The searchEpics method that executes the 'search-epics' tool: builds query using helpers, calls client.searchEpics, formats results.async searchEpics(params: QueryParams) { const currentUser = await this.client.getCurrentUser(); const query = await buildSearchQuery(params, currentUser); const { epics, total } = await this.client.searchEpics(query); if (!epics) throw new Error(`Failed to search for epics matching your query: "${query}"`); if (!epics.length) return this.toResult(`Result: No epics found.`); return this.toResult( `Result (first ${epics.length} shown of ${total} total epics found):`, await this.entitiesWithRelatedEntities(epics, "epics"), ); }
- src/tools/epics.ts:20-62 (registration)Registers the 'search-epics' tool with MCP server, including description and input schema, delegates to searchEpics handler.server.tool( "search-epics", "Find Shortcut epics.", { id: z.number().optional().describe("Find only epics with the specified public ID"), name: z.string().optional().describe("Find only epics matching the specified name"), description: z .string() .optional() .describe("Find only epics matching the specified description"), state: z .enum(["unstarted", "started", "done"]) .optional() .describe("Find only epics matching the specified state"), objective: z .number() .optional() .describe("Find only epics matching the specified objective"), owner: user("owner"), requester: user("requester"), team: z .string() .optional() .describe( "Find only epics matching the specified team. Should be a team's mention name.", ), comment: z.string().optional().describe("Find only epics matching the specified comment"), isUnstarted: is("unstarted"), isStarted: is("started"), isDone: is("completed"), isArchived: is("archived").default(false), isOverdue: is("overdue"), hasOwner: has("an owner"), hasComment: has("a comment"), hasDeadline: has("a deadline"), hasLabel: has("a label"), created: date(), updated: date(), completed: date(), due: date(), }, async (params) => await tools.searchEpics(params), );
- src/tools/epics.ts:23-60 (schema)Zod-based input schema defining all parameters for the search-epics tool.{ id: z.number().optional().describe("Find only epics with the specified public ID"), name: z.string().optional().describe("Find only epics matching the specified name"), description: z .string() .optional() .describe("Find only epics matching the specified description"), state: z .enum(["unstarted", "started", "done"]) .optional() .describe("Find only epics matching the specified state"), objective: z .number() .optional() .describe("Find only epics matching the specified objective"), owner: user("owner"), requester: user("requester"), team: z .string() .optional() .describe( "Find only epics matching the specified team. Should be a team's mention name.", ), comment: z.string().optional().describe("Find only epics matching the specified comment"), isUnstarted: is("unstarted"), isStarted: is("started"), isDone: is("completed"), isArchived: is("archived").default(false), isOverdue: is("overdue"), hasOwner: has("an owner"), hasComment: has("a comment"), hasDeadline: has("a deadline"), hasLabel: has("a label"), created: date(), updated: date(), completed: date(), due: date(), },