Opsmith: An AI devops engineer in your terminal
Opsmith is a command-line tool that acts as an AI-powered DevOps assistant. It's designed to streamline the process of deploying your applications to the cloud, from analyzing your codebase to provisioning infrastructure and deploying your services.
Opsmith helps you with the following tasks:
- Codebase Analysis: It scans your repository to automatically detect services, programming languages, frameworks, and infrastructure dependencies (like databases or caches).
- Configuration Generation: Based on its analysis, Opsmith generates necessary deployment artifacts.
- Infrastructure Provisioning: It uses tools like Terraform and Ansible to provision and configure required cloud resources on supported providers (e.g., AWS, GCP).
- Deployment: It handles the deployment of your application using various strategies, such as a monolithic deployment on a single virtual machine for hobby projects.
The primary goal of Opsmith is to make cloud deployments accessible to all developers, regardless of their DevOps expertise. It achieves this by automating complex tasks through an interactive setup process, allowing you to focus on writing code. Opsmith is also designed to prevent cloud provider lock-in, which helps control long-term costs. The generated configurations are standard and maintainable, making it easy to hand over the deployment to an in-house DevOps team.
Table of Contents
- Getting Started
- User Guide
- Contributing
Getting Started
Installation
-
Prerequisites: Opsmith requires
DockerandTerraformto be installed and available in your system'sPATH.-
macOS (with Homebrew):
brew install --cask docker brew install terraform
After installation, make sure you start Docker Desktop.
-
Windows (with Chocolatey):
choco install docker-desktop terraform
After installation, make sure you start Docker Desktop.
-
Linux (Debian/Ubuntu): Please follow the official installation guides for Docker and Terraform.
-
-
Install Opsmith: Once the prerequisites are installed, you can install Opsmith using
pip:pip install opsmith-cli
On macOS, you might need to use
pip3ifpipdoesn't work.
Deployment Workflow
Deploying your application with Opsmith follows a straightforward workflow:
-
Setup Your Project
Navigate to your project's root directory, which should be a Git repository, and run the
setupcommand. This command initializes your deployment configuration by analyzing your codebase to detect services and infrastructure requirements.opsmith --model <your-llm-provider:model-name> --api-key <your-api-key> setup
-
Deploy Your Application
After setting up the configuration, deploy your application using the
deploycommand:opsmith --model <your-llm-provider:model-name> --api-key <your-api-key> deploy
-
Manage Your Deployments
To manage an existing environment, run the
deploycommand again. You can select an environment and perform the following actions:release: Deploy a new version of your application.run: Execute a command on a specific service within your environment (e.g., run database migrations).delete: Tear down all the infrastructure and delete the environment.
User Guide
LLMs
Opsmith leverages Large Language Models (LLMs) to analyze your codebase, generate configurations, and make decisions about your infrastructure. To use Opsmith, you must provide an LLM model and a corresponding API key from the model's provider.
Supported Models
Opsmith supports a variety of models from different providers. Here is a list of the currently supported models:
- Google (Recommended):
google:gemini-3.1-pro-preview
- OpenAI:
openai:gpt-5.5openai-responses:gpt-5.5-pro
- Anthropic:
anthropic:claude-sonnet-4-6anthropic:claude-opus-4-8
Usage
To specify which model to use, pass the --model option with the full model name, and provide your API key with the --api-key option.
Example with OpenAI:
opsmith --model openai:gpt-5.5 --api-key YOUR_OPENAI_API_KEY COMMAND
Example with Anthropic:
opsmith --model anthropic:claude-sonnet-4-6 --api-key YOUR_ANTHROPIC_API_KEY COMMAND
Example with Google:
opsmith --model google:gemini-3.1-pro-preview --api-key YOUR_GEMINI_API_KEY COMMAND
Neither option has to be typed. Opsmith looks for the model in --model, then in OPSMITH_MODEL,
then in a model: entry in .opsmith.conf.yml; and for the key in --api-key, then in the
provider's own variable (OPENAI_API_KEY, ANTHROPIC_API_KEY or GEMINI_API_KEY). That keeps the
secret off the command line and out of your shell history:
export OPSMITH_MODEL=google:gemini-3.1-pro-preview
export GEMINI_API_KEY=...
opsmith COMMAND
A missing or unknown model stops the run with the list of models Opsmith knows.
Checking your configuration
opsmith config reads .opsmith/deployments.yml and needs no cloud account, docker or terraform,
so it works anywhere the package is installed:
opsmith config validate # exits 0 if the configuration is usable, 2 with the problems if not
opsmith config show # the configuration as Opsmith understands it
opsmith config schema # the JSON Schema of the configuration
opsmith config schema --format markdown > SCHEMA.md
Add --output json to any command for a single JSON document on stdout, with progress on stderr.
Use with Claude Code, Codex and other agents
Opsmith ships an Agent Skill: a set of instructions that teaches a coding harness how Opsmith works, what it may edit, and which commands to run. Install it into your project and the agent can take a repository to a deployed environment without being told the commands.
opsmith agent install --target claude # or codex, opencode, cursor, gemini, agents
opsmith agent install --target auto # wherever a harness is already set up here
opsmith agent install --target claude --agents-md # also add an Opsmith section to AGENTS.md
opsmith agent status # where it is installed, and whether it is current
opsmith agent uninstall # remove exactly what was installed
--target is required, because installing writes into directories belonging to your other tools
and a project that uses one harness should not acquire five more by default. uninstall needs no
target: it can only take back what it recorded putting there.
This needs no model and no cloud account - it copies files - so it is safe to run first. It writes
into .claude/skills/, .agents/skills/ and the equivalent directory for Codex, OpenCode, Cursor
and Gemini CLI. agent status says which of those paths have been verified against the harness
itself; the conventions are still moving, and an unverified path is Opsmith's best reading of one.
Re-run the install after upgrading Opsmith, so the skill matches the CLI. agent status reports an installed skill as stale when it does not.
What the agent will do
With the skill installed, an agent asked to deploy a repository will typically write
.opsmith/deployments.yml itself, from what it reads in your code, then have Opsmith check it:
opsmith --output json config validate
opsmith --output json dockerfile validate
opsmith --output json env plan --name dev --provider AWS --strategy Monolithic
opsmith --output json env create --name dev --provider AWS --region us-east-1 --strategy Monolithic
dockerfile validate is the one command added for this: it builds each service's Dockerfile and
runs the image, and reports what happened. It exits 4 when a Dockerfile is at fault, and 0 when the
container merely exited for want of a database it has not been given yet - so an agent does not
try to fix a file that is already correct.
The safety rules
The skill tells the agent, in as many words:
- Only
.opsmith/deployments.ymland the Dockerfiles are yours to edit. Everything under.opsmith/environments/belongs to Opsmith and is rebuilt or is state. - Never run terraform or ansible by hand inside
.opsmith/. - Never destroy an environment the user has not named. There is no flag that approves an
irreversible action in advance:
destroyneeds--answer delete.confirm=DELETE, spelled out, and--accept-defaultsrefuses it.
The long version, including the table of install paths, is in docs/reference/2026-09-21-agent-skill.md.
Running Opsmith without a terminal
opsmith setup and opsmith deploy are menus, meant for a person. Everything they can do is also
a subcommand that takes flags, returns a typed result and never prompts — which is what a script,
a CI job or a coding agent should drive.
The commands
opsmith init --app-name "My App" # write .opsmith/deployments.yml, without scanning
opsmith setup --rescan --accept-detected # detect services and generate Dockerfiles
opsmith env list # what environments this repository declares
opsmith env plan --provider AWS --strategy Monolithic # what creating one will ask for
opsmith env status --env dev # what one of them is running
opsmith env create --name dev --provider AWS --region us-east-1 --strategy Monolithic \
--domain api=api.example.com --domain-email me@example.com
opsmith release --env dev # build the last commit and deploy it
opsmith update --env dev # reconcile a deployed environment with the config
opsmith run --env dev --service api -- ls -la
opsmith --answer delete.confirm=DELETE destroy --env dev
env list, env plan and env status need no docker and no terraform, so they answer on a
machine with none of that installed. env create --no-deploy writes the environment to the
configuration without creating anything.
opsmith run exits with whatever the remote command exited with, so it can stand in for the
command itself in a script.
Every command accepts --output json, which writes exactly one document to stdout and sends all
progress to stderr:
{"ok": true, "command": "env create", "result": {"resources": [{"kind": "virtual_machine", "id": "i-0abc", "address": "203.0.113.10", "size": "t4g.small"}], "urls": {"api": "https://api.example.com"}}, "warnings": []}
{"ok": false, "command": "env create", "error": {"code": "MISSING_ANSWER", "message": "...", "hint": "...", "details": {"key": "env.region", "choices": ["us-east-1", "..."], "resume": "opsmith env create --name dev"}}}
| Exit code | Meaning |
|---|---|
| 0 | success |
| 1 | unexpected failure |
| 2 | usage or validation error |
| 3 | the run needs an answer it does not have |
| 4 | an external tool failed: terraform, ansible or docker |
| 5 | cloud credentials or permissions |
| 6 | a model step could not produce a usable result |
| 7 | state conflict |
| 8 | something outside Opsmith has to happen first |
Answering questions from the command line
Every question Opsmith asks has a stable key, and every flag above is shorthand for answering one:
--region us-east-1 is --answer env.region=us-east-1. Answers may also come from a file, a
dotenv file or the environment, in this order:
| Option | Answers |
|---|---|
--answer key=value |
one question, repeatable, and wins over everything else |
--env-file <file> |
the envvar.<KEY> questions, secrets included |
--answers <file> |
a YAML mapping of key to answer |
OPSMITH_ANSWER_<KEY> |
one question, with dots upper-cased into underscores |
--accept-defaults |
each question's own default, where it has one |
--accept-detected |
setup only: the detected services and dependencies, without opening an editor per service |
There is no blanket "say yes to everything" flag, and that is deliberate. Anything irreversible is
approved by naming it — --answer delete.confirm=DELETE, --answer update.confirm_infra_changes=true — so approving one gate never approves another, and
--accept-defaults refuses these keys outright.
--non-interactive forces this mode; so does --output json, and so does a stdin that is not a
terminal. Every answer is remembered under ~/.opsmith/projects/<name>/environments/<env>/, so a
re-run never asks the same question twice.
Knowing what it will ask, first
opsmith env plan answers that without creating anything:
opsmith env plan --provider AWS --strategy Monolithic --accept-defaults
It reports every answer a creation will need — the key, the question, the options where it can list them, the default where there is one, and the environment variable to put a secret in — and which of them this run would actually stop for. Nothing is created, no configuration is written, and it needs neither docker nor terraform. It will read from your cloud account where it can, to list the regions that account really has, but a machine with no credentials yet still gets the plan; it just says which parts of it went unlisted.
Which questions exist depends on the cloud provider and the strategy, so a plan that has not been
told those two reports what it can and names them as the answers to give first. Give them, run it
again, and the branch they open is listed too. The same is true of a provider or strategy plugin
that declares no questions: complete is false and partial_reasons says which one is quiet.
--write-answers FILE writes the list as a YAML file to fill in and hand back with --answers.
Anything with a default is written with it; anything still to be answered is written commented
out, because a key present with an empty value would count as an answer of the empty string. A
secret is always commented out — those belong in a --env-file.
The driver loop
Nothing has to be planned up front. Run the command; if it stops, do the one thing it asks for and run it again:
- Exit 3 — a question had no answer.
error.detailsnames thekey, thechoicesit must come from, andresume: the same command, ready to run again once the answer is added. - Exit 8 — something outside Opsmith has to happen first, such as a DNS record being created.
error.detailssays what, andresumeis the command that picks up where it stopped.
until opsmith --output json env create --name dev --provider AWS > result.json; do
case $? in
3) ;; # read result.json for the key, add --answer, run again
8) ;; # create the records it names, run again
*) break ;;
esac
done
Tracing
Tracing through Logfire is an optional extra:
pip install "opsmith-cli[logfire]"
opsmith --logfire-token YOUR_TOKEN COMMAND
Cloud Providers
Opsmith uses your cloud provider's command-line tools to authenticate and manage resources. Before using Opsmith, you need to configure the credentials for your chosen cloud provider.
AWS (Amazon Web Services)
Opsmith uses the official AWS CLI to interact with your account.
-
Install the AWS CLI: Follow the official installation guide for your operating system.
-
Configure Credentials: Once installed, configure the CLI with your AWS credentials by running:
aws configureYou will be prompted to enter your
AWS Access Key ID,AWS Secret Access Key, default region, and default output format. This will store your credentials in the~/.aws/credentialsfile, which Opsmith will use automatically.
GCP (Google Cloud Platform)
Opsmith uses the Google Cloud CLI to authenticate.
-
Install the gcloud CLI: Follow the official installation guide for your operating system.
-
Authenticate with Application Default Credentials (ADC): Run the following command to log in and create your ADC file:
gcloud auth application-default login
This command will open a browser window for you to log in to your Google account and authorize access. Once completed, your credentials will be stored locally, and Opsmith will use them to authenticate.
Deployment Strategies
Deployment strategies in Opsmith define the architecture and approach for deploying your application. When you create a new environment, you will be prompted to select a strategy that best fits your project's needs. Each strategy automates the provisioning of specific infrastructure and handles the deployment process accordingly.
Monolithic
The Monolithic strategy is designed for simplicity and is ideal for hobby projects, experiments, or small-scale applications. It deploys your entire application to a single virtual machine (VM).
Key features of the Monolithic strategy include:
- Single Virtual Machine: Provisions one VM to host all backend services and infrastructure dependencies.
- Containerization: Backend and full-stack services are containerized using Docker and managed with
docker-compose. This isolates services and simplifies dependency management. - Frontend Deployment: Frontend services are built and deployed to a cloud storage bucket (like AWS S3 or GCS) and served through a Content Delivery Network (CDN) for optimal performance.
This strategy is a great starting point for getting your application running in the cloud quickly with minimal complexity.
Deployments Directory
When you run opsmith, it creates a .opsmith directory in the root of your project. This directory stores all the configurations, generated artifacts, and state files required to manage your deployments. This directory is intended to be committed to your git repository so that your deployment configurations are versioned. Sensitive files like Terraform state are automatically ignored.
Here is an overview of what you can find inside the .opsmith directory:
deployments.yml: The main configuration file for your application. It contains the list of services, infrastructure dependencies, cloud provider details, and environment configurations.docker/: Contains the generatedDockerfiles for each of your services, organized into subdirectories by service name.environments/: This directory holds the state and configuration for each of your deployment environments (e.g.,dev,staging).<environment-name>/: A directory for each environment, containing Terraform state for provisioned infrastructure and other environment-specific files.global/: Contains configurations that are shared across environments within a specific region, such as container registries.
Extending Opsmith
Opsmith has been designed with extensibility in mind, allowing you to add your own cloud providers and deployment strategies. This is achieved through Python's entry points mechanism, which enables other packages to plug into Opsmith seamlessly.
Adding a Cloud Provider
To add a new cloud provider, you need to:
-
Create a Python class that inherits from
opsmith.cloud_providers.base.BaseCloudProviderand implements its abstract methods (name,description,get_detail_model,detect_account,build_detail,get_instance_types).Reaching an account is three separate things, because only the first two can happen before a person is involved.
detect_accountchecks that the account can be reached and reads the facts that are not a matter of choice — an account id, the path to a helper — and must not ask anything.build_detailturns that plus the answers into the record the environment keeps indeployments.yml.In between,
questionsdeclares what your provider needs chosen — a region, a project — as data rather than as prompts, which is what puts it inopsmith env planbefore a run starts. Each question names the key it is answered by, and a question whose options depend on an earlier answer says so withdepends_on, so they are asked in an order that works. A choice loader that cannot list its options here — no credentials yet — returnsNonerather than failing, and the plan reports the question without them.Declaring is optional. A provider that implements only the three abstract methods and asks whatever it needs through
ctx.interactinsidebuild_detailworks exactly as before; the only thing it gives up is being listed byenv plan, which then says its list is partial. -
Package your new provider class.
-
In your package's
pyproject.toml, add an entry point under the[project.entry-points."opsmith.cloud_providers"]group.
Example pyproject.toml entry:
[project.entry-points."opsmith.cloud_providers"]
my-provider = "my_opsmith_plugin.providers:MyCloudProvider"
Once your package is installed in the same environment as opsmith-cli, Opsmith will automatically discover and register your new provider.
Adding a Deployment Strategy
Similarly, you can add a new deployment strategy by:
-
Creating a Python class that inherits from
opsmith.deployment_strategies.base.BaseDeploymentStrategyand implements its abstract methods (name,description,deploy,release,update,run,destroy,status).The five action methods each return a result model from
opsmith.core.resultsdescribing what they did — the infrastructure and urls fordeploy, the images and verdict forrelease, the exit code forrun, and so on — which is what the CLI puts in the JSON envelope.statusreports what the environment is running by reading its own state file, and must not contact a cloud.Infrastructure is reported as a list of
Resource, never as named fields like a public IP, so a strategy that raises several machines, deploys to a cluster, or creates nothing a person could SSH into describes what it actually made. Each one carries akind— aResourceKindvalue where one fits, or your own word where none does — anid, and whatever ofname,region,address,sizeanddetailsapplies.A strategy asks the user whatever it needs, wherever it needs it, through
ctx.interact; nothing has to be declared up front. Its steps must be safe to run again, because a run that stops for an answer resumes by repeating the command — wrap anything that is not withwith ctx.steps.once("name") as should_run:.You may also implement
questions, listing what you are going to ask, so thatopsmith env plancan report it before a run starts. It is not a promise to ask only those, and nothing is ever asked on your behalf — you still ask inline. A strategy that declares nothing is reported as a partial plan and behaves exactly as it always did. -
Packaging your new strategy class.
-
In your package's
pyproject.toml, add an entry point under the[project.entry-points."opsmith.deployment_strategies"]group.
Example pyproject.toml entry:
[project.entry-points."opsmith.deployment_strategies"]
my-strategy = "my_opsmith_plugin.strategies:MyStrategy"
After installation, your custom deployment strategy will be available for selection when creating a new environment.
Contributing
We welcome contributions to Opsmith! If you're interested in helping improve the tool, here are a few ways to get started:
- Reporting Bugs: If you encounter a bug, please open an issue on our GitHub repository. Include as much detail as possible, such as your operating system, the command you ran, and the full error message.
- Suggesting Enhancements: Have an idea for a new feature or an improvement to an existing one? We'd love to hear it. Open an issue to start a discussion.
- Submitting Pull Requests: If you'd like to contribute code, please fork the repository and submit a pull request. For major changes, it's best to discuss your idea in an issue first.
When contributing, please follow our engineering conventions and ensure your code is formatted with black.
Metadata
Release files for opsmith-cli 0.7.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| opsmith_cli-0.7.0.tar.gz | 4.0 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| opsmith_cli-0.7.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 4.4 MB
Release files / opsmith_cli-0.7.0.tar.gz
| Download URL | opsmith_cli-0.7.0.tar.gz |
|---|---|
| Size | 4.0 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
618f6af2f97301446777f82fa14b442d2516916b59c506bbd6a79f3d56ea309a
|
|
BLAKE2b-256 checksum How to use checksums |
bbfc17ab7849452af8793245202a7b2ce2d9eae4e77419803aa6342cf9788d4c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 2, 2026.
Transparency logRelease files / opsmith_cli-0.7.0-py3-none-any.whl
| Download URL | opsmith_cli-0.7.0-py3-none-any.whl |
|---|---|
| Size | 394.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
17e3181640e865db0f2d16afe3459738e297c54de0e3fd2166b3f859b38ef1b0
|
|
BLAKE2b-256 checksum How to use checksums |
ceb180b084ff75cf3e27091f0137d7c32abec8d50beab22df60f38d5666be230
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 2, 2026.
Transparency log