Bob Ross 🎨
"We don't make mistakes, just happy little servers."
An MCP server for managing a Canonical Landscape estate from an AI agent (Claude Desktop / Claude Code). Bob Ross wraps the Landscape API as MCP tools — inventory, alerts, activities, patching, script execution — with a safety layer built in so an LLM can't accidentally reboot your whole fleet.
Jira: BR
Why it's not just a dumb API wrapper
- Blast-radius preview —
resolve_queryshows how many machines a query matches (and a sample) before you act. - Dry-run → confirm handshake — every destructive tool returns a short-lived
confirm_tokenon the first call; you must call again with the token to execute. If the matched machine set drifts in between, the token is rejected. - Secure by default — read-only mode is on out of the box. Writes need two explicit switches flipped. TLS is verified. Secrets never hit logs.
- Full audit log — every action (dry runs, executes, denials) is appended to a redacted JSONL audit trail.
- Dual auth — REST bearer token or legacy HMAC query API, auto-detected.
Status
MVP scaffold. Read tools + gated write tools are implemented against both API
backends. Exact REST endpoint paths are set as constants in client.py and get
finalized once pointed at a live instance — run the ping tool to validate.
Setup
python3.14 -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
cp .env.example .env # then fill in URL + credentials
pytest # run the safety/signing/config tests
Configuration
All via BOBROSS_* env vars (or .env). See .env.example. Key ones:
| Var | Default | Meaning |
|---|---|---|
BOBROSS_LANDSCAPE_URL |
— | Landscape base URL |
BOBROSS_API_TOKEN |
— | REST bearer token (mode A) |
BOBROSS_ACCESS_KEY / BOBROSS_SECRET_KEY |
— | Legacy HMAC keys (mode B) |
BOBROSS_READ_ONLY |
true |
Blocks all writes |
BOBROSS_ALLOW_WRITES |
false |
Second switch required for writes |
BOBROSS_TLS_VERIFY |
true |
Verify TLS certs |
Run
bob-ross # stdio transport (Claude Desktop / Code)
# or
python -m bob_ross
Claude Code (CLI)
Install once (user scope → available in every project). The cd wrapper makes it
location-independent and keeps credentials in .env (never in Claude's config):
claude mcp add bob-ross --scope user -- \
bash -lc 'cd /path/to/bob-ross && exec ./.venv/bin/bob-ross'
Starts in read-only mode. To enable actions, flip BOBROSS_READ_ONLY=false and
BOBROSS_ALLOW_WRITES=true in .env, then restart Claude Code.
Claude Desktop / Code (stdio)
{
"mcpServers": {
"bob-ross": {
"command": "/path/to/bob-ross/.venv/bin/bob-ross",
"env": { "BOBROSS_LANDSCAPE_URL": "https://landscape.example.com",
"BOBROSS_API_TOKEN": "..." }
}
}
}
Tools
Read: ping, estate_health, list_computers, get_computer, resolve_query,
pending_updates, list_alerts, list_activities, get_activity, wait_for_activity,
list_scripts
Write (gated): execute_script, reboot_computers, apply_security_upgrades,
upgrade_packages, install_packages, remove_packages, add_tags, remove_tags
Activity-creating write tools accept wait=true to poll the resulting Landscape
activity to a terminal status and return a completion summary
(succeeded / failed / still-incomplete), so the agent knows the real outcome
instead of just "queued".
Resources: landscape://computers, landscape://alerts, landscape://health,
landscape://computer/{computer_id} (template)
Prompts: patch_security_updates, triage_estate, reboot_reboot_required,
patch_machine
Metadata
Release files for bob-ross-landscape 0.1.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 | |
|---|---|---|---|
| bob_ross_landscape-0.1.0.tar.gz | 22.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| bob_ross_landscape-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 43.4 kB
Release files / bob_ross_landscape-0.1.0.tar.gz
| Download URL | bob_ross_landscape-0.1.0.tar.gz |
|---|---|
| Size | 22.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ebaecc90227aa1c80668ccc1629f7df72ac6c895b3253691195a1ed805761c95
|
|
BLAKE2b-256 checksum How to use checksums |
369ef7b3b55480cfc8477e88ad1de5637169e081f21a587486558579c6fbe968
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
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 Jul 5, 2026.
Transparency logRelease files / bob_ross_landscape-0.1.0-py3-none-any.whl
| Download URL | bob_ross_landscape-0.1.0-py3-none-any.whl |
|---|---|
| Size | 20.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
70beb1f1ea77b9f44bcd7a836a905320f1a34351980e268cda55d657acbb81ea
|
|
BLAKE2b-256 checksum How to use checksums |
00b92161059371328c635e568f7ae43aed4f91f6e0b711b825560ca311676336
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
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 Jul 5, 2026.
Transparency log