Skip to main content
Glama

HireLine

An MCP and terminal workflow for agents to ask humans for help on Gibwork, with a separate approval vault.

An agent can implement a checkout fix but cannot test it on a physical iPhone. HireLine lets it propose a small bounty, wait for evidence, check submissions against explicit criteria, and request payment approval. The agent-side client receives a WalletSigner adapter, not a wallet secret.

Built for the Gibwork Developer Hackathon. This is a non-web-app prototype, using the real @gibwork/sdk@0.2.0 from a CLI and an MCP server. It is not a production-audited wallet.

Run the complete demo without an account or funds

Requires Node.js 22+ and npm (or pnpm). From this directory:

npm ci --ignore-scripts
npm test
node bin/hireline.js demo --yes
node bin/hireline.js demo --attack --yes

Alternative reproducible install: pnpm install --frozen-lockfile --ignore-scripts.

The happy path hires a fictional mobile tester, receives two fictional submissions, flags the suspicious one, requests a payout signature, and verifies the audit chain. The attack demo advertises a 5.125 USDC quote but includes an additional 500 USDC direct transfer; the vault refuses before approval.

What is real: Gibwork SDK calls, the WalletSigner interface, the HTTP vault, Ed25519 signatures, Solana versioned transaction bytes, and MCP stdio protocol. What is simulated: the Gibwork HTTP service, escrow program, network confirmation, workers, fees, and payouts. Nothing is broadcast on-chain. --yes is explicitly a non-human demo approval, not evidence of human authorization.

Run node bin/hireline.js demo in an interactive terminal to type approve yourself. In a noninteractive shell the demo uses a visibly labelled test approver. Use a separate vault with terminal approval for live operations.

Related MCP server: @grokchain/mcp

Architecture

Agent -> MCP or CLI -> Gibwork SDK -> prepared transaction
                              |
                        RemoteSigner (HTTP)
                              |
                  Vault process holding wallet key
                  decode -> policy -> owner -> sign
                              |
                    signed audit entry -> SDK submit

The vault checks direct SOL/token instructions it understands, token spending caps, supported instruction types and program allowlists. Unknown programs require first-use approval before pinning. Pinned program instructions remain opaque and require approval on every call. Caller-supplied action, title, quote and review are untrusted context, not proof of the transaction's effects. The approval card shows decoded transfers, program IDs and blockhash.

Funding and payout are different decisions: funding moves money into escrow; payout selects a worker. Both use prepare/sign/submit SDK methods. Submissions are data; deterministic checks offer a recommendation, never an independent guarantee of work quality. Pattern-based injection warnings are deliberately limited.

What improved in this revision

  • Audit verification is enforced before appending or computing spend; tampered history refuses further signatures. In-process truncation is detected.

  • System account creation and conservative priority-fee estimates count against the SOL cap. Unsupported system/token instructions fail closed.

  • Opaque program warnings prevent a caller from bypassing approval by labelling an escrow action differently.

  • Concurrent signer requests keep separate approval context using AsyncLocalStorage.

  • Auth messages require recognised operation/method/path combinations, unique fields, fresh timestamps and request hashes.

  • Vault HTTP is loopback-only, bearer-authenticated and rejects malformed payloads. Live CLI auto-approval is disabled.

  • Submission review traverses all reported pages, URL checks reject lookalike hosts, zero payout amounts and invalid polling parameters are rejected.

These are bounded prototype checks. See SECURITY.md for the trust boundary and remaining gaps.

Tests and actual evidence

npm test             # unit, HTTP, transaction attacks, end-to-end SDK, MCP stdio
npm run test:mcp     # exercises all eight MCP tools through a real child process
npm run check:live   # optional production READ ONLY request, no user wallet required

check:live generates an ephemeral wallet in a temporary directory, signs one public API authentication request through the vault, and fetches this hackathon's public listing. Transaction signing is disabled. Recorded live result confirms API reachability; it does not prove funded mainnet execution.

See verification results, actual happy-path output, blocked-attack output and the recording instructions in DEMO_SCRIPT.md.

Live configuration (owner supervised)

Do not use a wallet containing material funds. Review the security document first. No live funding/payout was performed while preparing this entry.

macOS / Linux

export HIRELINE_HOME="$PWD/.hireline-vault"
node bin/hireline.js init
# In the VAULT terminal only, using your own key file:
export HIRELINE_KEYPAIR_PATH=/absolute/path/to/dedicated-key.json
node bin/hireline.js vault --approver terminal

Windows PowerShell

$env:HIRELINE_HOME = Join-Path $PWD '.hireline-vault'
node bin/hireline.js init
# In the VAULT terminal only:
$env:HIRELINE_KEYPAIR_PATH = 'C:\absolute\path\dedicated-key.json'
node bin/hireline.js vault --approver terminal

In a second terminal, remove wallet secret variables. Supply HIRELINE_VAULT_URL, HIRELINE_VAULT_TOKEN and a different agent state directory via HIRELINE_HOME. Use your operating system's secret manager to pass the token; never commit it. The CLI default state directory contains both agent state and vault configuration for convenience; that default is not process isolation against a same-user agent.

Set GIBWORK_PRODUCTION=1 explicitly for production; stage is the default. The wallet may need to be registered on Gibwork and funded for money-moving operations. Live supported transaction shapes may be refused by the conservative decoder; do not disable policy to force them through.

node bin/hireline.js doctor
node bin/hireline.js discover --n 3
node bin/hireline.js hire --title "Test checkout on iPhone" --instructions "Use our test environment and report reproduction steps" --why "Physical device required" --budget 5 --criterion "Device model and iOS version" --criterion "Screen recording"
node bin/hireline.js wait TASK_ID --timeout 60
node bin/hireline.js review TASK_ID
node bin/hireline.js pay TASK_ID SUBMISSION_ID --amount 5 --rating 5
node bin/hireline.js reject TASK_ID SUBMISSION_ID --reason "Evidence is missing"
node bin/hireline.js refund TASK_ID
node bin/hireline.js audit verify

Plain-language CLI criteria require human review. Machine-checkable criteria can be supplied through MCP; see examples/job.json. Rejecting a submission is an authenticated off-chain action and does not request a transaction signature.

If the SDK reports an ambiguous submission/network error, do not re-create the bounty or retry payment blindly. Inspect the task and transaction/intent status on Gibwork first. Automated reconciliation and idempotent recovery remain future work.

MCP

Use examples/mcp-config.json as a template and replace the absolute path and connection values. Do not pass wallet secrets into the MCP process. All eight tools are integration tested:

Tool

Purpose

hireline_hire_human

Prepare, approve and submit a funded bounty

hireline_wait_for_submissions

Poll with a bounded timeout

hireline_review_submissions

Check declared acceptance criteria

hireline_pay_submission

Request owner approval for an escrow payout

hireline_reject_submission

Reject with actionable feedback

hireline_refund_bounty

Request approval to return escrow

hireline_jobs

Read local job state

hireline_audit_verify

Verify vault audit signatures and hash chain

Policy and optional phone experiment

Default policy allows USDC up to 25 per transaction and 50 per rolling 24 hours, counts signed direct token outflows conservatively even if the transaction is never broadcast, and asks for approval by default. Caps do not describe arbitrary inner-program effects. SOL rent through inner instructions is not fully decoded. Pin real program IDs independently; trust on first use is a convenience, not a program audit.

The existing Bland.ai phone adapter is retained as an experimental optional feature, not the primary security claim. HIRELINE_PHONE_DRY_RUN=1 prints the payload and always refuses. Real calls require an API key, phone number and PIN, incur provider charges and disclose the approval request and spoken response to that provider. Phone integration has parser tests but no live-call validation in this delivery. Use the terminal for the primary demo.

Submission package

BOUNTY_SUBMISSION.md contains the entry description and checklist. The terminal replay video and labelled PNG frames are included. The creator reports that the Hackathon role and two Discord sessions are already completed; the repository does not independently verify attendance.

MIT licensed. No user funds, secrets or personal phone numbers are included.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers