Skip to main content

strands-osmo

PyPI version Docs License

Awesome Strands Agents

Strands OSMO

NVIDIA OSMO workflow orchestration for Strands Agents - submit, monitor, and debug Physical AI pipelines from natural language.

OSMO is NVIDIA's open-source Kubernetes-native control plane for Physical AI. It runs heterogeneous compute (training GPUs, simulation GPUs, edge devices) from a single YAML spec - used in production for GR00T, Isaac Lab, Isaac Dexterity, Isaac Sim, Isaac ROS.

This package wraps the production osmo CLI as 22 Strands tools so an agent can drive the entire workflow lifecycle in plain English.

Sister project: strands-cosmos (Cosmos VLM provider + 21 generation/edge tools).


🔌 Use as an MCP server

Use strands-osmo from Claude Code, Claude Desktop, Cursor, Kiro, or any MCP client — all 25 OSMO tools (workflows, tasks, data, datasets, apps, pools) become MCP tools.

claude mcp add osmo -- uvx strands-osmo

Claude Desktop config:

{
  "mcpServers": {
    "osmo": {
      "command": "uvx",
      "args": ["strands-osmo"]
    }
  }
}

Options:

strands-osmo --tools osmo_workflow_submit,osmo_workflow_status   # subset
strands-osmo --http --port 8000                                  # HTTP mode

Install

pip install strands-osmo

You also need the OSMO CLI on PATH:

curl -fsSL https://raw.githubusercontent.com/NVIDIA/OSMO/main/install.sh | bash
osmo login                  # one-time OAuth
osmo version                # confirm

Verify everything from your agent:

from strands_osmo import osmo_doctor
osmo_doctor()
# → {"osmo_present": True, "version_ok": True, "logged_in": True, ...}

Quick Start

Discover resources, submit a workflow

from strands import Agent
from strands_osmo import (
    osmo_doctor, osmo_pool_list, osmo_resources_list,
    osmo_workflow_validate, osmo_workflow_submit, osmo_workflow_status,
    osmo_workflow_logs, osmo_workflow_cancel,
    osmo_cookbook_fetch,
)

agent = Agent(tools=[
    osmo_doctor, osmo_pool_list, osmo_resources_list,
    osmo_workflow_validate, osmo_workflow_submit, osmo_workflow_status,
    osmo_workflow_logs, osmo_workflow_cancel,
    osmo_cookbook_fetch,
])

agent("""
Find me an idle H100 pool with at least 4 GPUs free,
fetch the GR00T fine-tune recipe from the cookbook,
validate it, then submit it. Report the workflow ID.
""")

One-shot pipeline

from strands_osmo import osmo_workflow_submit

osmo_workflow_submit(
    workflow_yaml="train.yaml",
    pool="h100-prod",
    set_vars={"num_gpu": 4, "epochs": 10},
    priority="LOW",   # bypass quota, run on idle capacity
)

Tools

Category Tools Wraps
Auth osmo_doctor, osmo_login, osmo_version env / osmo login / osmo version
Resources osmo_pool_list, osmo_resources_list, osmo_profile_list, osmo_bucket_list osmo pool/resources/profile/bucket list
Workflow osmo_workflow_submit, osmo_workflow_list, osmo_workflow_status, osmo_workflow_cancel, osmo_workflow_logs, osmo_workflow_exec osmo workflow ...
Task osmo_task_list, osmo_task_describe osmo task ...
Data osmo_data_upload, osmo_data_download, osmo_data_list osmo data ...
Dataset osmo_dataset_list, osmo_dataset_describe osmo dataset ...
App osmo_app_list, osmo_app_create osmo app ...
Cookbook osmo_cookbook_fetch GitHub raw / local clone
Spec osmo_workflow_validate, osmo_workflow_render local YAML + Jinja

Total: 25 tools (22 OSMO-CLI-backed + 3 local helpers).

from strands_osmo import osmo_pool_list, osmo_workflow_submit

osmo_pool_list(mode="free")
# → JSON: pools, free GPUs, quota state

osmo_workflow_submit("train.yaml", pool="h100-prod", set_vars={"epochs": 10})
# → workflow ID(s)

Why use it inside an agent?

OSMO already has a great CLI. The point of strands-osmo is letting an agent chain OSMO ops with reasoning:

Without an agent With an agent
osmo pool list → eyeball "Find me an idle H100"
Edit YAML by hand to fit quota "Cap memory to fit the smallest A100 node, then submit"
osmo workflow logs <id> → grep for stack trace "Why did workflow X fail and how do I fix it?"
osmo workflow submit && watch status "Submit, wait until done, summarize results, retrain on failure"

Architecture

strands_osmo/
├── __init__.py             # exports 25 tools
└── tools/
    ├── _common.py          # osmo CLI runner + ToolResult helpers
    ├── doctor.py           # env probe (osmo binary, login, profile)
    ├── login.py            # osmo login
    ├── version.py          # osmo version
    ├── pool_list.py        # osmo pool list [--mode free]
    ├── resources_list.py   # osmo resources list
    ├── profile_list.py     # osmo profile list
    ├── bucket_list.py      # osmo bucket list
    ├── workflow_submit.py  # osmo workflow submit
    ├── workflow_list.py    # osmo workflow list
    ├── workflow_status.py  # osmo workflow describe
    ├── workflow_cancel.py  # osmo workflow cancel
    ├── workflow_logs.py    # osmo workflow logs
    ├── workflow_exec.py    # osmo workflow exec
    ├── task_list.py        # osmo task list
    ├── task_describe.py    # osmo task describe
    ├── data_upload.py      # osmo data upload
    ├── data_download.py    # osmo data download
    ├── data_list.py        # osmo data list
    ├── dataset_list.py     # osmo dataset list
    ├── dataset_describe.py # osmo dataset describe
    ├── app_list.py         # osmo app list
    ├── app_create.py       # osmo app create
    ├── cookbook_fetch.py   # OSMO cookbook fetcher
    ├── workflow_validate.py# local YAML lint
    └── workflow_render.py  # local Jinja render

Design tenets:

  1. CLI is truth. Tools shell out to osmo, never re-implement its client SDK.
  2. Thin wrappers. Each tool ≈ 50 lines, normalizing JSON into Strands ToolResult.
  3. Graceful degradation. Missing osmo binary → exit 127 ToolResult, not crash.
  4. No upstream forking. Use OSMO as-is; it's a separate repo on disk.

Workflow YAML 101 (cheat sheet)

workflow:
  name: my-pipeline
  resources:
    default: { cpu: 4, memory: 16Gi, storage: 40Gi, gpu: 1 }

  tasks:
  - name: train
    image: pytorch/pytorch:2.6.0-cuda12.4-cudnn9-devel
    command: ["python", "train.py"]
    args: ["--epochs", "{{epochs}}", "--num-gpu", "{{num_gpu}}"]
    resources: { gpu: "{{num_gpu}}" }

Submit with:

osmo workflow submit my-pipeline.yaml --pool h100-prod \
    --set num_gpu=4 --set epochs=10

Or:

osmo_workflow_submit("my-pipeline.yaml", pool="h100-prod",
                     set_vars={"num_gpu": 4, "epochs": 10})

For the full reference (including groups, inputs, outputs.dataset, checkpointing, and platform constraints) see the OSMO User Guide.


Development

git clone https://github.com/cagataycali/strands-osmo && cd strands-osmo
pip install -e ".[dev]"
pytest tests/                # smoke tests
ruff check .                  # lint
ruff format .                 # format

See Also


License

Apache 2.0 - same license as upstream OSMO.

OSMO is © NVIDIA Corporation. strands-osmo is an independent community project.

Metadata

Release files for strands-osmo 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for strands-osmo 0.2.0
File Size Uploaded Provenance
strands_osmo-0.2.0.tar.gz 23.9 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for strands-osmo 0.2.0
File Interpreter ABI Platform
strands_osmo-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 53.9 kB

Release files / strands_osmo-0.2.0.tar.gz

Download URL strands_osmo-0.2.0.tar.gz
Size 23.9 kB
Tags Source
SHA-256 checksum
How to use checksums
a1d0fb6257ac0be423f277d832d0e39f8fa6b3a3e326fb243a7ea96b70ff424a
BLAKE2b-256 checksum
How to use checksums
6194b17b2d8e7bfbca45d265e0a181453b3d0297f2a4fed35b0d5957d2d8de15
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.13

Release files / strands_osmo-0.2.0-py3-none-any.whl

Download URL strands_osmo-0.2.0-py3-none-any.whl
Size 30.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
86842996a18e512ac9f893279106d711a5597acc81f43dfaa5f69cf4ad3ecd2a
BLAKE2b-256 checksum
How to use checksums
20613ab0e2c8adc9af44b1219c5c358464cb473f99865b11654f4f3d1454b61a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.13

Security for strands-osmo 0.2.0

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page