@moor-sh/mcp 0.27.0 → 0.27.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -75,16 +75,107 @@ Exit 0 with no output means the MCP connected, authenticated, and shut down clea
75
75
 
76
76
  ## Tools
77
77
 
78
- The MCP server exposes:
79
-
80
- - `moor_status` - list all projects with status, source, and domain
81
- - `moor_logs` - get recent container logs for a project (with tail length)
82
- - `moor_rebuild` - rebuild a project from source
83
- - `moor_restart` - stop and start a project's container
84
- - `moor_exec` - run a command inside a project's container
85
- - `moor_env_list` - list environment variables for a project
86
- - `moor_env_set` - set environment variables and restart
87
- - `moor_stats` - host CPU / memory / disk / container counts
78
+ This is the full reference. For the ~10 tools an agent actually needs for the core loop, see the [recommended agent workflow](https://github.com/caiopizzol/moor/blob/main/docs/agent-workflow.md).
79
+
80
+ The table below is generated from the tool registrations. Do not edit it by hand; run `bun run docs` in this package to regenerate.
81
+
82
+ <!-- BEGIN generated-tools (bun run docs) -->
83
+ The server registers 53 tools. Regenerate this section with `bun run docs` after changing any tool.
84
+
85
+ ### Projects
86
+
87
+ | Tool | Title | Description |
88
+ | --- | --- | --- |
89
+ | `moor_status` | List Projects | List all projects managed by Moor. `status` is moor's recorded state (only changes on explicit start/stop/build/cancel). `live_status` is Docker's view at last successful inspect; differences (e.g. recorded='running' live='error') mean moor missed an external change like a host docker stop, crash, or OOM kill. `live_error` non-null means the most recent inspect failed and the live_* values are the last successful snapshot, not necessarily current. |
90
+ | `moor_project_get` | Get Project | Returns the full record for a project (source, branch, dockerfile, domain, status, container id, restart policy). |
91
+ | `moor_project_create` | Create Project | Creates a new project. Provide exactly one of github_url or docker_image. Does not build or start; call moor_rebuild to bring it up, or use moor_deploy to create and start in one step. |
92
+ | `moor_project_update` | Update Project | Updates project metadata. Does NOT rebuild or restart the container. Domain or domain_port changes apply to Caddy immediately. Resource-limit changes (memory_limit_mb, cpus) take effect on the next container recreate (moor_rebuild / moor_restart / moor_deploy / moor_project run) — an already-running container keeps its existing limits. |
93
+ | `moor_project_delete` | Delete Project | Stops and removes the container, then deletes the project record. Requires confirm_name to match the resolved project name exactly. Irreversible. Named Docker volumes are preserved by default (data survives so a recreated project can remount them); pass purge_volumes: true to also delete the underlying Docker volumes — that deletion is also irreversible. |
94
+ | `moor_deploy` | Deploy Project | Create-or-update a project end to end: metadata, env vars (merged into existing), and an optional build/run. Default fails if the project already exists; pass update_existing: true to upsert. When run: true (default), waits for the full Docker build/pull and start, which can take minutes for large images. Errors are tagged by the failing step ([create], [update], [set_env], or [run]) and do not roll back earlier steps. |
95
+
96
+ ### Deployments & runs
97
+
98
+ | Tool | Title | Description |
99
+ | --- | --- | --- |
100
+ | `moor_logs` | Get Container Logs | Get recent logs from a project's container. Annotates output with state: ok (container running), exited (container is stopped but Docker still has logs), no_container (project never started), or missing (container_id is set but Docker doesn't have it). Throws only on docker_error (Docker daemon 5xx / unreachable) so an operator can distinguish infrastructure failure from app silence — pre-#74 the tool returned empty logs for all of these. |
101
+ | `moor_rebuild` | Rebuild Project | Rebuild a project from source (git pull + docker build) and restart the container. Returns the build output when it finishes. While a build is in flight, the most recent moor_runs entry has finished_at=null — call moor_run_get on its id to tail the live output. Use moor_rebuild for code, Dockerfile, or base-image changes. For env vars / resource limits / port / volume / restart-policy changes, or to recover a crashed container from the existing image, use moor_restart — it skips the build and is much faster. |
102
+ | `moor_restart` | Restart Project | Stop and recreate a project's container from its existing image. Does NOT pull from git or rebuild — uses the existing image_tag. Right tool for: applying changed env vars / resource limits / ports / volumes / restart policy, recovering a crashed container, or simply bouncing the process. Wrong tool for: code or Dockerfile changes (use moor_rebuild — those need a new image). |
103
+ | `moor_runs` | List Project Run History | Paginated list of cron runs and build runs for a project. Returns one compact line per run (id, type, status, exit code, duration, output byte counts, timestamps) — stdout/stderr bodies are NOT included to avoid blowing token budgets on large build outputs. Use moor_run_get(run_id) to fetch the stored output for a single run (cron rows store full output; build/manual rows store at most a 64 KiB tail with the original total bytes recorded separately). |
104
+ | `moor_run_get` | Get Run Detail | Fetch one cron or build run with its stdout and stderr. Output is tail-truncated (default 8 KiB per stream; max 65536) to keep responses under typical agent token limits. Use tail_bytes=0 for metadata-only. |
105
+ | `moor_run_stop` | Stop or Cancel a Run | Stops an active cron run or cancels an active build/pull run (from moor_rebuild / moor_deploy). Closing the connection to the Docker build/pull endpoint aborts the daemon-side job. Cancellation is only valid during the build/pull streaming phase — once the build finishes and container start has begun, the call returns not_cancellable. Returns one of: cancelled, cancelled_cron, not_cancellable, already_finished, not_active, not_found. These are all expected outcomes, not errors — the tool throws only on unexpected server failures. |
106
+
107
+ ### Exec & terminal
108
+
109
+ | Tool | Title | Description |
110
+ | --- | --- | --- |
111
+ | `moor_exec` | Execute Command | Run a shell command inside a project's running container. Bounded by a per-call timeout (default 10 min, max 1 h). For jobs that may exceed an hour, use moor_exec_async. |
112
+ | `moor_exec_async` | Start Async Exec | Run a long-lived command inside a project's container, returning immediately with a run_id. Use moor_exec_status to poll for output and exit code; moor_exec_stop to terminate. Bounded by an optional timeout_ms (default 86400000 = 24h; min 60000 = 1 min; max 86400000). The recorded output is tail-truncated to the last 64 KiB per stream; stdout_total_bytes and stderr_total_bytes report the full pre-truncation byte count. |
113
+ | `moor_exec_status` | Get Async Exec Status | Return the current state of an async exec run: state, exit code (when finished), running tail of stdout/stderr (default 8 KiB each inline; the API stores up to 64 KiB), total bytes seen, duration, and any error message. State is one of: running, exited, stopped, timed_out, error. Pass tail_bytes to control how many bytes of each stream are returned inline (0 to 65536; default 8192). The API's 64 KiB-per-stream storage cap is unchanged — tail_bytes only controls what the MCP tool returns to keep responses under typical agent token limits. |
114
+ | `moor_exec_stop` | Stop Async Exec | Terminate a running async exec by run_id. Walks the descendant process tree inside the container and sends SIGTERM then SIGKILL. Always transitions the run to a terminal state: state=stopped on clean termination (all descendants gone), state=error if any descendant survived OR if the kill handle was lost (moor restart, missing pidfile). Stop is NOT retry-safe — the kill script removes the pidfile after every attempt, and reparented survivors are unreachable from the original PID. |
115
+
116
+ ### Environment, cron, volumes & files
117
+
118
+ | Tool | Title | Description |
119
+ | --- | --- | --- |
120
+ | `moor_env_list` | List Environment Variables | List all environment variables set for a project. |
121
+ | `moor_env_set` | Set Environment Variables | Set environment variables for a project. Merges with existing vars. Automatically restarts the container if running. |
122
+ | `moor_cron_create` | Create Cron | Creates a cron schedule on a project. Schedule is a 5-field crontab string with numeric values only (no jan/sun/etc.). Day-of-week uses 0=Sunday through 6=Saturday; 7 is not accepted. |
123
+ | `moor_cron_update` | Update Cron | Updates a cron's fields by id. Schedule is validated if provided. |
124
+ | `moor_cron_delete` | Delete Cron | Deletes a cron by id. |
125
+ | `moor_cron_run` | Run Cron Now | Triggers a cron to run immediately. Requires the project's container to be running. |
126
+ | `moor_env_delete` | Delete Environment Variables | Removes one or more environment variables from a project. Restarts the container only if at least one key was actually deleted AND the project was running. |
127
+ | `moor_volume_list` | List Project Volumes | List the named Docker volumes attached to a project. Each entry includes the logical name (per-project handle), the in-container target path, and the actual Docker volume name (for `docker volume ls` / `docker volume inspect` outside moor). |
128
+ | `moor_volume_add` | Add Project Volume | Attach a named Docker volume to a project. The volume is created lazily by Docker on first container start; moor stores the mount config (logical name, in-container target, and the generated docker_name like moor-<project>-<name>). Takes effect on container recreate (next moor_rebuild / moor_restart / moor_deploy / moor_project run) — already-running containers keep their existing mounts. |
129
+ | `moor_volume_remove` | Remove Project Volume Mount | Detach a named volume from a project's mount config. The underlying Docker volume (and its data) is intentionally preserved — to actually delete the data, use moor_project_delete with purge_volumes:true, or run `docker volume rm <docker_name>` manually. Takes effect on next container recreate. |
130
+ | `moor_file_set` | Set Project File | Declare a file to inject into a project's container. moor writes it via a tar archive PUT right before the container starts, on every recreate, honoring the octal mode (e.g. 0600 for a TLS key). Identified by path — setting the same path again updates its content/mode rather than duplicating. Provide exactly one of content (inline) or env_ref (the name of a project env var to source content from at create time, so a secret stays in the env store instead of plaintext here). Takes effect on next container recreate (moor_rebuild / moor_restart / moor_deploy / moor_project run). |
131
+ | `moor_file_list` | List Project Files | List the declarative files configured for a project. Each entry shows the in-container path, octal mode, and how content is sourced (inline or env). Raw inline content is never returned (it may be large, and env-sourced content lives in the env store). |
132
+ | `moor_file_remove` | Remove Project File | Remove a declared file from a project's injection set. The file stops being written on future container recreates; a copy already present in a running container is not deleted until the next recreate. Takes effect on next container recreate. |
133
+
134
+ ### Credentials & DNS
135
+
136
+ | Tool | Title | Description |
137
+ | --- | --- | --- |
138
+ | `moor_dns_check` | Check Domain DNS | Resolves a domain's A record and reports whether it matches the server's public IP. Useful before pointing a project's domain at the server. |
139
+ | `moor_registry_credentials_list` | List Registry Credentials | List all stored Docker registry credentials. Returns metadata only - the raw secret value is never returned by any read path. Each row carries `secret: { configured: true, kind }` where kind is derived from known token prefixes (github_classic_pat, github_fine_grained_pat) or 'unknown'. |
140
+ | `moor_registry_credential_get` | Get Registry Credential | Get a single stored registry credential by id. Returns metadata only - the raw secret is never returned. Use this before moor_registry_credential_delete to confirm the hostname you intend to delete. |
141
+ | `moor_registry_credential_add` | Add Registry Credential | Store a credential for a Docker registry. The pull path will attach X-Registry-Auth to /images/create whenever an image ref matches this hostname. Hostname must be the bare host as it appears in the image ref (e.g. ghcr.io, docker.io, localhost:5000) - no scheme, no path. Note: the secret value passes through the MCP client and tool-call transport, same security model as moor_env_set; rotate via moor_registry_credential_update if it has been exposed. |
142
+ | `moor_registry_credential_update` | Update Registry Credential | Rotate username and/or secret on an existing credential. Hostname is intentionally not patchable - changing the lookup key on an existing row would silently break the pull path. To change hostnames, delete and re-create. Requires at least one of username or secret. Note: the secret value passes through the MCP client on input - same security model as moor_env_set. |
143
+ | `moor_registry_credential_delete` | Delete Registry Credential | Delete a stored registry credential. Requires confirm_hostname to match the resolved row's hostname exactly - guards against deleting the wrong row from a stale id. After deletion, pulls for that registry fall back to anonymous. Irreversible. |
144
+ | `moor_source_credentials_list` | List Source Credentials | List all stored Git source credentials (HTTPS PATs). Returns metadata only - the raw secret value is never returned by any read path. Multiple credentials can share a hostname (e.g. two github.com rows for different orgs); use label to disambiguate. |
145
+ | `moor_source_credential_get` | Get Source Credential | Get a single source credential by id. Returns metadata only. Use this before moor_source_credential_delete to confirm the label you intend to delete. |
146
+ | `moor_source_credential_add` | Add Source Credential | Store a Git source credential (HTTPS PAT) for a private repo host. v1 supports HTTPS PATs only; SSH deploy keys may be added in a future version. Hostname must be the bare host as parsed from a Git URL (github.com, gitlab.com, etc.) - no scheme, no path. Multiple credentials can share a hostname; the (hostname, label) pair is unique. For GitHub: use a fine-grained PAT with `Contents: read` (username `x-access-token`), or a classic PAT with `repo` scope. Note: the secret value passes through the MCP client and tool-call transport on input, same security model as moor_env_set. |
147
+ | `moor_source_credential_update` | Update Source Credential | Rotate username, secret, label, or expires_at on an existing source credential. Hostname is intentionally not patchable - changing the lookup key on an existing row would silently break in-flight builds. To change hostname, delete and recreate. Requires at least one of username, secret, label, or expires_at. |
148
+ | `moor_source_credential_delete` | Delete Source Credential | Delete a stored source credential. Requires confirm_label to match the resolved row's label exactly - protects against deleting the wrong credential on a host that has several (e.g. two github.com rows). Refused with credential_in_use if any project still references this credential. Irreversible. |
149
+ | `moor_source_credential_check` | Check Source Credential Access | Run a real `git ls-remote` against the repo URL to verify access. Without source_credential_id, probes anonymously first; if private and exactly one credential matches the host, auto-selects it. With source_credential_id, tests that exact credential. With branch, tests the specific branch (branch_not_found is distinct from auth failure). Discovers default_branch via HEAD symref when no branch is provided. Side effect: updates last_checked_at and last_check_status on the credential row; flips state to failed on a credentialed rejection. |
150
+
151
+ ### Server & observability
152
+
153
+ | Tool | Title | Description |
154
+ | --- | --- | --- |
155
+ | `moor_stats` | Server Stats | Get server resource usage: load, memory, per-filesystem disk usage (the filesystems the moor container can see, plus any operator-configured monitored host disks via MOOR_MONITORED_DISKS), Docker disk by category (images/containers/volumes/build cache) with reclaimable bytes, and container counts. Note: cpu.percent is load-derived (load avg ÷ cores), not instantaneous CPU; use the `load` field for the same signal with explicit naming. |
156
+ | `moor_drain_status` | Drain Status | Read-only: current drain state (enabled, reason, expires_at, clear_after_version) plus counts of active work the operator should wait on before an update. active_work uses the same counter as moor_update_status so the two never disagree. |
157
+ | `moor_drain_enable` | Enable Drain Mode | Refuse new builds, deploys, execs, manual cron runs, and terminal upgrades with a 503 carrying { reason, expires_at, hint }. Existing in-flight work runs to completion — drain does NOT kill anything. Scheduled cron ticks during drain write a synthetic 'skipped due to drain' run row instead of executing. Read-only routes (status, logs, runs) keep working. Default TTL is 30 minutes; set ttl_minutes to override. clear_after_version is the updater's hook — when set, the drain auto-clears on boot if the running moor version matches. |
158
+ | `moor_drain_disable` | Disable Drain Mode | Explicit operator action to clear drain immediately. Does not kill or restart anything — just removes the gate so new builds/deploys/execs/cron triggers/terminal upgrades succeed again. |
159
+ | `moor_db_backup` | DB Backup (snapshot) | Take a SQLite snapshot of moor.db via VACUUM INTO. The file lands next to the main DB as moor.db.backup-<epoch-ms>. Retention is enforced after each snapshot (keeps the 7 most recent by default; older ones are pruned). After this returns, moor_update_status' db_backup.age_seconds will read close to 0. Use before a manual `docker compose pull moor && up -d` if you don't have MOOR_DB_BACKUP_INTERVAL_HOURS scheduled. |
160
+ | `moor_project_stats` | Project Container Stats (live) | Live container stats for one project: CPU percent, memory (excluding page cache, same accounting as `docker stats`), network and block I/O totals, PID count. Single Docker stats snapshot — CPU uses the cpu_stats/precpu_stats delta the daemon already includes. Stopped or never-started projects return running=false with zeroed counters (no 404). |
161
+ | `moor_project_history` | Project History (stored) | Stored resource history + lifecycle events for one project over a time window — answers 'what was going on with this project around this case?' (NOT live: use moor_project_stats for a current snapshot). Resource samples are taken ~every minute; CPU is averaged across each interval and network/block reported as rates, both computed from raw counters and reset-aware. Events come from the Docker event stream (start/die/oom/kill/restart) and moor's own state changes. Window defaults to the last `hours` (24); pass from_ms/to_ms (epoch ms) for an exact window. A gap warning means events may be incomplete in that window. |
162
+
163
+ ### Self-update
164
+
165
+ | Tool | Title | Description |
166
+ | --- | --- | --- |
167
+ | `moor_update_status` | Update status / preflight | Report moor's current version + image digest, the latest available digest on GHCR, active in-flight work counts, DB backup recency, and a safe_to_update boolean. update_available is null (not false) when either the local repo_digest or the registry digest is unknown — never lies by comparing across identifier spaces. unsafe_reasons is a human-readable array; render inline rather than re-deriving from booleans. Read-only diagnostic — does NOT perform any update. |
168
+ | `moor_update_apply` | Apply moor update (transient respawner) | Update moor in-place via a transient respawner container. Runs preflight, enables drain, takes a fresh DB backup, then launches a one-shot Compose-aware respawner that pulls + re-creates the moor service. The respawner writes a marker file when done; this tool returns the audit_id immediately so the caller can poll via moor_update_audit. Outcomes: success \| failed (pull failed pre-replacement) \| rolled_back (up/health failed, automatic rollback succeeded) \| rollback_failed (rollback also failed — manual recovery needed) \| crashed (no marker after 30-min grace). Bypass is per-blocker: pass {bypass:['active_work']} to interrupt in-flight builds/execs/crons via the existing shutdown coordinator; {bypass:['unknown_digest']} when the registry comparison was inconclusive. Backup is mandatory and not bypassable. |
169
+ | `moor_update_audit` | Update history (audit log) | Read-only: recent moor_update_apply attempts and their outcomes. Each row shows audit_id, state (success \| failed \| rolled_back \| rollback_failed \| in_progress \| crashed), duration, digest deltas, backup path, and any error logs. error_log preserves the ORIGINAL apply failure (never overwritten by rollback step details); rollback_error is set only on rollback_failed. Default tail is 4 KiB per log field; pass tail_bytes=0 to omit log bodies entirely (keeps the metadata line and replaces the body with a sized marker), or up to 16384 to read more. |
170
+
171
+ ### Cleanup
172
+
173
+ | Tool | Title | Description |
174
+ | --- | --- | --- |
175
+ | `moor_cleanup_plan` | Cleanup Plan (dry-run) | Dry-run: list Docker resources that are safe to delete on this host. v1 covers build cache (host-wide prune) and dangling images (per-ID). Returns candidates with reclaimable bytes. Pass the same candidate list to moor_cleanup_execute to actually delete. No state is kept between plan and execute — execute re-validates eligibility against current Docker state. |
176
+ | `moor_cleanup_execute` | Cleanup Execute | Delete the candidates returned by moor_cleanup_plan. Server uses only the identifying fields (category + id where applicable) and re-validates eligibility against current Docker state immediately before each delete — Docker state can change between plan and execute. Reclaimable byte estimates from plan are ignored; the server reports the actual freed bytes. Every execute writes an audit row. |
177
+
178
+ <!-- END generated-tools -->
88
179
 
89
180
  ## Transport
90
181
 
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env bun
2
+ import "../dist/index.js";