Skip to main content
The keystroke CLI is the primary way to build, deploy, and operate Keystroke projects. You’ll use it to scaffold a project, ship it to the platform, and then invoke and inspect what’s running there. Keystroke is deploy-first: edit your codebase, deploy, then run and inspect against your cloud project on the platform. Command shape — resource collections use plural names (matching the HTTP API): keystroke <collection> <verb> [<slug>]. Examples: keystroke workflows run greeting, keystroke triggers disable inbound-email-poll, keystroke apps execute github ….
Run keystroke --help, or keystroke <command> --help, for the authoritative list of flags on any command.

Install

Install the keystroke command globally. Requires Node.js ^22.18.0 || >=24.0.0 (Node 23 is not supported).
To refresh the CLI and every project @keystrokehq/* dependency to npm latest:
keystroke deploy / build / lint / typecheck require those packages to be current and will tell you to run keystroke update when they are not.

Authentication

Log in once and the token is reused for every command. Switching organizations does not require logging in again.
Your token is stored in your operating system’s secure credential store (Keychain, Credential Manager, or secret service).

Project targeting

Most runtime commands (workflows, agents, triggers, credentials, connect, health) run against your deployed cloud project on the platform. Which platform project you deploy to is stored in the project’s keystroke.config.ts as optional project and organization slugs — set by keystroke projects link or keystroke init --project. Global CLI config lives in ~/.keystroke (active organization and related settings).
For a one-off override that doesn’t change your config, pass --project:

Scaffold a project

Create a project from the default template, then deploy it.
Or seed the link at init time:
keystroke init creates keystroke.config.ts, a committed tsconfig.json (extends @keystrokehq/cli/tsconfig.json), a src/ directory with an example agent, and an AGENTS.md guide so your coding agent knows how Keystroke works. Lint, typecheck, and test tooling (oxlint, TypeScript, vitest, @types/node) ship inside @keystrokehq/cli — projects do not declare them or ship .oxlintrc.json / vitest.config.ts. AGENTS.md is versioned to your CLI — commands run inside the project re-sync it automatically after a CLI update. For deeper context, use keystroke docs search and keystroke docs query.
package.json scripts (pnpm lint, pnpm typecheck, pnpm test) call these commands. Config files stay in the CLI bundle — nothing is written into your project when you run them.

Deploy

Deploy runs lint and typecheck, builds your project, uploads the dist/ artifact, and activates it on the platform. Link the directory first (or pass --project for a one-off deploy). After deploy, runtime commands target your linked cloud project. A lockfile in your project is not part of what ships — deploy uploads only the built dist/ tree. You do not need to run keystroke lint, keystroke typecheck, or keystroke build first — deploy is the gate.
Pass --filter <entry> to build and deploy only matching module entries on top of the active artifact, useful for fast, targeted redeploys after a full deploy.

Pull

keystroke pull is the inverse of deploy: it downloads a project’s active deploy source into a local directory and installs dependencies. Use it to start from a project that was created or deployed elsewhere — for example, onto a fresh machine.
pull targets the linked project in keystroke.config.ts when --project is omitted. A directory that already contains an unrelated project is refused unless you pass --force; a directory from a prior pull of the same project refreshes in place, and a pull that’s already on the active artifact exits without changes.

Invoke and inspect

Run your workflows and agents, fire triggers, and audit run history against your deployed cloud project.

Workflows

See workflow forms for when to use forms, field presentation, and dashboard publish.

Agents

Actions

Discover and run catalog actions with a single <app> <tool> shape at every step — find → inspect → run. Credentials stay in the cloud; the CLI proxies execution through /mcp/execute, so no project code is required.
apps actions list and apps actions get print next steps (run ad-hoc, import into code, connect) after their output. Slugs are case-insensitive. If the app is not connected, apps execute exits with a hint to run keystroke connect <app>. Catalog vs custom org apps. Built-in catalog apps (github, exa, …) expose toolkit actions you can list/execute. Custom org apps ({org}/{name}, from apps create) are credential templates only — their actions live in your project as defineApp(...).action(...).
Credential resolution matches the runtime: it uses the project default, then the org default. Project credentials only resolve when you target a project with the global --project <slug> flag (or run inside a linked project); without it, only org credentials resolve. User credentials are never a default — reach one explicitly with --credential <slug>.
Pass --credential <slug> to pin a specific instance when a scope has more than one — the slug is the one you set with keystroke credentials create <key> --slug <slug> and can see with keystroke credentials list. It’s also the only way to use a user-scoped credential.

Triggers

History (cloud)

Integrations and secrets

Connect third-party accounts and manage the credentials your agents and workflows use.
connect requires an app slug (see keystroke apps list for connectable slugs) and chooses scope in the web flow — scope and project pinning are set on credentials create, not connect. For credential values, --set key=value takes a literal, and --set key=@env:VAR reads from your shell (falling back to the project .env). credentials update --scope moves one existing instance (exactly one of org, user, or project); credentials duplicate fans out copies like create. See connect and manage apps. apps create’s --field syntax is key, key:secret, key:optional, or key:secret:optional (repeatable). For manual custom apps, --name and at least one --field are required; --description defaults to --name when omitted. Optional --logo <url> sets a public image URL for the Apps catalog (same as Logo URL in the web create dialog). Example: keystroke apps create --name Acme --description "Internal Acme API" --logo https://example.com/acme-logo.png --field apiKey:secret. With --mcp, --openapi, or --graphql, auth and credential fields are auto-detected from the URL (this registers a connectable org catalog app, not only local scaffolding); use --preview to print the assembled request without creating, and --name, --slug, --description, --logo, --field, or --auth (MCP only) to override detected values. After create, connect with keystroke connect <slug>, then author actions with defineApp / apps sync — see custom apps and MCP. LLM provider API keys (BYOK for model inference) are not app credentials — connect those with keystroke managed-services instead.

Managed services (cloud)

Bring your own LLM provider API keys for organization-wide inference. See Managed services.

Channels

Bind agents to external channels (like Slack) so people can talk to them where they already work. For Slack, connect slackbot first (keystroke connect slackbot), then bind channels — see external channels.

Organization and access

Manage members and platform API keys for your active organization. Most of these are org-admin operations.

Docs

Read the Keystroke documentation from the CLI. These commands need no authentication, organization, project, or config — they work the moment the CLI is installed, for you and your coding agent alike.
See docs for agents for how query works (stateless calls, output caps) and more examples.

Feedback

Coding agents can report build friction directly to the Keystroke team. Use this after a build loop when the agent encountered unclear documentation, confusing errors, unexpected framework constraints, missing capabilities, or non-obvious workarounds. feedback create requires authentication and an active organization. The platform attaches the signed-in user’s identity and organization automatically; the CLI also includes its version and the linked project slug when available.
The message is freeform; the recap and numbered feedback above are a suggested structure. Write it for a Keystroke team member with zero context on the session: plain language first, technical detail (paths, commands, error text) second, one numbered item per issue. Run keystroke feedback create --help for the full writing guide. Do not include secrets, tokens, credentials, private source dumps, proprietary code, or personal data from project files or user inputs. Success prints { "ok": true }. See CLI for agents for when coding agents should use this command.

Global options

--project applies to platform-targeting commands; docs commands ignore organization/project scope. --version and --help work on every command.

Using the CLI with AI agents

Keystroke is built for coding agents. Learn how agents use the CLI, the docs commands, and headless mode to build and operate your project.