Skip to content

MCP Tool Reference

The full surface exposed by portbay-mcp. Every tool returns structuredContent (typed JSON Schema output) plus a plain-text mirror for clients that don't support structured content. Tools declare behavior annotations: readOnlyHint for read-only tools, destructiveHint for destructive ones, idempotentHint where applicable.

Tools are grouped into toolsets you can enable or disable with --toolsets.

19 tools · 4 static resources · 2 resource templates

Legend: read-only · mutates state · destructive (confirm first)


Projects toolset

portbay_list_projects (read-only)

List every registered project with hostname, URL, and — when the daemon is running — live status, PID, and restart count. daemon_reachable: false means only registry data is shown; status will be unknown. Start here before acting.

No arguments.

Returns: ListProjectsResult

FieldTypeNotes
daemon_reachableboolWhether the Process Compose daemon answered.
projectsProjectSummary[]See ProjectSummary.

portbay_status (read-only)

Live runtime detail for one project or all projects. Returns the same shape as portbay_list_projects but filtered to the requested project(s).

ArgTypeNotes
idstring?Project id (slug). Omit to get all projects.

Returns: ListProjectsResult


portbay_detect_project (read-only)

Inspect a folder and return the detected framework plus suggested registration defaults: id, hostname, port, start command. Nothing is registered — a non-committal preview to confirm with the user before calling portbay_add_project.

ArgTypeNotes
pathstringAbsolute path to the folder to inspect.

Returns: DetectResult

FieldTypeNotes
kindstringDetected framework (next, vite, php, static, node, …).
suggested_idstringSlug derived from the folder name.
suggested_namestringHuman-readable display name.
suggested_hostnamestring<slug>.<domain-suffix>.
suggested_portnumber?Dev server port, when detected.
suggested_start_commandstring?Dev server command, when detected.
suggested_document_rootstring?PHP: relative document root, when detected.
suggested_php_versionstring?PHP: version label, when detected.

portbay_list_recipes (read-only)

List the available stack recipes — named blueprints (laravel, next, vite, …) that compose a project's framework, language version, document root, and HTTPS in one step. Map the user's request to a recipe id, then call portbay_setup_from_recipe. A recipe with composes_fully: false also recommends a database or mail service that isn't auto-provisioned yet (the project still registers, with a warning).

No arguments.

Returns: ListRecipesResult — an object with a recipes array of RecipeSummary:

FieldTypeNotes
idstringStable recipe id to pass to portbay_setup_from_recipe.
titlestringHuman-readable name.
descriptionstringOne-line summary.
project_typestringFramework the recipe registers.
php_versionstring?Default PHP version (PHP recipes only).
document_rootstring?Relative document root (e.g. public).
httpsboolWhether HTTPS is on by default.
databasestring?Recommended database as engine:version (e.g. mysql:8.0).
mailboolWhether the stack recommends a local mail catcher.
composes_fullyboolfalse when a database or mail service is needed but not auto-provisioned.

Current catalog: next, vite, astro, node, static, php, laravel, symfony, statamic.


portbay_add_project (mutates state)

Register an existing local folder as a PortBay project. It gets a local hostname, optional HTTPS via mkcert, and managed start/stop. Omit kind to auto-detect the framework from the folder contents. Does not start the project — call portbay_start after, or use portbay_setup to register and start in one call.

ArgTypeNotes
pathstringRequired. Absolute path to the existing folder.
namestring?Display name. Defaults to the folder name.
hostnamestring?Hostname without scheme. Defaults to <slug>.<domain-suffix>.
kindstring?Framework (next, vite, php, static, node, flutter, xcode, android, custom). Omit to auto-detect.
portnumber?Dev server port. Omit for static / PHP-only projects.
start_commandstring?Shell command to start the dev server. Omit for Caddy-only projects.
httpsbool?Enable local HTTPS via mkcert. Default true.
auto_startbool?Start on daemon boot. Default false.
php_versionstring?PHP version label (e.g. 8.3). PHP projects only.
document_rootstring?Relative document root (e.g. public). PHP projects only.

Returns: OpResult


portbay_update_project (mutates state · idempotent)

Patch fields on an existing project. Only the fields you provide are changed.

ArgTypeNotes
idstringRequired. Project id (slug).
namestring?New display name.
hostnamestring?New hostname. Changing this re-issues the cert on the next reconcile.
portnumber?New dev server port.
start_commandstring?New start command.
httpsbool?Enable or disable HTTPS.
auto_startbool?Enable or disable auto-start on daemon boot.
tagsstring[]?Replace the project's tag list entirely.

Returns: OpResult


portbay_remove_project (mutates state · destructive)

Unregister a project and clean up its cert and /etc/hosts entry. Source files on disk are not touched. Confirm with the user before calling — this is irreversible from PortBay's side.

ArgTypeNotes
idstringRequired. Project id (slug).

Returns: OpResult


portbay_export_config (mutates state · idempotent)

Write a .portbay.json into the project folder so the setup can be committed and reproduced by teammates. Secret values are never written — only their names.

ArgTypeNotes
idstringRequired. Project id (slug).

Returns: ExportResult

FieldTypeNotes
wrotestringAbsolute path of the written .portbay.json.
env_countnumberNumber of env vars written to the template.
secret_namesstring[]Names of secret vars (values not written).

portbay_import_config (mutates state)

Register a project from a committed .portbay.json. Pass the project folder path or the file path directly.

ArgTypeNotes
pathstringRequired. Absolute path to the folder containing .portbay.json, or to the file itself.
secretsobject?Key → value map for declared secret env vars. Omitted secrets are registered as empty placeholders (a warning is returned listing them).

Returns: OpResult


portbay_setup (mutates state)

The one-call "set this up for me" flow: register an existing folder (auto-detecting the framework) and immediately start it, returning the live URL. Set start_now: false to register without starting.

ArgTypeNotes
pathstringRequired. Absolute path to the existing folder.
namestring?Display name.
hostnamestring?Hostname without scheme.
kindstring?Framework. Omit to auto-detect.
portnumber?Dev server port.
start_commandstring?Dev server start command.
httpsbool?Enable HTTPS. Default true.
start_nowbool?Start after registering. Default true.
auto_launchbool?If the daemon is down and start_now is true, open the PortBay app first. Default false.

Returns: OpResult


portbay_setup_from_recipe (mutates state)

Apply a named stack recipe to an existing folder: register it with the recipe's framework, language version, document root, and HTTPS, then start it. The fastest path when the user names a stack. Call portbay_list_recipes first to discover available recipe ids.

For a brand-new project that doesn't exist on disk yet, use portbay_setup_from_template instead.

ArgTypeNotes
recipestringRequired. Recipe id, e.g. laravel, next, vite.
pathstringRequired. Absolute path to the existing project folder.
namestring?Display name.
hostnamestring?Hostname without scheme.
php_versionstring?Override the recipe's default PHP version.
httpsbool?Override the recipe's HTTPS default.
start_nowbool?Start after registering. Default true.
auto_launchbool?If the daemon is down and start_now is true, open the app first. Default false.

Returns: OpResult. If the recipe recommends a database or mail catcher that PortBay can't provision yet, the project is still registered and warnings describes what to add manually.


Lifecycle toolset

Lifecycle tools require the PortBay daemon to be running. Without it, they return SIDECAR_DOWN. Pass auto_launch: true on portbay_start only when the user is at their machine and expects the app to open.

portbay_start (mutates state · idempotent)

Start a registered project.

ArgTypeNotes
idstringRequired. Project id (slug).
auto_launchbool?Open the PortBay app if the daemon is down, wait up to ~15 s, then start. Default false.

Returns: OpResult


portbay_stop (mutates state · idempotent)

Stop a running project.

ArgTypeNotes
idstringRequired. Project id (slug).

Returns: OpResult


portbay_restart (mutates state · idempotent)

Restart a project (stop then start).

ArgTypeNotes
idstringRequired. Project id (slug).

Returns: OpResult


portbay_stop_all (mutates state · idempotent)

Stop every running PortBay process. No arguments.

Returns: OpResult


Diagnostics toolset

portbay_logs (read-only)

Return recent log output for a project. The first thing to read when a project won't start or is crash-looping. Requires the daemon.

ArgTypeNotes
idstringRequired. Project id (slug).
linesnumber?Trailing lines to return. Default 200.
offsetnumber?Offset into the log buffer (0 = newest). Default 0.

Returns: LogsResult

FieldTypeNotes
idstringThe project id.
linesstring[]Log lines, newest last.

portbay_doctor (read-only)

Run an environment health check. Checks: registry readability, daemon reachability on the configured port, mkcert / caddy / process-compose on PATH, current license tier. Use when something is broken and you don't yet know what.

No arguments.

Returns: DoctorResult

FieldTypeNotes
okbooltrue when no check returned fail.
findingsDoctorFinding[]Each finding has check (string), verdict (ok / warn / fail), and detail (string).

portbay_sidecar_status (read-only)

Report the state of PortBay's background services. Process Compose is probed directly over HTTP. Caddy, mkcert, dnsmasq, and Mailpit are managed by the daemon and reported as install-presence only (state unknown from outside the daemon). Use portbay_doctor for a fuller picture.

No arguments.

Returns: SidecarStatusResult

FieldTypeNotes
daemon_reachableboolWhether Process Compose answered.
sidecarsSidecarReport[]Each report has name, state (running / stopped / unknown), and detail.

Scaffold toolset

portbay_setup_from_template (mutates state)

Scaffold a brand-new project from a starter template into parent_path/name, then register it with PortBay. Runs the upstream scaffolder (pnpm create for JS frameworks, composer create-project for Laravel). This takes time and requires network access. open_world_hint is set on this tool because the scaffolder may reach the internet.

For a folder that already exists, use portbay_add_project or portbay_setup_from_recipe instead.

ArgTypeNotes
templatestringRequired. One of: nextjs, vite, astro, laravel, php.
parent_pathstringRequired. Absolute path to the directory the new folder is created inside.
namestringRequired. Name of the new folder to create under parent_path.
start_nowbool?Start after registering. Default false (scaffolding can be slow; the agent usually reports the URL and lets the user start manually).

Returns: OpResult


Common output types

ProjectSummary

Returned by list, status, and most mutation results.

FieldTypeNotes
idstringStable slug. Pass this to all other tools.
namestringHuman-readable display name.
kindstringFramework: next, vite, php, static, node, flutter, xcode, android, custom.
hostnamestringHostname without scheme.
urlstringFull URL (https:// or http:// + hostname).
httpsboolWhether HTTPS is enabled.
portnumber?Dev server port, when set.
statusstringrunning / starting / stopped / crashed / unhealthy / port_conflict / unknown (when daemon is down).
pidnumber?Process id when running.
restartsnumber?Restart count since last start.
readystring?Last readiness-probe result (e.g. Ready), when known.

OpResult

Acknowledgement returned by all mutation and lifecycle tools.

FieldTypeNotes
okbooltrue on success.
projectProjectSummary?The affected project, when applicable.
detailstringHuman-readable summary of what happened.
warningsstring[]Non-fatal issues (e.g. /etc/hosts couldn't be updated without sudo; pending database provisioning). May be non-empty even on success.

Resources

The server exposes read-only MCP resources an agent can read into its context without making tool calls. All resources return application/json.

Static resources

URIContents
portbay://registryThe full PortBay registry as JSON — every project and its config.
portbay://doctorEnvironment health snapshot. Same data as portbay_doctor.
portbay://sidecarsSidecar status snapshot. Same data as portbay_sidecar_status.
portbay://recipesThe stack-recipe catalog. Same data as portbay_list_recipes.

Resource templates

URI templateContents
portbay://projects/{id}Live status + config for a single project, by id.
portbay://projects/{id}/logsRecent log tail for a single project (200 lines).

Error envelope (isError)

When a tool call fails, the result has isError: true and structuredContent carries PortBay's standard error envelope instead of the success type. The agent reads the envelope and can recover or tell the user the next step.

json
{
  "code": "SIDECAR_DOWN",
  "whatHappened": "process-compose is not running",
  "whyItMatters": "Projects can't start until process-compose is running again.",
  "whoCausedIt": "system",
  "actions": [{ "label": "Restart process-compose", "command": "sidecars.restart_pc" }]
}

Resources do not have an isError channel. A failed resource read is reported as a protocol-level error.

Common error codes:

CodeMeaning
PROJECT_NOT_FOUNDNo project with that id in the registry.
SIDECAR_DOWNProcess Compose daemon not reachable — open the PortBay app.
PORT_CONFLICTThe configured port is in use.
PROJECT_CAP_REACHEDProject limit for the current tier reached. Sign in or upgrade to Pro.
BAD_INPUTAn argument was invalid, malformed, or a required path was missing.
REGISTRYThe registry file could not be read or written.
INTERNALUnexpected internal failure.

PortBay is pre-MVP software. Use the docs as an operating guide, not a stability guarantee.