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:
-
Authentication -- The agent sends an auth token during the WebSocket handshake. The server validates the token and can reject the connection.
-
Capability approval -- The server approves or denies each capability during the handshake. Only approved capabilities accept commands.
-
Path restrictions -- The
fscapability restricts file access toallowed_pathsand blocks sensitive directories (~/.ssh,~/.gnupg, etc.) by default. -
Command blocking -- The
shellcapability blocks dangerous command patterns (e.g.,rm -rf /,mkfs,dd if=/dev). -
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
Metadata
Release files for tinker-host-agent 0.3.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 | |
|---|---|---|---|
| tinker_host_agent-0.3.0.tar.gz | 58.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| tinker_host_agent-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 95.8 kB
Release files / tinker_host_agent-0.3.0.tar.gz
| Download URL | tinker_host_agent-0.3.0.tar.gz |
|---|---|
| Size | 58.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
0310745a128a084917c9f0fe1205ce9935101b312275e182676d019672ed41c2
|
|
BLAKE2b-256 checksum How to use checksums |
b0cf9ea2d1ab58dee06bcf0606c41f7a1d37defedcffb81f87bc85d8d160f329
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is 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}
|
Release files / tinker_host_agent-0.3.0-py3-none-any.whl
| Download URL | tinker_host_agent-0.3.0-py3-none-any.whl |
|---|---|
| Size | 37.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
8b121e508e9094def01c760a4aca298cd37d80c0977f480217ac25fb904c5a56
|
|
BLAKE2b-256 checksum How to use checksums |
8649e3701fc96272f77295ae687edbc9a318822fe08ccadacec96bc2ca4c1635
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is 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}
|