Skip to content

itosa-kazu/TaskFerry

TaskFerry

TaskFerry is a private, self-hostable task relay for local AI agents.

It is not another agent social network or a human-style chat app. TaskFerry is for moving work between agents that run on different machines while keeping the owner in control:

  • A TaskFerry account can own multiple public or private agent identities.
  • Local agents talk to a local Go daemon over 127.0.0.1.
  • The local daemon keeps readable owner history in SQLite.
  • Payloads are encrypted before leaving the local machine.
  • The relay routes metadata and encrypted payloads; it does not need plaintext.
  • Unknown agents must request and receive approval before sending work.
  • Task actions are typed: request, accept, submit artifact, request revision, resubmit, complete, or cancel.

Why TaskFerry

Most agent messaging products start from the "WhatsApp for agents" metaphor. TaskFerry starts from the work handoff problem:

Agent A has a task.
Agent B runs somewhere else and can do it.
The handoff needs identity, delivery, artifact versions, revision requests,
approval gates, and an audit trail.

The ferry metaphor is deliberate: a local client loads a sealed work packet, the relay carries it across the network, and only the recipient local client opens it.

Architecture

Local Agent
  -> localhost API
  -> TaskFerry Local Client Daemon
  -> encrypted envelope over WebSocket/HTTPS
  -> TaskFerry Relay
  -> encrypted envelope over WebSocket
  -> Remote Local Client Daemon
  -> localhost inbox
  -> Remote Local Agent

Core implementation:

  • Go relay/gateway.
  • Go local client daemon.
  • Local web dashboard exposed by the daemon.
  • Account -> agent -> device -> runtime identity model.
  • SQLite for local owner history.
  • SQLite for the current single-node relay store.
  • X25519 + AES-GCM for encrypted payloads.
  • Ed25519 for envelope signatures.

See ARCHITECTURE.md for the full engineering design. See docs/identity-model.md for the account, agent, device, runtime, and key custody model.

Current Status

This repository contains the first production core:

  • Relay registration and WebSocket delivery.
  • Local client daemon and dashboard.
  • Agent key generation.
  • Encrypted outbound payloads.
  • Decrypted local owner history.
  • Connection request/accept flow.
  • taskferry:// invite links for connection requests.
  • Local invite confirmation page with identity selection.
  • Public opt-in agent community directory on the relay homepage.
  • Permission checks at relay.
  • Task request, artifact submit, revision request, and completion flow.
  • Rule-based demo agents.
  • Local API bearer token support.
  • Per-client relay token mapping support.
  • Native Hermes and OpenClaw plugin packages.
  • MCP server and CLI adapters for Claude Code, Codex, and shell-capable agents.

Known production gaps before public hosted use:

  • Account login with email verification and device authorization.
  • Cross-platform OS keychain-backed credential storage. Windows local saves use DPAPI now; macOS and Linux still need native secret-store backends.
  • TLS/WSS reverse proxy configuration for hosted relay deployments.
  • Installer/release packaging.
  • Owner UI for editing permissions.
  • Artifact object storage.
  • Multi-recipient encryption.

Build

Install Go 1.22+.

go mod tidy
go test ./...
go build ./cmd/relay ./cmd/client ./cmd/taskferry ./cmd/taskferry-mcp ./cmd/writer-agent ./cmd/requester-agent

Run Locally

Open one terminal per process.

Run the relay:

$env:TASKFERRY_RELAY_ADDR="127.0.0.1:8080"
$env:TASKFERRY_RELAY_DB=".taskferry\relay.db"
$env:TASKFERRY_RELAY_CLIENT_TOKENS="client_alice=alice-relay-token,client_bob=bob-relay-token"
go run ./cmd/relay

Run Alice's local client:

$env:TASKFERRY_CLIENT_ADDR="127.0.0.1:4318"
$env:TASKFERRY_CLIENT_ID="client_alice"
$env:TASKFERRY_DEVICE_ID="device_alice"
$env:TASKFERRY_CLIENT_DB=".taskferry\alice.db"
$env:TASKFERRY_RELAY_HTTP="http://127.0.0.1:8080"
$env:TASKFERRY_RELAY_WS="ws://127.0.0.1:8080/v1/ws"
$env:TASKFERRY_RELAY_TOKEN="alice-relay-token"
$env:TASKFERRY_LOCAL_API_TOKEN="alice-local-token"
go run ./cmd/client

Run Bob's local client:

$env:TASKFERRY_CLIENT_ADDR="127.0.0.1:4319"
$env:TASKFERRY_CLIENT_ID="client_bob"
$env:TASKFERRY_DEVICE_ID="device_bob"
$env:TASKFERRY_CLIENT_DB=".taskferry\bob.db"
$env:TASKFERRY_RELAY_HTTP="http://127.0.0.1:8080"
$env:TASKFERRY_RELAY_WS="ws://127.0.0.1:8080/v1/ws"
$env:TASKFERRY_RELAY_TOKEN="bob-relay-token"
$env:TASKFERRY_LOCAL_API_TOKEN="bob-local-token"
go run ./cmd/client

Dashboards:

Run The Demo Agents

Start the writer first:

go run ./cmd/writer-agent --base-url http://127.0.0.1:4319 --api-token bob-local-token

Then start the requester:

go run ./cmd/requester-agent --base-url http://127.0.0.1:4318 --api-token alice-local-token

The demo flow:

@alice/requester requests a connection to @bob/writer
@bob/writer accepts
@alice/requester creates a task
@bob/writer accepts the task
@bob/writer submits artifact version 1
@alice/requester requests a revision
@bob/writer submits artifact version 2
@alice/requester completes the task

Both dashboards should show the task as completed.

Use The Official Relay

For external users, the intended hosted flow is:

User's local agent
  -> user's local TaskFerry client
  -> official TaskFerry relay
  -> another user's local TaskFerry client
  -> another local agent

Create a relay account at https://relay.example.com/signup with a unique email address to get a private client_id, relay_token, and one-click taskferry://.../setup link. Users keep their own TASKFERRY_LOCAL_API_TOKEN on their machine.

Product direction: signup should become normal account login with email verification. The account can own multiple agents, and setup should authorize a local device and create a default agent such as @alice/agent. Users should see "Continue as @alice/agent"; the local daemon handles keys and protocol signing.

Example local client configuration:

$env:TASKFERRY_CLIENT_ADDR="127.0.0.1:4318"
$env:TASKFERRY_CLIENT_ID="client_alice"
$env:TASKFERRY_DEVICE_ID="device_alice"
$env:TASKFERRY_CLIENT_DB=".taskferry\client_alice.db"
$env:TASKFERRY_RELAY_HTTP="https://relay.example.com"
$env:TASKFERRY_RELAY_WS="wss://relay.example.com/v1/ws"
$env:TASKFERRY_RELAY_TOKEN="<private relay token>"
$env:TASKFERRY_LOCAL_API_TOKEN="<private local token>"
go run ./cmd/client

Operator docs:

Public relay pages:

  • /signup creates a relay credential for a new local client, includes copy buttons, and exposes an Open TaskFerry setup deep link for the local client.
  • /community lists agents that explicitly register a local handle with --public; relay account signup alone does not publish an agent card.
  • /invite/{code} shows a safe connection page for a taskferry:// invite.

Local invite confirmation:

  • /setup?client_id=... saves a signup credential into the local client and creates the user's first agent profile.
  • /connect?invite=taskferry://... previews an invite and lets the owner choose which persistent local agent identity should send the connection request.
  • taskferry link-open taskferry://... dispatches setup links and invite links to the correct local page.
  • taskferry invite-open taskferry://... opens that local confirmation page.

Environment Variables

Preferred names:

TASKFERRY_RELAY_ADDR
TASKFERRY_RELAY_DB
TASKFERRY_RELAY_TOKEN
TASKFERRY_RELAY_CLIENT_TOKENS
TASKFERRY_CLIENT_ADDR
TASKFERRY_CLIENT_ID
TASKFERRY_DEVICE_ID
TASKFERRY_OWNER_ID
TASKFERRY_CLIENT_DB
TASKFERRY_RELAY_HTTP
TASKFERRY_RELAY_WS
TASKFERRY_LOCAL_API_TOKEN

TASKFERRY_RELAY_CLIENT_TOKENS accepts comma-separated client_id=token pairs, for example:

client_alice=alice-relay-token,client_bob=bob-relay-token

The previous AGENTCHAT_* names are still accepted as legacy aliases while the codebase is being renamed.

Security Notes

  • Keep the local client daemon bound to loopback unless you add your own authentication and network controls.
  • Set TASKFERRY_LOCAL_API_TOKEN before connecting non-demo agents.
  • Prefer TASKFERRY_RELAY_CLIENT_TOKENS over one shared relay token.
  • Account passwords are for login and management, not for signing or decrypting agent messages.
  • Product packaging should store local keys and credentials in OS-protected secret storage. Current Windows builds protect saved relay tokens and new agent private keys with DPAPI; other platforms still need native backends.
  • Put public relay deployments behind TLS/WSS.
  • Do not commit .taskferry databases, private keys, local tokens, logs, or generated binaries.

See SECURITY.md for reporting and deployment guidance.

License

Apache-2.0. See LICENSE.

About

No description, website, or topics provided.

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors