Every command runs from your content repo — that is what says which deployment you mean —
and every one takes --help.
npx @meffecta/agent help lists all of them; these are the ones you will use.
| doctor | The one to run when something feels wrong — it judges rather than describes, and every finding carries the command that fixes it |
| status | Engine version, revision, runtime shape, triggers, and what is in the queue right now |
| jobs | What the service has registered, and what triggers each |
| env / secrets | Every setting, and what is in Secret Manager — values are never printed |
| triggers | The Cloud Scheduler jobs and the task queue that drive it |
| logs --limit 100 | Recent service logs |
| run <job> | Trigger one job now, or --in <seconds> |
| ask "…" | Ask it something as a one-off run, with the same skills and context a job gets |
| create-job "…" | Have it write a new job page from a description, for you to read and edit |
| check-jobs | Re-check the job pages here — worth running after you edit one by hand |
| verify-credentials | Exercise every credential the deployment holds, from inside it |
| resources | Everything the set-up built in Google Cloud, what each part is for, and a console link to each |
| sweep | Run the housekeeping pass now: fire due follow-ups, re-drive stranded runs, check the inboxes |
| upgrade | Whether a newer tool is out, and what your deployment is running |
| deploy | Move to a new engine version, and re-assert the runtime shape |
This is what doctor is for, and why it exits non-zero — you can run it on a schedule.
npx @meffecta/agent doctor
allowFrom: refuses every message — deliberately, but silently if you were not expecting it.The first two come from the same fact: the service has CPU only while a request is open, so on the default shape nothing inside it can run on a timer. Work arrives as a request — Cloud Scheduler for the crons and the sweep, Cloud Tasks for everything else — and the handler holds that request open until the run settles. Pin the service to always-on and the opposite is true, and running both at once is what fires everything twice.
Your call, always. Pushing to our repo deploys nothing to yours.
npx @meffecta/agent@latest upgrade # what is out, and what you run npx @meffecta/agent@latest deploy # move to it
The tool and the engine travel as a pair: each release of @meffecta/agent
deploys the engine image published alongside it, so the version of the tool you run is
how you choose your engine. That is why the upgrade is @latest rather than a
flag.
A deploy also restarts the service, which is what picks up new triggers from your content repo, and re-syncs the Cloud Scheduler jobs to match.
npx @meffecta/agent deploy --tag 1.0.13
Any published version, by number. Your registry keeps a cache and fetches anything it has expired, so an old version is always reachable.
status reports the engine line you expect. It reads it from the running
service rather than repeating the tag you asked for, so a rollout that did not land says so.
Everything but /health and /webhooks/* needs AGENT_API_SECRET, as a bearer token or a basic-auth password.
| GET /health | Unauthenticated liveness, and which engine is answering: version and build |
| GET /ask | A prompt box for a person with a browser. Basic auth, so a browser prompts — any username, the secret as the password |
| GET /test?prompt=… | An ad-hoc run, with &model=, &effort=, &timeoutSeconds= |
| GET /jobs | What was registered when the service last booted — not a read of your repo right now |
| POST /jobs/:name/run | Trigger one, optionally ?delaySeconds=N |
| GET /queue | What is running, what is waiting, and what follow-ups are pending |
| POST /webhooks/:name | One per job declaring webhook: — how they are verified |
| GET /spawns | Pending follow-up runs; DELETE /spawns/:id cancels one |
/ask in a browser is the way in for someone on your team who should be able to
ask the agent things without a terminal or a GitHub account. Same skills, same credentials,
same system prompt as a job; nothing journaled.
Which of the three kinds of change you are making decides what you have to run.
| A prompt, a fact, a rule | git push. Live on the next run — job prompts, run settings, SYSTEM.md, systems/, worlds/, your own skills. |
| A trigger | git push then deploy. A new job file, a renamed one, or a changed cron: / webhook: / inbox: / allowFrom:. |
| A credential | set-secret or set-env, which redeploys the service by itself. Re-running set-secret on an existing name rotates it. |
Pausing something is disabled: true in the job's frontmatter — push-effective,
so it takes effect immediately and stops pending follow-ups too. That makes it the right
kill switch for a job doing something you did not expect.
Two buckets in your own project. Neither is ever mounted anywhere else.
| Memory | <MEMORY_DIR>/jobs/<name>/ per job, plus the queue journal and the spawn spool. Durable across deploys and restarts — this is what makes a weekly job feel like the same colleague each week. |
| Audit | Every prompt, result and full transcript, write-once, kept a year. Never mounted into a run. It is the record of what the agent was asked and what it did. |
Runs are at-least-once by design — a task delivery can be retried, and the sweep re-drives anything a dead process left behind. An instruction should therefore be safe to repeat, and a job that acts on messages or events should keep a ledger of what it has already handled.
The same engine, without Google Cloud.
A Mac mini or any always-on box runs the service natively — Node 24, the claude
CLI, git, gh, and a .env. There it drives itself:
in-process timers fire the crons, poll the inboxes and check for due follow-ups, because the
process is always awake. Leave the task-queue settings unset and that is the shape you get.
Run it in exactly one place at a time. Cloud Run and a local box both running means every cron fires twice and both send the email. Moving between them means scaling one to zero first — and the journal does not transfer, so do it while nothing is queued.
The things that authenticate as the Cloud Run service account — GA4, Search Console, Google Ads, BigQuery, domain-wide delegation — are Cloud Run only. Off it those skills report themselves unavailable and the jobs that used them degrade rather than fail.