Skip to main content

sillydev

The Python client for the Silly Development panel API: start, stop and restart your bots, send console commands, manage files and backups, and deploy from Git, all from your own code. It also comes with a sillydev command line tool and an MCP server for AI assistants.

Full API docs: https://sillydev.co.uk/docs/panel

Install

pip install sillydev

Python 3.9 or later. The only dependency is httpx.

Quick start

Create an API key in the panel under Account, API keys and put it in the SILLYDEV_API_KEY environment variable. Keys start with sdevc_ (older ptlc_ keys keep working).

from sillydev import SillyDev

client = SillyDev()  # or SillyDev(api_key="sdevc_...")

for server in client.panel.servers.list():
    print(server["identifier"], server["name"])

client.panel.servers.power("1a7ce997", "restart")
client.panel.servers.command("1a7ce997", "say Back in a minute")

Each server has an 8-character identifier, shown in the panel and in the identifier field of every server. Every method takes it (or the full UUID) as its first argument.

Examples

from sillydev import SillyDev

client = SillyDev()
panel = client.panel
server = "1a7ce997"

# Live state and resource use
stats = panel.servers.resources(server)
print(stats["current_state"], stats["resources"]["memory_bytes"])

# Restart and wait until it's running again (raises WaitTimeoutError after 120 seconds)
panel.servers.restart(server)
panel.servers.wait_for_state(server, "running", timeout=120)

# Files
for f in panel.files.list(server, directory="/"):
    print(f["name"], f["size"])
config = panel.files.read(server, "/config.json")
panel.files.write(server, "/config.json", config.replace("debug", "info"))

# Backups
backup = panel.backups.create(server, name="before-update")
print(backup["uuid"])

# Deploy the linked Git repository
deployment = panel.git.deploy(server)
print(deployment["status"])  # "queued"

# Startup variables
panel.startup.set_variable(server, "MAIN_FILE", "bot.py")

Responses

Methods return plain dicts and lists. The API's {"object": ..., "attributes": {...}} envelopes are removed, so panel.servers.get(server)["name"] just works.

Pagination

panel.servers.list(), panel.backups.list(), panel.servers.activity() and panel.account.activity() return iterators that fetch the next page as you go. For one page at a time, with the list's meta, use the *_page methods:

page = panel.servers.list_page(page=1, per_page=25)
print(page.total, page.has_next, page.meta.get("pending_orders"))

Async

import asyncio
from sillydev import AsyncSillyDev

async def main():
    async with AsyncSillyDev() as client:
        async for server in client.panel.servers.list():
            print(server["name"])
        await client.panel.servers.restart("1a7ce997")

asyncio.run(main())

Errors

Every error is a sillydev.SillyDevError. Errors the API answers with have their own class:

Status Exception
400 BadRequestError
401 AuthenticationError
403 PermissionDeniedError
404 NotFoundError
409 ConflictError
422 ValidationError (.errors has every problem, .fields groups them by field)
429 RateLimitError (.retry_after in seconds)
5xx ServerError

If the API cannot be reached at all you get APIConnectionError.

from sillydev import ConflictError, NotFoundError

try:
    panel.servers.restart(server)
except ConflictError:
    print("The server is installing or being transferred; try again later")
except NotFoundError:
    print("No such server, or the key cannot reach it")

Retries and limits

Each account may make 768 requests a minute. Requests answered 429 are retried twice by default, and reads answered 502, 503 or 504 too (a command or power action is not repeated, since the server may already have run it), waiting as long as the Retry-After header asks. Change it with SillyDev(max_retries=...); 0 turns retries off.

Ordering a paid server (panel.billing.checkout(...)) always sends an Idempotency-Key, so a retried request never buys twice. Pass idempotency_key= yourself to make retries safe across runs.

Everything else

client.panel has one attribute for each area of the API:

Attribute What it covers
servers list, get, delete, resources, activity, permissions, power, command, share logs, websocket
settings rename, reinstall, Docker image, status badge
startup startup command and variables
files list, read, write, rename, copy, compress, decompress, delete, folders, chmod, pull, signed URLs
backups list, create, get, delete, download, lock, restore
schedules schedules and their tasks
network allocations (ports)
subusers other accounts with access to a server
git link a repository, deploy, deployments, sillydev.conf
account the key's account and its activity
server_creation create free servers
databases free MariaDB and Postgres databases
billing paid servers and subscriptions

Every method's docstring names the API operation it calls, so you can look it up in the API reference.

Command line

export SILLYDEV_API_KEY="sdevc_..."

sillydev servers list
sillydev status 1a7ce997
sillydev power 1a7ce997 restart
sillydev command 1a7ce997 "say hi"
sillydev deploy 1a7ce997
sillydev files ls 1a7ce997 /src
sillydev files cat 1a7ce997 /config.json
sillydev backups list 1a7ce997
sillydev backups create 1a7ce997 --name before-update

Add --json to any command for JSON output. python -m sillydev works too.

MCP server

The MCP server lets an AI assistant (Claude Desktop, Claude Code, Cursor and others) check on and control your servers. It needs Python 3.10 or later:

pip install 'sillydev[mcp]'

Then add it to your assistant's MCP settings, for example:

{
  "mcpServers": {
    "sillydev": {
      "command": "sillydev-mcp",
      "env": { "SILLYDEV_API_KEY": "sdevc_..." }
    }
  }
}

Its tools are: list servers, server status, power action, send command, list files, read file, Git deploy and list backups. There is nothing for billing or for deleting anything. Give it a key limited to the servers and permissions you want the assistant to have.

Configuration

Option Environment variable Default
api_key SILLYDEV_API_KEY (required)
base_url SILLYDEV_BASE_URL https://sillydev.co.uk/panel/api/client
timeout 60 seconds
max_retries 2

License

MIT

Metadata

Release files for sillydev 1.0.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 sillydev 1.0.0
File Size Uploaded Provenance
sillydev-1.0.0.tar.gz 29.9 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for sillydev 1.0.0
File Interpreter ABI Platform
sillydev-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 64.8 kB

Release files / sillydev-1.0.0.tar.gz

Download URL sillydev-1.0.0.tar.gz
Size 29.9 kB
Tags Source
SHA-256 checksum
How to use checksums
831d36e652e93c5f6589a83f7c0a977282b433f00d64fbd18d12c5b04c52004d
BLAKE2b-256 checksum
How to use checksums
8e5e6fd8150e0182be0178c4825ccf31ac55d553abeb85cea0f5c6490b8e012f
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 13, 2026.

Transparency log

Release files / sillydev-1.0.0-py3-none-any.whl

Download URL sillydev-1.0.0-py3-none-any.whl
Size 34.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f77efa41575a3481458115c445498c189277abdbd389eb318b6783b90da32092
BLAKE2b-256 checksum
How to use checksums
80ade3d46263e3ad071d32875f310e880d82dd6e0ec0c72faa902380279c8d31
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 13, 2026.

Transparency log

Security for sillydev 1.0.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.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for sillydev-1.0.0.tar.gz

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 13, 2026.

Transparency log

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.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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