Skip to main content
Glama
OctopusDeploy

Octopus Deploy MCP Server

Official

Get deployment details from an Octopus Deploy URL

get_deployment_from_url
Read-onlyIdempotent

Retrieve deployment details from an Octopus Deploy URL, including environment, release, and task ID for log investigation.

Instructions

Get deployment details from an Octopus Deploy deployment URL. Returns comprehensive deployment information including the task ID needed to view execution logs.

Accepts deployment URLs like: https://your-octopus.com/app#/Spaces-1/projects/my-app/deployments/releases/1.0.0/deployments/Deployments-123

Returns:

  • Full deployment details (environment, release, project, created time)

  • taskIdForLogs: the ServerTasks- ID for this deployment

  • taskResourceUri: octopus:// URI for the structured activity tree (resources/read or read_resource)

  • grepTaskLogHint: pre-filled arguments for the grep_task_log tool — call it with a pattern to search the raw log without fetching the whole thing

  • Public URL for web portal access

Recommended workflow for investigating deployment issues:

  1. Call get_deployment_from_url with the deployment URL

  2. Review deployment context (environment, release version, etc.) 3a. Fetch the taskResourceUri for the structured activity tree (step timings, embedded log entries by category), OR 3b. Call grep_task_log with the taskId to search the raw log for a specific error / pattern

Handles space ID to space name resolution automatically.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
urlYesFull Octopus Deploy deployment URL (e.g., https://your-octopus.com/app#/Spaces-1/projects/my-app/deployments/releases/1.0.0/deployments/Deployments-123)

Implementation Reference

  • Core handler function that parses a deployment URL, resolves the space name, fetches the deployment via DeploymentRepository, fetches release details (version + VCS ref), and returns comprehensive deployment info including taskIdForLogs, taskResourceUri, and grepTaskLogHint.
    export async function getDeploymentFromUrl(client: Client, params: GetDeploymentFromUrlParams) {
      const { url } = params;
    
      if (!url) {
        throw new Error("URL is required");
      }
    
      const urlParts = parseOctopusUrl(url);
    
      if (!urlParts.spaceId) {
        throw new Error("Could not extract space ID from URL. URL must contain a space identifier like 'Spaces-1234'");
      }
    
      const spaceName = await resolveSpaceNameFromId(client, urlParts.spaceId);
    
      const deploymentId = extractDeploymentId(url);
    
      if (!deploymentId) {
        throw new Error(
          `Could not extract deployment ID from URL. ` +
          `URL must contain a deployment identifier (Deployments-XXXXX). ` +
          `The provided URL appears to be: ${urlParts.resourceType || 'unknown type'}`
        );
      }
    
      validateEntityId(deploymentId, 'deployment', ENTITY_PREFIXES.deployment);
    
      const deploymentRepository = new DeploymentRepository(client, spaceName);
      let deployment: Deployment;
      try {
        deployment = await deploymentRepository.get(deploymentId);
      } catch (error) {
        handleOctopusApiError(error, {
          entityType: 'deployment',
          entityId: deploymentId,
          spaceName,
          helpText: 'The deployment may have been deleted or you may not have permission to view it. Use list_deployments to find valid deployment IDs.'
        });
      }
    
      let releaseVersion: string | undefined;
      let versionControlReference: { GitRef?: string; GitCommit?: string } | undefined;
      if (deployment.ReleaseId) {
        const releaseRepository = new ReleaseRepository(client, spaceName);
        try {
          const release = await releaseRepository.get(deployment.ReleaseId);
          releaseVersion = release.Version;
          versionControlReference = release.VersionControlReference;
        } catch {
          releaseVersion = undefined;
          versionControlReference = undefined;
        }
      }
    
      const configuration = getClientConfigurationFromEnvironment();
      const publicUrl = releaseVersion
        ? getPublicUrl(
            `${configuration.instanceURL}/app#/{spaceId}/projects/{projectId}/deployments/releases/{releaseVersion}/deployments/{deploymentId}`,
            {
              spaceId: deployment.SpaceId,
              projectId: deployment.ProjectId,
              releaseVersion,
              deploymentId: deployment.Id,
            }
          )
        : undefined;
    
      return {
        deployment: {
          spaceId: deployment.SpaceId,
          id: deployment.Id,
          name: deployment.Name,
          releaseId: deployment.ReleaseId,
          releaseVersion,
          versionControlReference,
          environmentId: deployment.EnvironmentId,
          tenantId: deployment.TenantId,
          projectId: deployment.ProjectId,
          channelId: deployment.ChannelId,
          created: deployment.Created,
          taskId: deployment.TaskId,
          deploymentProcessId: deployment.DeploymentProcessId,
          comments: deployment.Comments,
          formValues: deployment.FormValues,
          queueTime: deployment.QueueTime,
          queueTimeExpiry: deployment.QueueTimeExpiry,
          useGuidedFailure: deployment.UseGuidedFailure,
          specificMachineIds: deployment.SpecificMachineIds,
          excludedMachineIds: deployment.ExcludedMachineIds,
          skipActions: deployment.SkipActions,
          forcePackageDownload: deployment.ForcePackageDownload,
          forcePackageRedeployment: deployment.ForcePackageRedeployment,
          publicUrl,
        },
        resolvedSpaceName: spaceName,
        resolvedDeploymentId: deploymentId,
        taskIdForLogs: deployment.TaskId,
        urlInfo: {
          originalUrl: url,
          extractedSpaceId: urlParts.spaceId,
          extractedDeploymentId: deploymentId,
          resourceType: urlParts.resourceType,
        },
        nextSteps: {
          description: "To inspect this deployment's task: fetch the taskResourceUri for the structured activity tree (steps, timings, embedded log entries), or call grep_task_log with this taskId to search the raw log without inhaling the full body.",
          useTaskId: deployment.TaskId,
          taskResourceUri: `octopus://spaces/${encodeURIComponent(spaceName)}/tasks/${encodeURIComponent(deployment.TaskId)}/details`,
          grepTaskLogHint: {
            tool: "grep_task_log",
            spaceName,
            taskId: deployment.TaskId,
          },
        }
      };
    }
  • Registration function 'registerGetDeploymentFromUrlTool' that calls server.registerTool with the name 'get_deployment_from_url', the Zod input schema, READ_ONLY_TOOL_ANNOTATIONS, and the handler callback. Also calls registerToolDefinition at the bottom to self-register.
    export function registerGetDeploymentFromUrlTool(server: McpServer) {
      server.registerTool(
        'get_deployment_from_url',
        {
          title: 'Get deployment details from an Octopus Deploy URL',
          description: `Get deployment details from an Octopus Deploy deployment URL. Returns comprehensive deployment information including the task ID needed to view execution logs.
    
    Accepts deployment URLs like:
    https://your-octopus.com/app#/Spaces-1/projects/my-app/deployments/releases/1.0.0/deployments/Deployments-123
    
    Returns:
    - Full deployment details (environment, release, project, created time)
    - taskIdForLogs: the ServerTasks- ID for this deployment
    - taskResourceUri: octopus:// URI for the structured activity tree (resources/read or read_resource)
    - grepTaskLogHint: pre-filled arguments for the grep_task_log tool — call it with a pattern to search the raw log without fetching the whole thing
    - Public URL for web portal access
    
    Recommended workflow for investigating deployment issues:
    1. Call get_deployment_from_url with the deployment URL
    2. Review deployment context (environment, release version, etc.)
    3a. Fetch the taskResourceUri for the structured activity tree (step timings, embedded log entries by category), OR
    3b. Call grep_task_log with the taskId to search the raw log for a specific error / pattern
    
    Handles space ID to space name resolution automatically.`,
          inputSchema: {
            url: z.string()
              .describe("Full Octopus Deploy deployment URL (e.g., https://your-octopus.com/app#/Spaces-1/projects/my-app/deployments/releases/1.0.0/deployments/Deployments-123)")
          },
          annotations: READ_ONLY_TOOL_ANNOTATIONS,
        },
        async (args) => {
          const { url } = args as GetDeploymentFromUrlParams;
    
          if (!url) {
            throw new Error("URL is required");
          }
    
          const configuration = getClientConfigurationFromEnvironment();
          const client = await Client.create(configuration);
    
          const result = await getDeploymentFromUrl(client, { url });
    
          return {
            content: [
              {
                type: "text",
                text: JSON.stringify(result, null, 2),
              },
            ],
          };
        }
      );
    }
    
    registerToolDefinition({
      toolName: "get_deployment_from_url",
      config: { toolset: "deployments", readOnly: true },
      registerFn: registerGetDeploymentFromUrlTool,
    });
  • TypeScript interface 'GetDeploymentFromUrlParams' defining the input parameter: a single 'url' string.
    export interface GetDeploymentFromUrlParams {
      url: string;
    }
Behavior4/5

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

Annotations already indicate readOnlyHint=true and idempotentHint=true. Description adds value by explaining automatic space-to-name resolution and the specific return fields like taskIdForLogs and grepTaskLogHint.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Well-structured with bullet points for returns and workflow. Slightly long but every sentence adds value. Could be slightly more concise, but still efficient.

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

Completeness5/5

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

Given no output schema, description fully covers return values (including grep hint). Also explains handling of space IDs. Excellent for a single-parameter tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Only one parameter (url) with 100% schema coverage. Description adds example URL formats and explains the required structure, going beyond the schema's basic description.

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?

Clear verb ('get') and resource ('deployment details from URL'). Distinguishes from siblings like get_task_from_url and grep_task_log by stating it returns deployment context and a taskId for logs.

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

Usage Guidelines5/5

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

Provides explicit when-to-use (investigating deployment issues) and a recommended multi-step workflow using sibling tools (grep_task_log, read_resource). No when-not-to but alternatives are implied via workflow steps.

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

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/OctopusDeploy/mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server