Gimme MCP
Official# Gimme MCP
Gimme is an alpha MCP deployment control plane for Ubuntu targets. It keeps desired
state locally, provisions a target through a narrowly scoped privileged helper, and
deploys PHP/Laravel or static applications through Deployer.
Version 0.6 has four explicit resources:
- a **target** is an independently provisioned Ubuntu machine;
- an **application** is reusable source/build metadata;
- a **resource** is a named, version-pinned PostgreSQL or Valkey service;
- a **deployment** places one application revision on one target at one stage.
This is alpha software and 0.6 is a hard state/API break. There are no compatibility
tools. The migration preserves existing remote paths, database identities, cache
prefixes, and URLs while recording observed runtime and service versions explicitly.
## Safety model
Gimme deliberately exposes no arbitrary shell, SQL, hostname, package, service, or
filesystem-path parameters. Remote mutations use reviewable, content-addressed plans.
Applying a stale plan fails closed. Deployment placement is allocated once and cannot
be changed through the update API.
Repository URLs must be credential-free. Authentication belongs in SSH agents,
repository-scoped deploy keys, or credential helpers. The Deployer child receives an
explicit environment allowlist, so unrelated shell credentials are not inherited.
Secrets are references such as `my-deployment/STRIPE_KEY`, never MCP arguments or
tool output. They are resolved from `secrets.enc.json` with SOPS, placed in an
owner-only temporary file, transferred to an owner-only remote temporary file, and
removed after environment reconciliation.
Create or edit the encrypted document with `sops config/secrets.enc.json`; its nested
JSON keys must match the references declared by deployments. Configure age through
`SOPS_AGE_KEY_FILE` or `SOPS_AGE_KEY` in the MCP server's environment.
Production is policy, not a branch convention. A production deployment requires:
- a `public_dns` target and explicit domain;
- an exact commit source;
- `APP_ENV=production` and `APP_DEBUG=false`;
- a health gate before and after the current-symlink switch.
Staging also requires debug off and a health gate. Local and preview deployments are
less restrictive. Caddy uses its internal CA for local mDNS and automatic ACME HTTPS
for public DNS.
## Install
```bash
# From the repository root:
uv sync
composer install
```
State defaults to `config/state.json`. Set `GIMME_STATE_DIR` to keep operational state
elsewhere; the directory contains:
```text
state.json # schema-v3 targets, applications, resources, deployments, pins
secrets.enc.json # SOPS-encrypted secret values
.gimme.lock # local atomic-write lock
```
Operational state and encrypted secrets are ignored in this public source repository
because even encrypted documents, hostnames, repository URLs, and secret key names can
reveal private inventory. To make state Git-backed, point `GIMME_STATE_DIR` at a
separate private repository. Legacy 0.4 manifests remain ignored for the same reason.
Copy the example for a new installation, or use the migration tools for an older installation:
1. call `plan_state_migration`;
2. review its preserved placements and effects;
3. pass its exact `plan_id` to `apply_state_migration`;
4. commit the resulting desired state only if that repository is intended to hold
your operational inventory.
See [`config/state.example.json`](config/state.example.json) for the complete shape.
For a public target, use `network.mode: "public_dns"`, omit `mdns_name`, declare one
or more literal `expected_addresses`, and give every deployment an explicit `domain`.
Planning verifies that DNS resolves to a declared address before Caddy is allowed to
request an ACME certificate.
For guided workflows, see:
- [`docs/tutorials/first-local-deployment.md`](docs/tutorials/first-local-deployment.md)
- [`docs/how-to/migrate-a-runtime-to-mise.md`](docs/how-to/migrate-a-runtime-to-mise.md)
- [`docs/explanation/control-plane.md`](docs/explanation/control-plane.md)
## Target bootstrap
SSH must work against `bootstrap_hostname`. For local targets, normal operations use
the advertised `hostname`, which lets host-specific SSH settings such as agent
forwarding apply consistently.
The MCP server never handles a sudo password. Perform the initial helper installation
from a terminal:
```bash
uv run gimme-bootstrap-target devbox
uv run gimme-bootstrap-database devbox
```
This keeps one interactive terminal open for sudo and installs root-owned,
policy-bound helpers. Later MCP reconciliations use only those exact sudo rules. Run
the bootstrap command again after changing the target's stack policy or upgrading
Gimme's helper implementation.
The second command grants the deployment user PostgreSQL `CREATEDB` and `CREATEROLE`;
they allow database lifecycle management but do not grant operating-system root.
For a local mDNS target, import the exported Caddy public root once on each development
workstation. The CA private key never leaves the target:
```bash
scp devbox.local:/srv/gimme/apps/.caddy-local-root.crt /tmp/gimme-caddy-root.crt
```
Trust only a CA retrieved from a target you control.
## Runtime versions
Every deployment declares exact runtime versions. A pin has a `provider` and a
`version`; Gimme never resolves ranges such as `latest`, `^22`, or `8.4.*`.
- `system` selects an exact host binary and verifies its full version.
- `mise` installs and executes that exact user-space runtime from
`<apps_root>/.gimme/mise` without shell activation.
- `bundled` is valid only for npm, whose version is supplied by the selected Node.js.
Set `target.runtimes.mise_version` whenever any deployment uses mise and include
`mise` plus `software-properties-common` in the target stack. On Ubuntu 26.04 Gimme's
privileged helper enables only the fixed official `ppa:jdxcode/mise` source; it never
pipes a remote installer into a privileged shell. Use
`plan_deployment_runtimes` and `apply_deployment_runtimes` to review and install the
declared mise pins. Multiple Node.js, Bun, pnpm, Yarn, Python, Ruby, Go, and Java
versions can coexist because each deployment command runs through
`mise exec tool@version`.
PHP web deployments deliberately use the `system` provider: the exact PHP patch is
verified, Deployer uses `/usr/bin/phpX.Y`, Caddy uses
`/run/php/phpX.Y-fpm.sock`, and queue/Horizon/scheduler units use that same CLI.
Composer is also system-pinned so it cannot silently execute under another PHP.
Application `php_extensions` are exact required capabilities checked before deploy;
their packages remain part of the target's reviewed APT stack.
PostgreSQL and Valkey are named resources with explicit versions and deployment
bindings. The current `target_local` provider permits one version of each service per
target; the model leaves room for external or isolated providers later without
changing deployment identity.
## Frontend builds
Applications may select `npm`, `pnpm`, `yarn`, or `bun`. The deployment declares exact
runtime versions and verifies them before running a build. Gimme accepts
only a validated script name, never a free-form command, and requires exactly one
matching lockfile with no conflicting package-manager lockfiles.
| Manager | Frozen install |
| --- | --- |
| npm | `npm ci --no-audit --no-fund` |
| pnpm | `pnpm install --frozen-lockfile` |
| Yarn 1 | `yarn install --frozen-lockfile --non-interactive` |
| Yarn 2+ | `yarn install --immutable` |
| Bun | `bun install --frozen-lockfile` |
Gimme will not silently substitute a package manager or update a lockfile.
## Run
```bash
uv run gimme-mcp
```
Example stdio client configuration:
```json
{
"mcpServers": {
"gimme": {
"command": "uv",
"args": ["--directory", "/path/to/gimme", "run", "gimme-mcp"]
}
}
}
```
## Workflow
1. Register or migrate targets, applications, resources, and deployments.
2. `inspect_target`, then `plan_target_stack` / `apply_target_stack`.
3. `plan_deployment_runtimes` / `apply_deployment_runtimes` to install and verify pins.
4. `plan_deployment_resources` / `apply_deployment_resources` to reconcile routing,
PostgreSQL, Valkey, runtime values, workers, Horizon, and the scheduler.
5. `plan_deployment` to review the resolved commit and Deployer task graph, then
`apply_deployment` with the exact plan.
6. Use `list_releases`, `rollback_deployment`, deployment-scoped Artisan tools, and
`deployment_process_status` for operations.
7. Use `plan_promotion` / `promote_deployment` to deploy the exact current commit from
one deployment to another. The destination source is pinned only after success.
8. Use `plan_remove_deployment` / `remove_deployment` for explicit cleanup.
Laravel candidate health runs inside the release before activation. The live HTTPS
health gate runs after activation and automatically restores the prior release on
failure. Queue workers use `queue:restart`; Horizon uses `horizon:terminate`, matching
Laravel's graceful restart model and avoiding a PHP-FPM reload.
## MCP surface
Read-only resources:
- `gimme://state`
- `gimme://targets/{name}`
- `gimme://applications/{name}`
- `gimme://resources/{name}`
- `gimme://deployments/{name}`
See [`docs/reference/mcp.md`](docs/reference/mcp.md) for the complete tool and resource
catalog. Runtime schemas returned by `tools/list`, `resources/list`, and
`resources/templates/list` remain authoritative.
## Current scope
Gimme 0.6 provides the multi-target foundation and strong production invariants. It
still provisions target-local PostgreSQL and Valkey. Managed cloud databases, backups,
HA, external secret stores, immutable build artifacts, traffic splitting, and fleet
scheduling are intentionally future work rather than implied production guarantees.
## Development
```bash
# From the repository root:
bash scripts/gimme-verify
```
The project is licensed under the MIT License.
TDQS
Scored across 12 tools
Each tool targets a distinct resource and action: host inspection, stack planning/provisioning, app registration, app resource planning/provisioning, deployment, releases, rollback, and service status. The plan/provision pairs are clearly separated by their plan/resource names and descriptions, so an agent should not confuse them.
Tool names follow a mostly consistent verb_noun snake_case pattern such as plan_stack, provision_stack, list_apps, deploy_app, and rollback_app. The only outlier is service_status, which uses a noun_noun form instead of a verb-first convention, but it is still readable and not confusing.
Twelve tools is well-scoped for a provisioning and deployment server. Each tool covers a meaningful step in the workflow, and none feel redundant or unnecessary.
The tool set covers the main lifecycle well: inspect, plan, provision, register, deploy, list releases, rollback, and check service status. The main gap is the lack of teardown or removal operations, such as unregistering an app or dropping provisioned resources, but most core workflows are fully supported.