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.2.0.tar.gz (45.8 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.2.0-py3-none-any.whl (25.3 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: tinker_host_agent-0.2.0.tar.gz
  • Upload date:
  • Size: 45.8 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.2.0.tar.gz
Algorithm Hash digest
SHA256 405fb844cb523fed3fa7295da8728cc1e5c721f59adeddefcbb36868810bbc2d
MD5 0abd2161e72a527d35f9114a23789cc1
BLAKE2b-256 d3881def1dd610a06cf5a283a2106cca796e6f1a53ab2c502812c06f1a2042d3

See more details on using hashes here.

File details

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

File metadata

  • Download URL: tinker_host_agent-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 25.3 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.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1942496abdbda12ef3b588bae77311256fd0f8b8bf3b3e9811e5c6fc170e6b06
MD5 8d70522b4d93c438eaf8ab175f7ad635
BLAKE2b-256 e370efa667a0e33ded0862a98342a3f8c210f0c895500730829c7ff0f55c0cc3

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