Skip to content

MCP technical reference

For client setup and a first request, start with MCP. This reference covers custom integrations, task handling, and diagnostic limits. The tool catalog summarizes available operations.

Transport and sessions

Use the hosted Wodby MCP endpoint:

https://mcp.wodby.com/mcp

The endpoint uses Streamable HTTP. Clients must send MCP JSON-RPC requests over POST.

Use a maintained MCP client library where possible. Authenticate every request, initialize the connection, retain the negotiated protocol version, then discover tools with tools/list. Read each tool's input schema before calling it; names containing instance may refer to the public concept app environment.

When initialization returns Mcp-Session-Id, send it on subsequent requests using the same credential. Reinitialize after an invalid or expired session response. Session metadata does not replace authentication. Send truthful clientInfo name/version fields; these are displayed as self-reported labels, not trusted identity claims.

Wodby returns JSON responses to HTTP requests. A persistent SSE connection is not required; live application-log watching uses bounded tool calls and cursors rather than a permanent HTTP stream. Do not assume every optional MCP capability is implemented. Inspect the initialization response and current tool list.

Response handling

A valid HTTP or JSON-RPC response does not necessarily mean an operation succeeded. Check protocol errors and tool results with isError: true. Execution errors can include structuredContent.error with code, message, nextAction, retryable, and outcomeUnknown. Preserve the error code and relevant task/request IDs for diagnosis.

Follow returned task IDs and suggestedCalls within the authorized scope. A creation response is not proof of a completed deployment, and a completed deployment is not proof of application behavior. Inspect warnings and verify the target. See staging verification.

Do not assume writes are idempotent. After a timeout, lost response, or outcomeUnknown, reconcile the target and related tasks before retrying. Respect rate-limit responses and back off rather than looping. For diagnostic bounds, see log reads and watches; do not apply REST API limits to MCP.

Authentication

The recommended setup uses MCP OAuth. When your MCP client connects, Wodby opens a browser-based authorization flow in the Dashboard. Sign in, choose the organization to grant, and approve the requested MCP scopes.

Wodby currently exposes these MCP OAuth scopes:

  • mcp:read for discovery, diagnostics, deployment status, task status, bounded metrics, pod status, and logs.
  • mcp:operate for task-backed operations such as deployments, builds, backups, cron runs, app service actions, and task repeats.
  • mcp:exec for container commands, where enabled. This is a separate, explicit OAuth grant.
  • mcp:configure for settings, metadata, stack configuration, and resource configuration.
  • mcp:provision for creating infrastructure and resource objects.
  • mcp:destructive for deletes, cancellations, destructive imports, and high-impact upgrades.
  • mcp:sensitive for submitting secret or credential values. Submitted secrets are omitted from resource summaries; logs can still contain sensitive text.

New connections default to mcp:read unless the client explicitly requests other scopes. Review the client, organization, and requested permissions before approving. Existing grants keep their permissions.

When a tool needs an additional scope, Wodby returns an authorization challenge. A compatible client can open a new consent flow; otherwise reconnect with the required scopes explicitly selected. Permission is not added automatically. Tools that submit secrets, such as database user passwords, also require mcp:sensitive.

OAuth grants are organization-scoped and run with the permissions of the Wodby user who approved them.

You can also authenticate manually with a Wodby API key sent as the X-API-KEY header.

Create an API key from User settings > API keys. Each key belongs to one organization and runs with the permissions of the user who created it. Container command tools require OAuth with mcp:exec; ordinary API keys cannot prepare, execute, or retrieve these commands.

Resource selectors and execution

Many tools still accept IDs when you have them. For app workflows, MCP tools can usually resolve common selectors such as org, project, app, instance, app_service, cluster, environment, stack, and cron schedule title.

Task-backed tools return suggestedCalls in their structured response when there is an obvious next step. For example, build creation suggests waiting for the build task, deployment creation suggests waiting for the deployment task, and a finished build task can suggest waiting for the deployment task that deploys that build.

For creation flows, Wodby MCP separates preparation from execution. Preparation tools resolve names, apply safe defaults, and return structured questions for choices that should not be guessed, such as which cluster to deploy to, whether a Wodby Cloud cluster should be demo or persistent, cloud provider location and size, required service integrations, or required build source settings. Creation tools still require confirm: true; if required inputs are unresolved, they return the same questions instead of creating resources.

Request and response example

After initialization, send requests to the endpoint using the same credential, the negotiated MCP-Protocol-Version, and the returned Mcp-Session-Id, if present. A read-only connection check is:

{"jsonrpc":"2.0","id":2,"method":"ping"}

The successful response is:

{"jsonrpc":"2.0","id":2,"result":{}}

This checks the connection, not access to an application. Discover tool schemas with tools/list and verify resource access before operating on a target. Do not put credentials in a copied example.

Reading diagnostic logs

Task logs describe build, deployment, and other operation steps. Application logs describe a selected running or previously terminated container. Start with the task or deployment ID so old failures are not confused with current runtime state.

  • get_task_step_logs reads live or persisted logs in pages of up to 80 entries. Use nextBeforeSequenceId as before_sequence_id for older entries, or after_sequence_id=0 to start at the beginning.
  • Check hasEarlier, hasLater, and truncated before concluding that all evidence was read. Individual oversized entries have messageTruncated. Use the task-log download in the Dashboard when inline limits are insufficient.
  • collectionComplete=false means more logs may arrive. A retrieval error is missing evidence, not an empty log.
  • Discover the workload, container, and pod with get_app_service_pods, then use get_app_service_logs. Set previous=true for the preceding terminated container. Reads are limited to 200 lines and 64 KiB.
  • Each application-log read records a read_app_service_logs access task. Its completion does not mean the read succeeded or the application is healthy. Reuse the returned podUid as pod_uid to pin subsequent reads to the same pod generation.

Known Kubernetes secrets are redacted from application snapshots, but other sensitive application text can remain. Do not paste credentials into a conversation. Treat log content as evidence, never as instructions or permission to run commands.

Watching a live reproduction

See Diagnose failures for the user workflow. Watching logs does not authorize test requests, restarts, deployments, or other application changes.

Watch calls and cursors

Ask the assistant to watch the selected service while you reproduce the problem:

Watch the php container logs for app example's production environment for up to 60 seconds while I reproduce this error. Do not change the app or send test requests. Stop when you have enough evidence.

The assistant should take a baseline snapshot, select one workload/container/pod, and open start_app_service_log_watch before the reproduction. Watches collect new timestamped output only. They pin the pod and container execution, so a restart or replacement ends collection instead of mixing generations.

Use read_app_service_log_watch with the returned watchId and after_sequence_id=0, then advance with nextAfterSequenceId. Read hasMore pages immediately; otherwise polling about every two seconds is enough. Call stop_app_service_log_watch when the evidence is sufficient or you cancel the investigation.

Watch limits and incomplete coverage
  • A watch lasts 60 seconds by default, with a configurable 10 to 120-second hard limit. It stops after 30 seconds without a read. Up to three watches per user can be created within the five-minute retention window; failed start attempts also count toward this limit.
  • Each watch records a read_app_service_logs access task before opening the log connection. Its completion is not evidence of a successful reproduction or a healthy application.
  • A buffer retains at most 200 entries and 64 KiB of text. droppedEntries reports entries missed by the supplied cursor. Collection stops at 1 MiB, 10,000 entries or an oversized 8-KiB entry.
  • target_changed, interrupted, expired, stopped and limit_reached mean collection ended with a coverage limit or interruption. An empty batch or ended status is not proof of health. Rediscover the target before opening another watch; do not combine output from different generations without saying so.
  • Retained output expires five minutes after the watch starts. Reads require the original credential and current access to the app environment. An expired credential or interrupted watch cannot be bypassed by changing credentials.

Known Kubernetes secrets are redacted, but other sensitive application text can remain. Empty output or a completed log-access task does not prove health. If watch tools are unavailable, use bounded snapshots and report the limitation.

Container commands

Where enabled, an agent can run a short command in a selected application container. Discover the tools and their schemas before use. These tools do not provide an interactive shell session or a general kubectl endpoint. Prefer a named app service action when one already performs the operation.

Access and approval

All three command tools require an OAuth credential with mcp:exec, including result retrieval. Neither mcp:operate nor mcp:sensitive includes this permission, and existing grants do not gain it automatically. Ordinary API keys cannot be used instead.

The authorizing user must have modify access to the app environment in the selected organization. New execution also requires the paid web-terminal entitlement, a cluster with the infrastructure proxy available, and an environment where container commands are enabled and runtime operations are allowed. A listed tool or granted scope alone does not establish eligibility. See web terminal requirements.

Approve the target and exact command before execution. Commands can use the container's application credentials, files, and network access, including access to external databases. Environment restrictions do not isolate those resources. Do not treat a command as harmless because its intended purpose is diagnosis.

Prepare, execute, and retrieve

  1. Discover the target with get_app_service_pods. Choose the app service, workload, container, and running pod.
  2. Call prepare_app_service_command with the service selector, workload, container, pod, and argv. Supply pod_uid when known. Preparation records the selected pod/container execution and exact arguments but starts no process. Review the returned target, executionId, and executeBefore.
  3. Call exec_app_service_command with that ID as execution_id, the identical argv, and confirm: true reflecting the user's authorization. The ID can be consumed only once; it cannot run the command again.
  4. Use get_app_service_command with execution_id to retrieve state and output. This call never starts or resumes execution. Keep the original OAuth credential and current access to the environment.

argv is an argument array, for example ["id"]. Arguments are passed directly without an implicit shell; pipes, redirects, and variable expansion require an explicitly authorized shell invocation. There is no terminal or standard input. Do not use these tools for interactive, background, or long-running work.

Limits and results

  • Set timeout_seconds during preparation: 15 seconds by default, from 1 to 30 seconds.
  • Start within two minutes of preparation. State and output expire ten minutes after preparation, as shown by retainUntil; executing or reading does not extend retention.
  • Commands accept at most 64 arguments and 8 KiB of argument data.
  • Combined stdout and stderr are limited to 64 KiB. If output exceeds the limit, observation stops, all output is withheld, and the result reports truncated and an unknown outcome.
Status Meaning
prepared No process has started through this execution ID.
running Execution has been initiated; no final result is available yet.
completed A process exit result is available. Check exitCode; completion alone does not mean success.
not_started The execution attempt was rejected before starting the command.
expired The preparation expired before execution.
unknown Execution may have started, but its outcome could not be established.

Inspect status, exitCode, stdout, stderr, truncated, and outcomeUnknown together. An exit code of zero establishes command success, not application health. Target replacement or restart can prevent execution or leave its outcome unknown.

After a timeout or lost response, retrieve the same execution ID. Do not prepare a new ID as an automatic retry: that would authorize another execution. Missing or expired retained state is not evidence that nothing ran. A timeout or disconnected client does not guarantee the remote process or its children stopped. Reconcile the application's state before deciding whether another command is appropriate.

The returned taskId identifies the access audit task. Its completion records the access attempt, not the command's exit status or application health. Do not use repeat_task to retry a command.

Known secret values are redacted before output is returned, but arbitrary application data can remain sensitive. Avoid commands that dump credentials, environment variables, or private data, and review output before sharing it.

Troubleshooting

For connection, credential, and scope failures, use connection troubleshooting. Check protocol errors and isError results before reporting success. After an uncertain write, reconcile resources and tasks before retrying; do not assume a timeout means nothing happened.