Skip to main content

Tinker Host Agent — connects host machines to Tinker via Device Agent Protocol (DAP)

Project description

Tinker Host Agent

A lightweight Python agent that connects your host machine to a Tinker instance via WebSocket using the Device Agent Protocol (DAP). Once connected, Tinker can execute shell commands, manage files, take screenshots, control applications, and more on your machine.

Installation

pip install tinker-host-agent

Or with uv:

uv pip install tinker-host-agent

For GUI capabilities (screenshot, click, type), install with the gui extra:

pip install "tinker-host-agent[gui]"

Quick Start

Connect to a local Tinker instance:

tinker-host-agent

Connect to a remote Tinker server with authentication:

tinker-host-agent \
  --url wss://tinker.example.com/ws/device-agent \
  --token YOUR_AUTH_TOKEN

Or configure entirely via environment variables:

export TINKER_HOST_SERVER_URL=wss://tinker.example.com/ws/device-agent
export TINKER_HOST_AUTH_TOKEN=your-token
tinker-host-agent

Configuration

All settings can be configured via environment variables (prefixed with TINKER_HOST_) or a .env file in the working directory.

Connection

Variable Default Description
TINKER_HOST_SERVER_URL ws://localhost:3000/ws/device-agent WebSocket URL of the Tinker backend
TINKER_HOST_AUTH_TOKEN (empty) Authentication token for the server
TINKER_HOST_AGENT_ID (auto-generated) Unique agent identifier
TINKER_HOST_AGENT_NAME hostname (OS) Display name shown in Tinker UI
TINKER_HOST_AGENT_TYPE host Agent type: host or remote

Reconnection

Variable Default Description
TINKER_HOST_RECONNECT_DELAY 1.0 Initial reconnect delay (seconds)
TINKER_HOST_RECONNECT_MAX_DELAY 30.0 Maximum reconnect delay (exponential backoff cap)

Security

Variable Default Description
TINKER_HOST_ALLOWED_PATHS (empty = home dir) Comma-separated list of allowed filesystem paths
TINKER_HOST_BLOCKED_PATHS ~/.ssh,~/.gnupg,~/.aws,~/.config/gcloud Comma-separated list of blocked filesystem paths
TINKER_HOST_BLOCKED_COMMANDS rm -rf /,mkfs,dd if=/dev Comma-separated list of blocked shell command patterns

Capability Toggles

Variable Default Description
TINKER_HOST_ENABLE_SHELL true Enable shell command execution
TINKER_HOST_ENABLE_FS true Enable file system access
TINKER_HOST_ENABLE_GUI true Enable GUI automation (screenshot, click, type)
TINKER_HOST_ENABLE_APP true Enable application management
TINKER_HOST_ENABLE_CLIPBOARD true Enable clipboard access
TINKER_HOST_ENABLE_NETWORK true Enable network utilities

Plugins

Variable Default Description
TINKER_HOST_PLUGIN_DIR (empty) Directory to load custom plugins from

Available Capabilities

shell

Execute commands on the host machine.

  • exec -- Run a shell command and return stdout/stderr/exit_code
  • kill -- Send SIGTERM to a process by PID

fs

Read and write files within allowed paths.

  • read -- Read a file (max 10MB)
  • write -- Write content to a file
  • list -- List directory contents
  • search -- Recursive glob search

gui

GUI automation (requires platform tools: screencapture/cliclick on macOS, scrot/xdotool on Linux).

  • screenshot -- Capture the screen as base64 PNG
  • click -- Click at coordinates
  • type -- Type text
  • key -- Press a key or key combination (e.g., cmd+c)
  • scroll -- Scroll by delta
  • window_list -- List visible windows/applications

app

Application lifecycle management.

  • launch -- Open an application by name
  • list -- List running applications
  • info -- Get info about an application
  • quit -- Quit an application

clipboard

Host clipboard access.

  • get -- Read clipboard content
  • set -- Write to clipboard

network

Network utilities.

  • http -- Perform a simple HTTP GET request
  • ports -- List listening TCP/UDP ports
  • ping -- Ping a host (ICMP)

Plugin Development

Create custom capabilities by writing a plugin module. Place .py files in your TINKER_HOST_PLUGIN_DIR directory.

Each plugin must define a class that inherits from PluginBase:

from tinker_host.plugins import PluginBase


class MyPlugin(PluginBase):
    namespace = "my_tools"
    actions = ["hello"]
    description = "My custom tools"

    async def handle(self, action: str, params: dict) -> dict:
        match action:
            case "hello":
                name = params.get("name", "world")
                return {"message": f"Hello, {name}!"}
            case _:
                return {"error": f"Unknown action: {action}"}

The agent discovers plugins automatically on startup. Each plugin file should contain exactly one PluginBase subclass. The plugin's namespace becomes available as a capability that Tinker can invoke.

Security Model

The host agent enforces several layers of security:

  1. Authentication -- The agent sends an auth token during the WebSocket handshake. The server validates the token and can reject the connection.

  2. Capability approval -- The server approves or denies each capability during the handshake. Only approved capabilities accept commands.

  3. Path restrictions -- The fs capability restricts file access to allowed_paths and blocks sensitive directories (~/.ssh, ~/.gnupg, etc.) by default.

  4. Command blocking -- The shell capability blocks dangerous command patterns (e.g., rm -rf /, mkfs, dd if=/dev).

  5. Request scoping -- Each command is routed to a specific capability namespace and action. There is no generic "eval" endpoint.

These defaults are conservative. Adjust TINKER_HOST_ALLOWED_PATHS, TINKER_HOST_BLOCKED_PATHS, and TINKER_HOST_BLOCKED_COMMANDS to match your environment.

CLI Options

tinker-host-agent [OPTIONS]

Options:
  --url URL        Tinker server WebSocket URL
  --token TOKEN    Authentication token
  --name NAME      Agent display name
  --id ID          Agent ID (auto-generated if omitted)
  --mode {host,remote}  Agent type
  --no-gui         Disable GUI capability
  --no-shell       Disable shell capability
  -v, --verbose    Verbose (DEBUG) logging

License

MIT

Project details


Download files

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

Source Distribution

tinker_host_agent-0.1.1.tar.gz (15.0 kB view details)

Uploaded Source

Built Distribution

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

tinker_host_agent-0.1.1-py3-none-any.whl (20.1 kB view details)

Uploaded Python 3

File details

Details for the file tinker_host_agent-0.1.1.tar.gz.

File metadata

  • Download URL: tinker_host_agent-0.1.1.tar.gz
  • Upload date:
  • Size: 15.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.27 {"installer":{"name":"uv","version":"0.9.27","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for tinker_host_agent-0.1.1.tar.gz
Algorithm Hash digest
SHA256 157ebbd2fc8341b007632204b84a6bfa32943104010d6dafb903c3f566688c7f
MD5 d05bd073e65fdf93ed6b0ef6d94ac482
BLAKE2b-256 2087d5fde2741475f8cd56f3567aaa2a1abfbd0b7965ffe018c43f55d54d11cb

See more details on using hashes here.

File details

Details for the file tinker_host_agent-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: tinker_host_agent-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 20.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.27 {"installer":{"name":"uv","version":"0.9.27","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for tinker_host_agent-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 92249b6bb05dffe59b8be2b75ffc6618170dd6c662151613e91fcdd36b13c29e
MD5 367821769780c3a36359f9befef14494
BLAKE2b-256 ccd6ec6c049b8df81769259cc630e8f1b1d9f8e1b6aa09444887787fa35e1248

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page