|
2 | 2 | GetOrgsResponseBody, |
3 | 3 | GetProjectsResponseBody, |
4 | 4 | MachinePresetName, |
| 5 | + RunStatus, |
5 | 6 | } from "@trigger.dev/core/v3/schemas"; |
6 | 7 | import path, { dirname, join } from "path"; |
7 | 8 | import { x } from "tinyexec"; |
@@ -592,6 +593,154 @@ export function registerGetRunDetailsTool(context: McpContext) { |
592 | 593 | ); |
593 | 594 | } |
594 | 595 |
|
| 596 | +export function registerListRunsTool(context: McpContext) { |
| 597 | + context.server.registerTool( |
| 598 | + "list_runs", |
| 599 | + { |
| 600 | + description: "List all runs for a project", |
| 601 | + inputSchema: { |
| 602 | + projectRef: ProjectRefSchema, |
| 603 | + configPath: z |
| 604 | + .string() |
| 605 | + .describe( |
| 606 | + "The path to the trigger.config.ts file. Only used when the trigger.config.ts file is not at the root dir (like in a monorepo setup). If not provided, we will try to find the config file in the current working directory" |
| 607 | + ) |
| 608 | + .optional(), |
| 609 | + environment: z |
| 610 | + .enum(["dev", "staging", "prod", "preview"]) |
| 611 | + .describe("The environment to trigger the task in") |
| 612 | + .default("dev"), |
| 613 | + branch: z |
| 614 | + .string() |
| 615 | + .describe("The branch to trigger the task in, only used for preview environments") |
| 616 | + .optional(), |
| 617 | + cursor: z |
| 618 | + .string() |
| 619 | + .describe("The cursor to use for pagination, starts with run_") |
| 620 | + .optional(), |
| 621 | + limit: z |
| 622 | + .number() |
| 623 | + .int() |
| 624 | + .describe("The number of runs to list in a single page. Up to 100") |
| 625 | + .optional(), |
| 626 | + status: RunStatus.describe("Filter for runs with this run status").optional(), |
| 627 | + taskIdentifier: z |
| 628 | + .string() |
| 629 | + .describe("Filter for runs that match this task identifier") |
| 630 | + .optional(), |
| 631 | + version: z |
| 632 | + .string() |
| 633 | + .describe("Filter for runs that match this version, e.g. 20250808.3") |
| 634 | + .optional(), |
| 635 | + tag: z.string().describe("Filter for runs that include this tag").optional(), |
| 636 | + from: z |
| 637 | + .string() |
| 638 | + .describe("Filter for runs created after this ISO 8601 timestamp") |
| 639 | + .optional(), |
| 640 | + to: z |
| 641 | + .string() |
| 642 | + .describe("Filter for runs created before this ISO 8601 timestamp") |
| 643 | + .optional(), |
| 644 | + period: z |
| 645 | + .string() |
| 646 | + .describe("Filter for runs created in the last N time period. e.g. 7d, 30d, 365d") |
| 647 | + .optional(), |
| 648 | + machine: MachinePresetName.describe( |
| 649 | + "Filter for runs that match this machine preset" |
| 650 | + ).optional(), |
| 651 | + }, |
| 652 | + }, |
| 653 | + async ({ |
| 654 | + projectRef, |
| 655 | + configPath, |
| 656 | + environment, |
| 657 | + branch, |
| 658 | + cursor, |
| 659 | + limit, |
| 660 | + status, |
| 661 | + taskIdentifier, |
| 662 | + version, |
| 663 | + tag, |
| 664 | + from, |
| 665 | + to, |
| 666 | + period, |
| 667 | + machine, |
| 668 | + }) => { |
| 669 | + context.logger?.log("calling list_runs", { |
| 670 | + projectRef, |
| 671 | + configPath, |
| 672 | + environment, |
| 673 | + branch, |
| 674 | + cursor, |
| 675 | + limit, |
| 676 | + status, |
| 677 | + taskIdentifier, |
| 678 | + version, |
| 679 | + tag, |
| 680 | + from, |
| 681 | + to, |
| 682 | + period, |
| 683 | + machine, |
| 684 | + }); |
| 685 | + |
| 686 | + if (context.options.devOnly && environment !== "dev") { |
| 687 | + return respondWithError( |
| 688 | + `This MCP server is only available for the dev environment. You tried to access the ${environment} environment. Remove the --dev-only flag to access other environments.` |
| 689 | + ); |
| 690 | + } |
| 691 | + |
| 692 | + const projectRefResult = await resolveExistingProjectRef(context, projectRef, configPath); |
| 693 | + |
| 694 | + if (projectRefResult.status === "error") { |
| 695 | + return respondWithError(projectRefResult.error); |
| 696 | + } |
| 697 | + |
| 698 | + const $projectRef = projectRefResult.projectRef; |
| 699 | + |
| 700 | + context.logger?.log("list_runs projectRefResult", { projectRefResult }); |
| 701 | + |
| 702 | + const auth = await mcpAuth({ |
| 703 | + server: context.server, |
| 704 | + defaultApiUrl: context.options.apiUrl, |
| 705 | + profile: context.options.profile, |
| 706 | + context, |
| 707 | + }); |
| 708 | + |
| 709 | + if (!auth.ok) { |
| 710 | + return respondWithError(auth.error); |
| 711 | + } |
| 712 | + |
| 713 | + const apiClient = await createApiClientWithPublicJWT(auth, $projectRef, environment, [ |
| 714 | + "read:runs", |
| 715 | + ]); |
| 716 | + |
| 717 | + if (!apiClient) { |
| 718 | + return respondWithError("Failed to create API client with public JWT"); |
| 719 | + } |
| 720 | + |
| 721 | + const $from = typeof from === "string" ? new Date(from) : undefined; |
| 722 | + const $to = typeof to === "string" ? new Date(to) : undefined; |
| 723 | + |
| 724 | + const result = await apiClient.listRuns({ |
| 725 | + after: cursor, |
| 726 | + limit, |
| 727 | + status, |
| 728 | + taskIdentifier, |
| 729 | + version, |
| 730 | + tag, |
| 731 | + from: $from, |
| 732 | + to: $to, |
| 733 | + period, |
| 734 | + machine, |
| 735 | + }); |
| 736 | + |
| 737 | + return { |
| 738 | + content: [{ type: "text", text: JSON.stringify(result, null, 2) }], |
| 739 | + }; |
| 740 | + } |
| 741 | + ); |
| 742 | +} |
| 743 | + |
595 | 744 | export function registerDeployTool(context: McpContext) { |
596 | 745 | context.server.registerTool( |
597 | 746 | "deploy", |
|
0 commit comments