Skip to main content

shebangrun Python Client

Python client library and CLI tool for shebang.run - a platform for hosting and sharing shell scripts with versioning, encryption, and signing.

Installation

pip install shebangrun

This installs both the Python library and the shebang CLI tool.

CLI Tool

Quick Start

# Login and generate API credentials
shebang login

# List your scripts
shebang list

# Get a script
shebang get myscript

# Run a script
shebang run myscript

Commands

Commands are organized into subsystemsscripts, secrets, keys, files, and folders — e.g. shebang secrets get NAME, shebang keys list. Because scripts are the primary noun, the common script verbs are also available as bare top-level aliases: shebang get, shebang run, shebang list, shebang put, shebang search, shebang share, and shebang access all map to their shebang scripts … equivalents.

Login

shebang login

Interactive wizard that:

  • Prompts for server URL, username, password
  • Generates API credentials (Client ID/Secret)
  • Saves to ~/.shebangrc

Rotate credentials (no password prompt — uses the existing ~/.shebangrc):

# Generate new credentials, save them, and revoke the old ones
shebang login --rotate

# Rotate but keep the old credentials active
shebang login --rotate --skip-invalidate

List Scripts

# Your scripts
shebang list

# Include community scripts
shebang list -c

Search Scripts

# Search your scripts
shebang search "deploy"

# Search community
shebang search -c "backup"

Get Script

# Download to stdout
shebang get myscript

# From another user
shebang get -u username scriptname

# Save to file
shebang get -O deploy.sh myscript

# Decrypt with private key
shebang get -k private.pem encrypted-script

Run Script

# Run with confirmation
shebang run myscript

# Auto-accept (no prompt)
shebang run -a myscript

# Pass arguments
shebang run myscript arg1 arg2

# Run and delete
shebang run -d myscript

Key Management

# List keys
shebang keys list

# Create new keypair
shebang keys create
shebang keys create -O mykey.pem

# Delete key
shebang keys delete keyname

File Management

# List files (root)
shebang files list

# List files in folder (by path)
shebang files list /my-folder

# Upload file
shebang files upload document.pdf
shebang files upload file.txt /my-folder
shebang files upload file.txt /my-folder -v unlisted

# Download file
shebang files download 123
shebang files download 123 -o output.pdf

# Delete file
shebang files delete 123

# List versions (Ultimate tier)
shebang files versions 123

# Share file
shebang files share 123 -u alice
shebang files share 123 -l  # Enable link sharing

Folder Management

# List folders
shebang folders list
shebang folders list /parent-folder

# Create folder
shebang folders create my-folder
shebang folders create subfolder /parent-folder

# Show folder tree
shebang folders tree
shebang folders tree /my-folder
shebang folders tree "/Shared With Me/alice/shared-folder"

# Delete folder
shebang folders delete /my-folder

# Share folder (shares all contents)
shebang folders share /my-folder -u bob
shebang folders share /my-folder -l

#### Upload Script
```bash
# Upload from file
shebang put -n myscript -v public -f script.sh

# Upload from stdin
cat script.sh | shebang put -n myscript -v public -s

# Upload private script with encryption
shebang put -n private-script -v priv -k my-key -f script.sh -d "My private script"

Secrets Management

# List secrets
shebang secrets list

# Load a secret into your shell as $AWS_KEY
# (default, with no flags, is an eval-able `export` statement)
eval "$(shebang secrets get AWS_KEY)"

# --stdout prints the RAW value (for $(...) substitution in bash)
TOKEN=$(shebang secrets get AWS_KEY --stdout)
curl -H "Authorization: Bearer $(shebang secrets get AWS_KEY --stdout)" ...

# The raw value is blocked from an interactive terminal unless --stdout is given
shebang secrets get AWS_KEY --stdout

# Other formats
shebang secrets get AWS_KEY -f env --stdout    # AWS_KEY="value"
shebang secrets get AWS_KEY -f json --stdout   # {"AWS_KEY": "value"}

# Write the raw value to a file
shebang secrets get AWS_KEY -O token.txt

# Create/update secret
shebang secrets set AWS_KEY -v "AKIA..."
echo "secret-value" | shebang secrets set API_KEY -s

# Delete secret
shebang secrets delete AWS_KEY

#### `shebang secrets check` — verify names before runtime

A wrong secret name is invisible until the moment a script runs, and identical
across every caller that copied it. `check` answers the question first, without
reading any values.

```bash
shebang secrets check LLM_ASGARD_CLIENT_KEY GIT_TWILLCODE_PAT
shebang secrets check -f deploy.sh          # extract ${SECRET:NAME} refs and verify them
shebang secrets check -f a.sh -f b.sh       # repeatable

Exit codes follow the same contract as the other secrets verbs: 0 only when every name is confirmed present, 1 if any name is missing or uncheckable.

Three outcomes, and the third is the point:

Result Meaning
ok the name exists and this credential can see it
MISSING the name does not exist (only reported by a full-access credential)
UNKNOWN this credential is scoped and cannot see the name — it may still exist

A scoped credential can never prove a name is absent, so it reports UNKNOWN rather than MISSING. Collapsing those two would tell someone their correct secret name is wrong, which is worse than not checking at all. Both are non-zero exits: an unverifiable name is not a pass.

A file containing no ${SECRET:...} references warns rather than passing silently — an under-matching check produces output identical to a clean one.

View audit log

shebang secrets audit AWS_KEY

Rename a secret (its base name) and/or move it between collections

shebang secrets rename AWS_KEY AWS_ACCESS_KEY shebang secrets move AWS_ACCESS_KEY AWS # -> addressed AWS_AWS_ACCESS_KEY


#### Secret Collections (groups)

Group related secrets. A secret `API` in collection `GITHUB` is addressed
`GITHUB_API` (the collection name is a prefix). An ungrouped secret (collection
"None") keeps its bare name.

```bash
# Create a secret directly in a collection
shebang secrets set API -v "ghp_..." -c GITHUB     # -> addressed GITHUB_API
eval "$(shebang secrets get GITHUB_API)"           # loads $GITHUB_API

# Manage collections
shebang secrets collection list
shebang secrets collection create GITHUB
shebang secrets collection rename GITHUB GH        # rewrites member addresses
shebang secrets collection delete GH               # its secrets move to None

Scoped API Tokens

A token can be limited to specific resources (or a whole collection) instead of full account access. shebang login --rotate preserves the existing scope.

# Full-access token (default)
shebang login

# Token limited to one secret + an entire collection
shebang login --scope "secret:DEPLOY_KEY,collection:GITHUB"

# Limit to a script or key
shebang login --scope "script:deploy,key:signing-key"

# Rotate, preserving whatever scope the current token has
shebang login --rotate

A scoped token can read/use (and rename) the resources it's granted; a collection grant covers every secret in that collection. Creating brand-new top-level resources requires a full-access token.

Variable Substitution

Scripts support automatic variable substitution:

Secrets:

# In your script:
API_KEY=${SECRET:AWS_API_KEY}
curl -H "Authorization: $API_KEY" https://api.example.com

# Run with substitution (automatic):
shebang run myscript

Files:

# In your script:
CONFIG=${FILE:"/configs/app.conf"}
DATA=${FILE:"/data/input.csv"}

echo "Using config: $CONFIG"
python process.py "$DATA"

# Run with substitution (automatic):
shebang run myscript
# Downloads files to temp locations, replaces with paths
# Cleans up temp files after execution

# Also works with shared files:
SHARED=${FILE:"/Shared With Me/alice/data/report.pdf"}

Script Sharing

# List who has access
shebang access myscript

# Share with specific users
shebang share myscript -u alice -u bob

# Enable "anyone with link" sharing
shebang share myscript -l

# Remove user access
shebang share myscript -u alice -r

# Remove link sharing
shebang share myscript -l -r

# List scripts (includes shared by default)
shebang list

# Hide shared scripts
shebang list -i

Secret Substitution

# Get script with secrets substituted
shebang get myscript -s

# Run script (secrets always substituted)
shebang run myscript

MCP Server

shebang can run as an MCP stdio server, exposing the data plane (scripts, secrets, keys, files, folders) as agent-callable tools. Tool names mirror the CLI subsystems (scripts_list, secrets_get, …). Script execution is intentionally not exposed — an agent can read script content but cannot fetch-and-run code on the host.

# Install with the optional MCP extra (needs Python >= 3.10)
pip install 'shebangrun[mcp]'

# Run the server (reads credentials from ~/.shebangrc)
shebang --mcp

Configure it in your MCP client. Tool names mirror the CLI subsystems (scripts_list, secrets_get, keys_list, files_list, folders_list, …).

Claude Code (CLI):

claude mcp add shebang -- shebang --mcp

Claude Desktop — add to claude_desktop_config.json:

{
  "mcpServers": {
    "shebang": { "command": "shebang", "args": ["--mcp"] }
  }
}

OpenAI Codex CLI — add to ~/.codex/config.toml (or codex mcp add shebang -- shebang --mcp):

[mcp_servers.shebang]
command = "shebang"
args = ["--mcp"]

opencode — add to opencode.json (project) or ~/.config/opencode/opencode.json:

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "shebang": {
      "type": "local",
      "command": ["shebang", "--mcp"],
      "enabled": true
    }
  }
}

PATH note: MCP clients usually don't inherit your shell's PATH. If shebang isn't found, use its absolute path (e.g. ~/.local/bin/shebang or the path printed by which shebang) as the command.

CLI Options

Visibility:

  • priv - Private (encrypted, requires key)
  • unlist - Unlisted (accessible via URL only, supports ACL sharing)
  • public - Public (listed in community)

Configuration: Stored in ~/.shebangrc:

SHEBANG_URL="https://shebang.run"
SHEBANG_USERNAME="myuser"
SHEBANG_CLIENT_ID="..."
SHEBANG_CLIENT_SECRET="..."
SHEBANG_KEY_PATH="/path/to/key.pem"

Python Library

Google Colab Usage

import shebangrun as shebang
from google.colab import userdata

# Initialize from Colab secrets
shebangrc = userdata.get('shebangrc')
key = userdata.get('colabpem')
shebang.init(shebangrc)

# Run script with variables
results = shebang.run(
    script="pythontest",
    key=key,
    eval=True,
    accept=True,
    vars={"C": 5}
)

# Access variables from script
print(results['A'])  # Variables defined in script

Simple Script Fetching

from shebangrun import run

# Fetch a script (returns content as string)
content = run(username="mpruitt", script="bashtest")
print(content)

Execute Python Scripts

from shebangrun import run

# Fetch and execute with confirmation prompt
run(username="mpruitt", script="myscript", eval=True)

# Execute without confirmation (use with caution!)
run(username="mpruitt", script="myscript", eval=True, accept=True)

Working with Versions

from shebangrun import run

# Get latest version
content = run(username="mpruitt", script="deploy", version="latest")

# Get specific version
content = run(username="mpruitt", script="deploy", version="v5")

# Get tagged version
content = run(username="mpruitt", script="deploy", version="dev")

Private Scripts

from shebangrun import run

# Access private script with share token
content = run(
    username="mpruitt", 
    script="private-script",
    token="your-share-token-here"
)

Full API Client

For more advanced usage, use the ShebangClient class:

from shebangrun import ShebangClient

# Initialize client
client = ShebangClient(url="shebang.run")

# Login
client.login(username="myuser", password="mypassword")

# Create a script
client.create_script(
    name="hello",
    content="#!/bin/bash\necho 'Hello World'",
    description="My first script",
    visibility="public"
)

# File Management
# Upload file
file = client.upload_file('document.pdf', folder_id=5, visibility='private')
print(f"Uploaded: {file['id']}")

# List files
files = client.list_files(folder_id=5)
for f in files:
    print(f"{f['original_filename']} - {f['size']} bytes")

# Download file
client.download_file(file_id=123, output_path='downloaded.pdf')

# File versioning (Ultimate tier)
versions = client.list_file_versions(file_id=123)
client.restore_file_version(file_id=123, version=2)

# Share file
client.share_file(file_id=123, usernames=['alice', 'bob'])
client.share_file(file_id=123, link=True)  # Anyone with link

# Folder Management
# Create folder
folder = client.create_folder('my-folder', parent_id=None)

# List folders
folders = client.list_folders(parent_id=None)

# Get folder contents
contents = client.get_folder_contents(folder_id=5)
print(f"Folders: {len(contents['folders'])}")
print(f"Files: {len(contents['files'])}")

# Share folder (shares all contents recursively)
client.share_folder(folder_id=5, usernames=['alice'])

# List shared items
shared_files = client.list_shared_files()
shared_folders = client.list_shared_folders()
shared_all = client.get_shared_with_me()  # Grouped by owner

# Storage usage
storage = client.get_file_storage()
print(f"Used: {storage['used']} / {storage['limit']} bytes")

    description="My first script",
    visibility="public"
)

# List your scripts
scripts = client.list_scripts()
for script in scripts:
    print(f"{script['name']} - v{script['version']}")

# Update a script (creates new version)
client.update_script(
    script_id=1,
    content="#!/bin/bash\necho 'Hello World v2'",
    tag="dev"
)

# Generate share token for private script
token = client.generate_share_token(script_id=1)
print(f"Share URL: https://shebang.run/myuser/myscript?token={token}")

# Get script metadata
meta = client.get_metadata(username="mpruitt", script="bashtest")

# Secrets management
client.create_secret("AWS_KEY", "AKIA...")
secrets = client.list_secrets()
value = client.get_secret("AWS_KEY")
audit = client.get_secret_audit("AWS_KEY")
client.delete_secret("AWS_KEY")

# Script sharing
client.add_script_access(script_id=1, usernames=["alice", "bob"])
access_list = client.list_script_access(script_id=1)
client.remove_script_access(script_id=1, access_id=5)
shared = client.list_shared_scripts()

print(f"Version: {meta['version']}, Size: {meta['size']} bytes")

# Verify signature
verification = client.verify_signature(username="mpruitt", script="bashtest")
print(f"Signed: {verification['signed']}")

Key Management

from shebangrun import ShebangClient

client = ShebangClient(url="shebang.run")
client.login(username="myuser", password="mypassword")

# Generate a new keypair
key = client.generate_key(name="my-signing-key")
print(f"Public Key: {key['public_key']}")
print(f"Private Key: {key['private_key']}")  # Save this securely!

# List keys
keys = client.list_keys()
for key in keys:
    print(f"{key['name']} - Created: {key['created_at']}")

# Import existing public key
client.import_key(
    name="imported-key",
    public_key="-----BEGIN PUBLIC KEY-----\n..."
)

# Delete a key
client.delete_key(key_id=1)

Account Management

from shebangrun import ShebangClient

client = ShebangClient(url="shebang.run")
client.login(username="myuser", password="mypassword")

# Change password
client.change_password(
    current_password="oldpass",
    new_password="newpass"
)

# Export all data (GDPR)
data = client.export_data()
print(f"Exported {len(data['scripts'])} scripts")

# Delete account (permanent!)
client.delete_account()

API Reference

run() Function

run(username, script, key=None, eval=False, accept=False, 
    url="shebang.run", version=None, token=None)

Parameters:

  • username (str, required): Script owner's username
  • script (str, required): Script name
  • key (str, optional): Private key for decryption (not yet implemented)
  • eval (bool, optional): Execute the script in Python (default: False)
  • accept (bool, optional): Skip confirmation when eval=True (default: False)
  • url (str, optional): Base URL (default: "shebang.run")
  • version (str, optional): Version tag (e.g., "latest", "v1", "dev")
  • token (str, optional): Share token for private scripts

Returns:

  • String content if eval=False
  • Execution result if eval=True

ShebangClient Class

Authentication

  • register(username, email, password) - Register new user
  • login(username, password) - Login and get JWT token

Script Management

  • list_scripts() - List user's scripts
  • get_script(username, script, version=None, token=None) - Fetch script content
  • get_metadata(username, script) - Get script metadata
  • verify_signature(username, script) - Verify script signature
  • create_script(name, content, description="", visibility="private", keypair_id=None) - Create script
  • update_script(script_id, content=None, description=None, visibility=None, tag=None, keypair_id=None) - Update script
  • delete_script(script_id) - Delete script
  • generate_share_token(script_id) - Generate share token
  • revoke_share_token(script_id, token) - Revoke share token

Key Management

  • list_keys() - List keypairs
  • generate_key(name) - Generate new keypair
  • import_key(name, public_key) - Import public key
  • delete_key(key_id) - Delete keypair

Account Management

  • change_password(current_password, new_password) - Change password
  • export_data() - Export all data (GDPR)
  • delete_account() - Delete account

Security Notes

⚠️ Warning: Using eval=True with accept=True will execute remote code without confirmation. Only use this with scripts you trust completely.

Best Practices:

  • Always review scripts before executing with eval=True
  • Use accept=False (default) to see the script before execution
  • Store private keys securely, never commit them to version control
  • Use environment variables for tokens and credentials
  • Verify script signatures when available

Examples

Automation Script

#!/usr/bin/env python3
from shebangrun import run

# Fetch deployment script and execute with confirmation
run(
    username="devops",
    script="deploy-prod",
    version="latest",
    eval=True,
    accept=False  # Always confirm production deployments!
)

CI/CD Integration

import os
from shebangrun import ShebangClient

client = ShebangClient()
client.login(
    username=os.environ["SHEBANG_USER"],
    password=os.environ["SHEBANG_PASS"]
)

# Update deployment script
client.update_script(
    script_id=int(os.environ["DEPLOY_SCRIPT_ID"]),
    content=open("deploy.sh").read(),
    tag="latest"
)

print("Deployment script updated!")

License

MIT

Links

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

shebangrun-1.2.0.tar.gz (38.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

shebangrun-1.2.0-py3-none-any.whl (32.9 kB view details)

Uploaded Python 3

File details

Details for the file shebangrun-1.2.0.tar.gz.

File metadata

  • Download URL: shebangrun-1.2.0.tar.gz
  • Upload date:
  • Size: 38.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.14.4

File hashes

Hashes for shebangrun-1.2.0.tar.gz
Algorithm Hash digest
SHA256 551522c60408115a8096174a2df4c8cfdcb5036d0255acfc1d852f28691bd7eb
MD5 28b0363a64925484b67975dae78a1cdf
BLAKE2b-256 e4dd59c50f85e80275f18a73ae7af53c8e9d02969fb0a43980025e5b900e1ca7

See more details on using hashes here.

File details

Details for the file shebangrun-1.2.0-py3-none-any.whl.

File metadata

  • Download URL: shebangrun-1.2.0-py3-none-any.whl
  • Upload date:
  • Size: 32.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.14.4

File hashes

Hashes for shebangrun-1.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9d8d6efec2e903b647a43c757f42ce921b05e40399eb055eb32ab7acdd4964d8
MD5 44426d9588565cfdfa8a93bfbf55c6ed
BLAKE2b-256 365d89d0203ef256886406e8e893f62d2704ae346668c3fa1e528f26ba219667

See more details on using hashes here.

Release history Release notifications | RSS feed

1.10.9

2 files

1.10.8

2 files

1.10.7

2 files

1.10.6

2 files

1.10.5

2 files

1.10.4

2 files

1.10.3

2 files

1.10.2

2 files

1.10.1

2 files

1.10.0

2 files

1.9.1

2 files

1.9.0

2 files

1.8.0

2 files

1.7.0

2 files

1.6.0

2 files

1.5.0

2 files

1.4.1

2 files

1.4.0

2 files

1.3.0

2 files

1.2.1

2 files

This release

1.2.0 This release

2 files

1.1.1

2 files

1.1.0

2 files

1.0.1

2 files

0.8.1

2 files

0.8.0

2 files

0.7.3

2 files

0.7.1

2 files

0.7.0

2 files

0.6.6

2 files

0.6.5

2 files

0.6.4

2 files

0.6.3

2 files

0.6.2

2 files

0.6.1

2 files

0.6.0

2 files

0.5.7

2 files

0.5.6

2 files

0.5.5

2 files

0.5.4

2 files

0.5.3

2 files

0.5.2

2 files

0.5.1

2 files

0.5.0

2 files

0.4.0

2 files

0.3.1

2 files

0.3.0

2 files

0.2.3

2 files

0.2.2

2 files

0.2.1

2 files

0.2.0

2 files

0.1.0

2 files

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