Find runbooks in a project
find_runbooksRetrieve runbooks for a project, either by ID for a specific summary or list all (filtered by name if desired). Each summary includes snapshot, multi-tenancy mode, and environment scope for validating targets before executing.
Instructions
Find runbooks in an Octopus Deploy project.
Two modes, picked by which arguments are supplied:
runbookId → fetch the summary for that runbook.
neither → list all runbooks in the project (optionally filtered by partialName).
Each summary includes the publishedRunbookSnapshotId (which run_runbook uses by default), the multiTenancyMode, and the environmentScope so callers can determine which environments and tenants are valid targets before invoking run_runbook.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Implementation Reference
- src/tools/findRunbooks.ts:64-171 (handler)The main handler function 'registerFindRunbooksTool' which registers the 'find_runbooks' tool with the MCP server. Contains the core logic: validates the project exists, then either fetches a single runbook by ID or lists runbooks (optionally filtered by partialName). Includes error handling via handleOctopusApiError.
export function registerFindRunbooksTool(server: McpServer) { server.registerTool( "find_runbooks", { title: "Find runbooks in a project", description: `Find runbooks in an Octopus Deploy project. Two modes, picked by which arguments are supplied: - runbookId → fetch the summary for that runbook. - neither → list all runbooks in the project (optionally filtered by partialName). Each summary includes the publishedRunbookSnapshotId (which run_runbook uses by default), the multiTenancyMode, and the environmentScope so callers can determine which environments and tenants are valid targets before invoking run_runbook.`, inputSchema: findRunbooksSchema, annotations: READ_ONLY_TOOL_ANNOTATIONS, }, async ({ spaceName, projectName, runbookId, partialName, skip, take }) => { try { const client = await Client.create( getClientConfigurationFromEnvironment(), ); const projectRepository = new ProjectRepository(client, spaceName); const projectMatches = await projectRepository.list({ partialName: projectName, take: 100, }); const project = projectMatches.Items.find( (p) => p.Name === projectName, ); if (!project) { // Returned directly (not thrown) so the error surfaces to the LLM // with a project-specific message. handleOctopusApiError below would // otherwise rewrite a thrown "Project not found" into a misleading // "Space not found" because it requires entityId for the entity // branch and falls through to the space branch when entityId is // undefined (we haven't reached the runbook lookup yet). return { content: [ { type: "text", text: JSON.stringify( { success: false, error: `Project '${projectName}' not found in space '${spaceName}'. ` + `Use list_projects to find valid project names. Project names are case-sensitive.`, }, null, 2, ), }, ], isError: true, }; } const runbookRepository = new RunbookRepository( client, spaceName, project, ); if (runbookId) { const runbook = await runbookRepository.get(runbookId); return { content: [ { type: "text", text: JSON.stringify(runbookSummary(runbook, spaceName)), }, ], }; } const runbooksResponse = await runbookRepository.list({ partialName, skip, take, }); return { content: [ { type: "text", text: JSON.stringify({ totalResults: runbooksResponse.TotalResults, itemsPerPage: runbooksResponse.ItemsPerPage, numberOfPages: runbooksResponse.NumberOfPages, lastPageNumber: runbooksResponse.LastPageNumber, items: runbooksResponse.Items.map((runbook) => runbookSummary(runbook, spaceName), ), }), }, ], }; } catch (error) { handleOctopusApiError(error, { entityType: "runbook", entityId: runbookId, spaceName, helpText: "Use list_projects to find valid project names. Call find_runbooks without runbookId to list all runbooks for a project.", }); } }, ); } - src/tools/findRunbooks.ts:32-62 (schema)Input schema (Zod) for the find_runbooks tool. Defines required fields 'spaceName' and 'projectName', and optional fields 'runbookId', 'partialName', 'skip', 'take'. Uses superRefine validation to reject combining runbookId with partialName.
const findRunbooksSchema = z .object({ spaceName: z.string().describe("Space name."), projectName: z .string() .describe( "Project name. Runbooks are scoped to a project, so this is required for both single fetch and listing.", ), runbookId: z .string() .optional() .describe( "Fetch a single runbook by ID. Mutually exclusive with partialName/skip/take.", ), partialName: z .string() .optional() .describe("Filter listing by partial runbook name (case-insensitive)."), skip: z.number().optional().describe("Pagination offset."), take: z.number().optional().describe("Pagination page size."), }) .superRefine((args, ctx) => { if (args.runbookId && args.partialName) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: "partialName cannot be combined with runbookId. Use runbookId to fetch a single runbook; use partialName to filter the listing.", path: ["partialName"], }); } }); - src/tools/findRunbooks.ts:173-177 (registration)Self-registration via registerToolDefinition(). Registers 'find_runbooks' with toolset 'runbooks', readOnly: true, and points to registerFindRunbooksTool function.
registerToolDefinition({ toolName: "find_runbooks", config: { toolset: "runbooks", readOnly: true }, registerFn: registerFindRunbooksTool, }); - src/tools/findRunbooks.ts:14-30 (helper)Helper function 'runbookSummary' that extracts and returns a summary of a runbook (id, name, description, projectId, runbookProcessId, publishedRunbookSnapshotId, multiTenancyMode, environmentScope, environments, and a resource URI).
function runbookSummary(runbook: Runbook, spaceName: string) { const encodedSpace = encodeURIComponent(spaceName); const encodedId = encodeURIComponent(runbook.Id); return { id: runbook.Id, name: runbook.Name, description: runbook.Description, projectId: runbook.ProjectId, runbookProcessId: runbook.RunbookProcessId, publishedRunbookSnapshotId: runbook.PublishedRunbookSnapshotId, multiTenancyMode: runbook.MultiTenancyMode, environmentScope: runbook.EnvironmentScope, environments: runbook.Environments, resourceUri: `octopus://spaces/${encodedSpace}/runbooks/${encodedId}`, }; } - src/tools/index.ts:26-29 (registration)Import that triggers self-registration of the find_runbooks tool when tools/index.ts is loaded.
import "./findRunbooks.js"; import "./findTenants.js"; import "./findDeploymentTargets.js"; import "./findCertificates.js";