deployctl
Deploys Composer vendor/ folders (and other large web application assets) to remote hosting, using a differential change-detection engine and a zip + PHP auto-extract bridge to upload them in seconds over FTP/FTPS/SFTP.
Provides an official GitHub Action (donotwaitx/deployctl) that runs differential deployments inside GitHub Actions workflows, along with CLI usage in CI that configures credentials and deployment targets via secrets for automated headless deployments.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@deployctldeploy my-webapp to production"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
deployctl 🚀
Secure, Ultra-Fast Differential Deployment CLI & Model Context Protocol (MCP) Server for AI Agents (Antigravity, Claude Code) and Developers.
Deploy large web applications and Composer vendor/ folders over FTP, FTPS, and SFTP in seconds instead of hours without exposing server credentials to AI agents or CI/CD logs.
⚡ Why deployctl?
⚡ Ultra-Fast Zip & Self-Destructing PHP Auto-Extract Bridge: Compresses differential changes into a temporary zip package, uploads in one stream, and extracts directly on remote hosting in <1 second (turning 45-minute sequential uploads into 30 seconds).
🔍 Fast Remote Manifest Scanner Bridge: Queries remote server state in 0.35 seconds over a single HTTP request using recursive server-side iteration instead of slow sequential FTP roundtrips.
🛡️ Zero-Leak Credential Isolation: Passwords and SSH keys are stored in native macOS Keychain, Linux SecretService, or permission-locked headless vaults (
chmod 0600). Agents and logs never see or expose raw secrets.🤖 Model Context Protocol (MCP) Server: Native stdio JSON-RPC 2.0 tools for Google Antigravity and Claude Code to perform deployments, remote explorations, and dry-run diffs autonomously and safely.
🎯 Change Detection Engine: Computes differential file diffs (Added, Modified, Deleted, Unchanged) locally or against remote state caches in ~0.02s.
📂 Interactive Remote Directory Explorer: Browse and select target deployment directories directly from the terminal or MCP before deploying.
🌐 Headless & CI/CD Ready: Works seamlessly inside GitHub Actions, GitLab CI, and Docker containers with automated confirmations (
--yes) and secret masking.
Related MCP server: ftp-mcp
🏛 Architecture
┌───────────────────────────┐
│ Antigravity / Claude Code │
└─────────────┬─────────────┘
│ (MCP stdio JSON-RPC)
┌─────────────▼─────────────┐
│ deployctl │
└─────────────┬─────────────┘
│
┌────────────────────────┼────────────────────────┐
▼ ▼ ▼
Local State Cache Encrypted Vault Fast Deployment
~/.deployctl/state/ macOS Keychain / Linux Differential Engine
│ │ │
└────────────────────────┴────────┬───────────────┘
│
┌──────────────────┴──────────────────┐
▼ ▼
Direct FTP / SFTP Zip & PHP Bridge
(Sequential sync mode) (High-speed mode <1s)
│ │
└──────────────────┬──────────────────┘
▼
100+ Remote HostingsThe Core Boundary: AI Agent knows the
project. CLI knows theserver. Keychain/Vault holds thesecret.
📦 Installation
Install globally using uv (recommended) or pip:
# Using uv (fastest)
uv tool install --editable . --force
# Or via standard pip
pip install -e .Verify installation:
deployctl --help🚀 Quick Start
1. Initialize Configuration
deployctl initThis generates default configuration files in ~/.deployctl/:
config.yaml: Global preferences and default exclude patterns.projects.yaml: Project deployment targets registry.
2. Add Server Credentials
Securely store your server credentials into the system Keychain/Vault:
deployctl credential add my-webapp-prod \
--host "ftp.example.com" \
--username "deployer" \
--protocol ftp
# (Prompts for password securely without terminal echo)3. Configure a Deployment Target
Link a project environment to the stored credentials:
deployctl project set my-webapp production \
--credential my-webapp-prod \
--remote-path "/public_html" \
--zip \
--app-url "https://example.com"4. Deploy!
# Preview changes with dry-run diff
deployctl deploy my-webapp production --dry-run
# Deploy with automatic confirmation
deployctl deploy my-webapp production --yes5. Target safeguards (optional)
Extra keys on a target in ~/.deployctl/projects.yaml:
projects:
my-webapp:
production:
allowed_branches: [main] # refuse to deploy from any other branch (use --force to override)
require_clean: true # refuse to deploy with uncommitted changes in local_path
post_deploy_delete: # server files removed after a successful deploy (framework caches)
- bootstrap/cache/*.php
insecure_tls: false # true only for self-signed hosts: skips certificate checks
delete_missing: owned # owned (default) | all | none - which server files a deploy may deleteEvery deployment records the git branch, commit and dirty state. Without
allowed_branches, deploying from a branch other thanmain/master/developonly prints a warning, as does deploying from a different branch than the last deployment (files that exist only in the other branch can linger on the server).Files whose deletion fails are reported, kept in the state cache and retried by the next deployment; deletions never run when an upload failed.
The state cache is ignored once it is older than
state_max_age_days(default 7, inconfig.yaml) and the server is scanned again.Server files take priority. By default (
delete_missing: owned) a deploy only deletes files deployctl itself deployed earlier and that are now gone locally. Files that exist only on the server (admin uploads, generated thumbnails) are never removed; they are listed asskipped_deletes.allrestores the old "mirror the local tree" behaviour,nonenever deletes. Change it withdeployctl project set <project> <env> --delete-missing owned|all|noneor the MCP toolset_target_option.Deleting server files always needs an explicit yes (
--yes, oryes=trueover MCP); until then the run stops withDELETIONS_NEED_CONFIRMATIONand the list of files.Only one deployment per
project:environmentruns at a time.post_deploy_deletepatterns are relative toremote_path; only the file-name part may contain wildcards.
📖 CLI Reference
🚀 Deployments
Command | Description |
| Deploy changes to target server |
| Inspect differential changes without uploading |
| Force direct live remote scan via PHP bridge |
| Bypass production confirmation prompt |
🔑 Credentials Management
Command | Description |
| Save server credentials securely |
| List stored credential identifiers |
| Test connectivity with stored credentials |
| Delete credentials from Keychain/Vault |
📂 Remote Exploration
Command | Description |
| List files and directories on remote hosting |
| Interactively browse remote folders and save |
| Create remote directory on hosting server |
| Fast-sync remote manifest into local state cache |
📋 Audit & Configuration
Command | Description |
| View all configured projects, targets, and status |
| Display sanitized target configuration |
| Show past deployment audit logs |
| Test target connectivity |
| Launch MCP server on stdio |
🤖 Model Context Protocol (MCP) Integration
deployctl comes with a built-in MCP server for AI Coding Agents.
Antigravity Configuration
Add to ~/.gemini/antigravity/mcp_config.json or ~/.gemini/config/mcp_config.json:
{
"mcpServers": {
"deployctl": {
"command": "deployctl",
"args": ["mcp"]
}
}
}Claude Code Configuration
Add to ~/.claude.json or project settings:
{
"mcpServers": {
"deployctl": {
"command": "deployctl",
"args": ["mcp"]
}
}
}Available MCP Tools:
deploy_project: Deploy projects with differential diffs and zip strategy. Never prompts: a production deploy first returnsCONFIRMATION_REQUIREDwith the diff, and runs when repeated withyes=true. Returns a JSON report (status, git branch/commit, warnings, file lists, failed uploads/deletes).list_projects: Inspect configured projects and targets.test_connection: Test server connectivity.show_project: View sanitized target settings.browse_remote_directories: Browse remote server folder hierarchy.download_remote_file: Download one remote file (e.g. a log) to~/.deployctl/downloads/<project>/<env>/and return its redacted tail.set_target_option: Change a validated target option (delete_missing,allowed_branches,require_clean,insecure_tls,post_deploy_delete,app_url,zip_deploy).set_remote_path: Configure remote destination folder.
🧠 Official AI Agent Skill
deployctl provides an official Agent Skill (SKILL.md) that teaches AI coding assistants (Claude Code, Cursor, GitHub Copilot, Google Antigravity, OpenHands) how to safely inspect, preview diffs, and execute deployments without leaking credentials.
Option 1: Using deployctl CLI (Fastest)
# Install globally for all detected agents (Claude Code, Cursor, Antigravity)
deployctl skill install
# Or target a specific agent
deployctl skill install --agent claude
deployctl skill install --agent cursorOption 2: Using NPX (Zero Install)
npx deployctl-skill
# or target a specific agent
npx deployctl-skill --agent claudeOption 3: Package for Marketplaces (Agensi / Glama)
deployctl skill package
# -> Generates dist/deployctl-skill.zip ready for one-click marketplace uploadsSee skills/deployctl/README.md for detailed configuration options.
🔄 GitHub Actions CI/CD Integration
Option A: Using the Official GitHub Action (Recommended)
Simply use donotwaitx/deployctl@main in your workflow:
name: Deploy to Hosting
on:
push:
branches: [ main ]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: 📥 Checkout Code
uses: actions/checkout@v4
- name: 🚀 Ultra-Fast Deploy
uses: donotwaitx/deployctl@main
with:
host: ${{ secrets.FTP_HOST }}
username: ${{ secrets.FTP_USERNAME }}
password: ${{ secrets.FTP_PASSWORD }}
protocol: ftp
remote_path: "/public_html"
app_url: "https://example.com"
zip_deploy: "true"
remote_scan: "true"Option B: Using CLI directly via uv
- name: 🐍 Set up uv
uses: astral-sh/setup-uv@v3
- name: 🚀 Deploy via deployctl CLI
env:
FTP_HOST: ${{ secrets.FTP_HOST }}
FTP_USER: ${{ secrets.FTP_USER }}
FTP_PASS: ${{ secrets.FTP_PASSWORD }}
run: |
uv tool install deployctl
deployctl credential add prod-cred --host "$FTP_HOST" --username "$FTP_USER" --password "$FTP_PASS"
deployctl project set my-app production --credential prod-cred --remote-path "/public_html" --zip --app-url "https://example.com"
deployctl deploy my-app production --yes --remote-scan🛡️ Security & Privacy Guarantees
Passwords Never Logged: Passwords, API tokens, and SSH keys are automatically masked (
[REDACTED]) in all logs, error traces, and MCP responses.Self-Destructing PHP Bridges: Temporary PHP worker scripts execute in memory, enforce 32-hex random authentication tokens, and self-delete immediately upon execution (
register_shutdown_function+@unlink).Project Isolation Safeguards: Prevents accidental cross-deployments when working in different repository working trees.
TLS Verified by Default: Requests to the PHP bridges verify the server certificate. Set
insecure_tls: trueon a target to skip verification; only then is the server-IP fallback (virtual hostHostheader) tried, since a certificate is never valid for a bare IP.Constant-time Token Check: The PHP bridges compare tokens with
hash_equals.
☕ Support
If deployctl saves you time, you can support its development:
MoMo: 0336679423
MB Bank:
910191005
📄 License
MIT License © 2026 deployctl Contributors. See LICENSE for details.
Available Tools
8 toolsbrowse_remote_directoriesARead-onlyIdempotent
Inspect and browse actual remote directories and files on the hosting server. Use this to explore what folders exist on the server before picking a remote deployment destination.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | Remote path to browse (default: /) | / |
| project | Yes | Project name (e.g. my-webapp) | |
| environment | No | Environment name (default: production) | production |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false and openWorldHint=true, so the safety profile is fully covered. The description usefully reinforces that this reads live server state ('actual remote directories'), but adds nothing about return shape, whether hidden files or symlinks appear, or any permission/size limits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, each earning its place: the first defines the action and scope, the second the workflow trigger. The purpose is front-loaded with zero filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only, fully-annotated, fully-documented exploration tool this is close to complete; the workflow cue is genuinely helpful. The only notable gap is that with no output schema, the description never states what is returned (a listing? entries with types?), forcing the agent to infer.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% — path, project and environment are all documented in the schema with defaults. The description adds no extra semantics such as path syntax, relative vs. absolute handling, or what 'environment' means for browsing. Baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb pair (Inspect/browse) and resource (remote directories and files on the hosting server), which is more concrete than a bare name restatement. It doesn't explicitly name the sibling it contrasts with (set_remote_path / download_remote_file), but the 'explore before picking a destination' framing makes the distinction inferable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Use this to explore what folders exist on the server before picking a remote deployment destination' gives a clear trigger condition tied to the deployment workflow. No explicit when-not or named alternatives (e.g., vs. set_remote_path) are provided, so it falls short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
deploy_projectADestructiveIdempotent
Deploy project files to a remote server using credentials securely loaded from macOS Keychain / Linux SecretService / Vault. Never requires or exposes passwords. Returns a JSON report: status, git branch/commit, warnings, added/modified/deleted files and any failed uploads or deletes.
| Name | Required | Description | Default |
|---|---|---|---|
| yes | No | Confirm a production deployment. Leave false first: the call then stops with CONFIRMATION_REQUIRED (production) or DELETIONS_NEED_CONFIRMATION (server-only files would be deleted) and returns the diff; repeat it with yes=true once the diff has been reviewed. | |
| app_url | No | Public web URL of the target app for triggering remote PHP extraction bridge | |
| dry_run | No | Simulate deployment and calculate diff without uploading any files | |
| project | Yes | The name of the project to deploy (e.g. my-webapp) | |
| zip_deploy | No | Use fast Zip packaging and remote PHP auto-extraction bridge (ideal for large codebases and vendor folders) | |
| environment | No | Target environment (e.g. production, staging) | production |
| remote_scan | No | Compare against a fresh scan of the server instead of the local state cache | |
| force_branch | No | Deploy even when the target's allowed_branches / require_clean policy blocks it |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, openWorldHint=true, and idempotentHint=true; the description adds genuinely non-redundant context about how credentials are obtained (Keychain/SecretService/Vault) and that passwords are never exposed. It also partially names destructive consequences ('deleted files', 'failed ... deletes'), but does not warn about server-only file deletion or the confirmation gate, which is the riskiest behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tightly packed sentences: action and scope first, security guarantee second, return payload third. No filler and no repetition of schema details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description usefully enumerates the JSON report fields, and credentials handling is covered. The main missing element is the two-step confirmation flow and dry-run-first workflow, which are behavioral essentials for a destructive deployment tool, even though the schema hints at them.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so every parameter is already well documented in the schema (including the important 'yes' confirmation semantics). The description adds no parameter-level meaning beyond the schema, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Deploy project files to a remote server') plus the credential source and return shape, so an agent immediately knows this is the mutation/deploy operation. It is clearly distinct from the list/show/test siblings, though it never explicitly contrasts with any of them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no when-to-use/when-not-to-use guidance: it does not mention that a first call with yes=false returns CONFIRMATION_REQUIRED, nor when to prefer dry_run, remote_scan, or zip_deploy. That confirmation workflow exists only in the schema's 'yes' parameter text, not in the description, and force_branch's policy-override risk is unaddressed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
download_remote_fileAIdempotent
Download one file (e.g. storage/logs/laravel.log) from the remote server using Keychain credentials. The file is saved under ~/.deployctl/downloads/// (the response gives local_path, readable with a file tool) and the last lines are returned inline with secrets redacted. Refuses directories and files over max_bytes.
| Name | Required | Description | Default |
|---|---|---|---|
| project | Yes | Project name (e.g. my-webapp) | |
| max_bytes | No | Refuse files larger than this many bytes (default 52428800 = 50 MB) | |
| tail_lines | No | Return this many trailing lines inline (0 = save only, no preview) | |
| environment | No | Environment name (default: production) | production |
| remote_path | Yes | Absolute remote file path, as shown by browse_remote_directories |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations are sparse in substance (readOnlyHint=false, idempotentHint=true) and the description carries the real weight: it discloses the auth mechanism (Keychain credentials), the exact local destination pattern (~/.deployctl/downloads/<project>/<environment>/), that the response exposes local_path, that trailing lines are returned inline with secrets redacted, and the two refusal conditions. None of that is recoverable from the annotations and it is consistent with readOnlyHint=false (a local write occurs).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, front-loaded with the action and path example, then destination/return behavior, then the refusal guardrails. No sentence restates the name or the schema, and each clause adds new information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the description must explain the return — and it does: local_path plus inline tail lines with redaction. Combined with the destination path, credential source, and refusal rules, an agent has everything needed to call it once and interpret the result without a follow-up.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3, but the description earns an increment by tying tail_lines to observable behavior ("the last lines are returned inline") and by surfacing the max_bytes refusal as a semantic consequence rather than just a field. It does not add format or syntax detail for remote_path or environment beyond what the schema already states.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource ("Download one file ... from the remote server") and immediately scopes it with an example path plus the constraint that directories are refused. The combination of "one file" and the path example makes it unambiguous versus a bulk or directory-listing operation like browse_remote_directories.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states the context of use (retrieving a single remote file with Keychain credentials) and gives exclusions in the form of refusals: directories and files over max_bytes. It also names the downstream step (local_path readable with a file tool). What it never states explicitly is how to obtain a valid remote_path — that routing to browse_remote_directories appears only in the parameter schema, not the description.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_projectsARead-onlyIdempotent
List all configured projects, target environments, protocols, and credential status.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive, and closed-world, so the safety profile is covered. The description adds real value by disclosing what the response contains (environments, protocols, credential status) — notably that credential status is exposed, which matters for an agent reasoning about auth readiness.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no filler; every element (projects, environments, protocols, credential status) carries information about the return payload.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description appropriately compensates by listing the fields returned. Minor gaps remain — no mention of ordering, whether credentials are masked, or how an empty configuration is represented — but for a zero-param read tool this is largely complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so there is nothing for the description to disambiguate; baseline 4 applies. No parameter discussion is needed or present.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb ('List') plus resource ('projects') and it enumerates the content returned: target environments, protocols, and credential status. The word 'all' implicitly contrasts with the singular show_project sibling, but no sibling is named explicitly, so it falls short of full differentiation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied — an agent can infer this is the entry point for discovering configured projects before calling show_project or deploy_project, but the description never states when to use it versus those alternatives or any prerequisites.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_remote_pathAIdempotent
Configure the remote deployment destination directory (remote_path) for a project and environment in projects.yaml.
| Name | Required | Description | Default |
|---|---|---|---|
| project | Yes | Project name (e.g. my-webapp) | |
| environment | No | Environment name (default: production) | production |
| remote_path | Yes | Remote directory path on hosting (e.g. /public_html or /public_html/demo) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare this is a non-destructive, idempotent, closed-world write. The description adds the non-obvious fact that the write lands in projects.yaml rather than creating a directory on the remote host — a real clarification for an agent that might otherwise assume remote filesystem effect. It stops short of noting overwrite behavior on an already-set path.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One sentence, front-loaded with the action and the field being set, with the persistence target tacked on where it costs nothing. No filler to cut.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Enough to call it correctly, but silent on the behavior an agent would want before mutating shared config: whether an existing value is overwritten, whether the remote path must already exist, and what the tool returns (no output schema). Reasonable but with clear gaps for a config-mutation tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and every parameter carries its own example-laden description, so the schema does the heavy lifting. The description only restates that project + environment identify the target and remote_path is the value, adding no format or validation detail beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb plus resource: "Configure the remote deployment destination directory (remote_path)" scoped to a project and environment, and it even names the persistence target (projects.yaml). That distinguishes it from browse_remote_directories and download_remote_file, though it never explicitly separates itself from the similarly named set_target_option.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: an agent can infer this is a setup step before deploy_project, but the description never says when to call it, whether a prior listing via browse_remote_directories is expected, or what happens if the project/environment doesn't already exist.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_target_optionAIdempotent
Change one safety/behaviour option of an existing deployment target in projects.yaml. Options: delete_missing (owned = default, only delete files deployctl itself deployed; all; none), allowed_branches (list of branch names), require_clean (bool), insecure_tls (bool), post_deploy_delete (list of file patterns), app_url (string), zip_deploy (bool).
| Name | Required | Description | Default |
|---|---|---|---|
| value | No | New value; null removes the option so the default applies | |
| option | Yes | Option to change | |
| project | Yes | Project name | |
| environment | No | Environment name (default: production) | production |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare idempotentHint=true, destructiveHint=false and openWorldHint=false, and the description goes beyond them by explaining what each option value means, including that delete_missing=owned is the default and only removes files deployctl itself deployed. It stops short of saying when the setting takes effect (next deploy vs. immediately) or whether values are validated, which is the one behavioral gap left for a config mutation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences: the action and scope first, then a compact option-to-type mapping. No filler, and the densest information (the option list) is placed after the statement of purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema the description must carry the load, and it does for purpose, target, storage location and value semantics. The remaining omission is what happens after the write (does the change require a subsequent deploy_project to take effect, what does the call return), which is a meaningful but modest gap for a simple config setter.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, and the description earns above that by adding semantics the enum alone lacks: delete_missing's three levels with their default, allowed_branches as branch names, post_deploy_delete as file patterns, and the type of each other option. It adds nothing for project, environment or value, but the schema already covers those.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Names a specific verb and resource ("Change one safety/behaviour option of an existing deployment target") and pins the storage location (projects.yaml), which no sibling touches. It is clearly distinguishable from list_projects, deploy_project, show_project and set_remote_path.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase "an existing deployment target" implies the project must already exist, and "Change one ... option" implies one option per call. But there is no explicit when-to-use/when-not, no mention that this does not deploy, and no pointer to deploy_project to apply the change. Usage is inferred rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
show_projectARead-onlyIdempotent
Inspect project deployment configuration. All passwords remain strictly protected.
| Name | Required | Description | Default |
|---|---|---|---|
| project | Yes | Project name | |
| environment | No | Environment name (default: production) | production |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnlyHint=true, idempotentHint=true and destructiveHint=false, so the safety profile is covered. The description adds one genuine behavioral fact: passwords in the returned configuration are protected/redacted, which warns the agent not to expect secrets. It doesn't say whether they are omitted, masked, or otherwise altered, and says nothing about the shape or size of the returned config.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, front-loaded with the action and resource, and the redaction warning in the second sentence is directly relevant. Nothing is padded or repeated from the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only tool with full schema coverage and complete annotations, the basics are covered. However, there is no output schema, and the description doesn't indicate what 'deployment configuration' actually contains or how it varies by environment, leaving the agent guessing at the response.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with both 'project' and 'environment' (including its production default) documented in the schema. The description adds no meaning beyond that, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
It states a specific verb and resource ('Inspect project deployment configuration'), which clearly separates it from siblings like list_projects and deploy_project. It never names a sibling explicitly, so the differentiation is inferred from wording rather than stated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The use case is implied: fetch the deployment configuration of one project rather than listing projects or deploying. There is no explicit when-to-use/when-not guidance, no mention of the environment parameter, and no routing to an alternative tool for adjacent needs such as test_connection or set_target_option.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
test_connectionARead-onlyIdempotent
Test connectivity to a remote server target using stored credentials without deploying.
| Name | Required | Description | Default |
|---|---|---|---|
| project | Yes | The name of the project to test | |
| environment | No | Target environment (default: production) | production |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive, open-world behavior, so the safety profile is covered. The description adds two genuinely new facts: connections use stored credentials (no auth flow needed) and no deployment is performed, which is exactly the context an agent needs to trust it as a dry-run check.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no filler; the non-deploying, credential-using nature is stated immediately.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple two-parameter read-only probe with rich annotations, most of what's needed is present. However, there is no output schema and the description never says what a test returns (pass/fail, error detail, latency), which is the key cognitive gap for a connectivity test tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so both `project` and `environment` are already documented with defaults. The description adds no syntax, format, or environment-name conventions beyond the schema, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Names a specific verb (test connectivity) and resource (remote server target), and the phrase 'without deploying' implicitly separates it from the sibling deploy_project. It stops short of naming any sibling tool explicitly, so differentiation is somewhat inferential.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Without deploying' hints at when to prefer this over deploy_project, but there is no explicit guidance on prerequisites, when to run it (pre-deploy validation?), or what to do with the result. Usage is implied rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
8 tool updates
v0.2.0- First observed
browse_remote_directories - First observed
deploy_project - First observed
download_remote_file - First observed
list_projects - First observed
set_remote_path - First observed
set_target_option - First observed
show_project - First observed
test_connection
TDQS
Scored across 8 tools
Most tools have clearly distinct actions: list/show projects, deploy, test connectivity, browse remote directories, download a remote file, and modify target configuration. There is mild overlap between list_projects and show_project, and between browse_remote_directories and download_remote_file when inspecting remote files, but descriptions largely clarify the boundaries.
All tool names use a consistent snake_case verb_noun pattern: list_projects, deploy_project, test_connection, show_project, browse_remote_directories, download_remote_file, set_target_option, set_remote_path. The convention is predictable throughout.
Eight tools is well within the appropriate range for a deployment management server. Each tool covers a distinct operational need such as listing, inspecting, testing, deploying, remote browsing, downloading, and target configuration.
The core deployment workflow is covered: inspect projects, test connectivity, browse remote paths, deploy, download remote files, and update target options/paths. However, notable lifecycle operations are missing, such as creating/removing projects or targets, listing deployment history, and rollback, which may force agents to work around the tool surface or fail on onboarding/recovery tasks.
Maintenance
Related MCP Connectors
Deploy sites and apps from your AI coding agent: domains, DNS, logs, env, versions and rollback.
Remote Desktop Commander: use files, terminal and processes on your own computers from any AI app.
Deploy and manage your apps, databases, storage, and scheduled jobs from your AI agent
Deploy local apps, add managed Postgres, and inspect logs from your AI coding agent.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceBridges AI coding assistants with website codebases, local git repositories, and shared hosting via FTP/SFTP, enabling code discovery, file management, git operations, smart deployments, backups, and rollbacks.9 npmMIT
- AlicenseBqualityDmaintenanceEnables AI agents to perform FTP/FTPS/SFTP file operations including upload, download, sync, and directory management with multi-server support.3635 npm7MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI apps to connect to remote servers via SSH, SFTP, and tunnels.8,785 npmMIT
- AlicenseNot gradedqualityCmaintenanceEnables AI agents to manage remote servers via SSH, including command execution, multi-host batch operations, SFTP file transfer, background job handling, DevOps diagnostics, port tunneling, and safety guardrails like high-risk command blocking and read-only mode.MIT