A free, open, auditable registry where companies list tools, agents discover them, and reputation emerges from verified usage — backed by Dolt DB, accessed via SSH, inspired by AT Protocol's data philosophy.
AI agents are increasingly capable, but when they need specialized tools — fraud detection, geospatial analysis, compliance checking — they hit a wall.
Tools are hardcoded or manually configured. There's no Yellow Pages for agent capabilities.
An agent can't know which tool provider is reliable, fast, or accurate without a human pre-vetting everything.
Switch your MCP server or API provider and you're rewiring everything from scratch.
When an agent makes a decision based on a tool's output, there's no versioned, reproducible record of what happened.
Agents interact with the world through HTTP clients, SDK wrappers, and credential managers. Discovery should be as simple as running a command.
The protocol debate (MCP vs. skills vs. REST vs. gRPC) is a distraction. The real gap is: how do agents find, trust, and audit tool usage across organizational boundaries?
Dan Abramov's article reframes AT Protocol as a distributed
filesystem. ToolShed borrows its design patterns — records,
.well-known discovery, “data outlives
software” philosophy.
.well-known discovery —
providers self-declare their tools at a standard URL
“Our memories, our thoughts, our designs should outlive the software we used to create them.” Replace “software” with “agent frameworks” and the same principle applies to tools.
SSH as the primary interface. Public key identity. Interactive TUI + non-interactive commands over the same protocol.
A multi-agent orchestration system — Dolt as the backbone for all agent state.
A SQL database you can fork, clone, branch, merge, push, and pull — just like Git. MySQL-compatible with full version history.
| Feature | Application in ToolShed |
|---|---|
dolt_history_* |
Full row-level history of every tool registration |
AS OF queries |
“What tools existed at time T?” |
dolt_diff() |
“What changed between schema versions?” |
| Branch & merge | Preview schema changes before publishing |
dolt clone / push |
Distribute the registry, federate across organizations |
| Signed commits | Tamper-evident audit trail |
Every definition is identified by a hash of its syntax tree. Names are just metadata — pointers to hashes.
“What we now think of as a dependency conflict is instead just a situation where there are multiple terms or types that serve a similar purpose.” The ToolShed applies this to tool schemas.
The ToolShed doesn't require an SDK, HTTP client, or credential manager. Agents interact via SSH — available in every runtime, every container, every sandbox. Providers declare tools in a YAML file. Agents discover them via SSH.
# Search the registry ssh toolshed.sh search "fraud detection" # Get tool details ssh toolshed.sh info acme.com/fraud-detection # Crawl a domain's tools ssh toolshed.sh crawl acme.com # Report a tool call (for reputation) ssh toolshed.sh report --tool acme.com/fraud-detection \ --latency 45ms --success --input-hash sha256:abc # Upvote a tool ssh toolshed.sh upvote acme.com/fraud-detection --quality 4 --useful # Interactive TUI browser ssh toolshed.sh
Identity is built-in. The first time you connect, your SSH public key fingerprint becomes your account ID. Zero signup. No email, no password, no OAuth.
version: "0.1" provider: domain: acme.com contact: tools@acme.com tools: - name: Fraud Detection description: Real-time fraud scoring for transactions version: "1.0.0" capabilities: [fraud-detection, real-time, fintech] invoke: protocol: rest endpoint: https://api.acme.com/fraud tool_name: fraud_detection schema: input: transaction_id: { type: string } amount: { type: number, min: 0 } merchant_category: { type: string } output: risk_score: { type: number, min: 0, max: 100 } flags: { type: array, items: { type: string } } pricing: model: free
~25 lines for a complete tool registration. An agent can read it. A
human can write it. Host it at
/.well-known/toolshed.yaml, then
ssh toolshed.sh crawl acme.com to index it.
The ToolShed exposes nine commands via SSH:
Find tools by capability, quality, and reputation
Get full details on a specific tool
Index tools from a domain's .well-known/toolshed.yaml
Submit an invocation report for reputation
Submit a quality review linked to a report
Verify domain ownership
Structured JSON command catalog for agent self-discovery
View Dolt commit history for a tool — every change is a commit
View computed reputation score with quality, upvotes, and trend
Agent has a task:
"analyze this transaction for fraud"
Agent doesn't have a fraud tool →
ssh toolshed.sh search "fraud detection"
ToolShed returns JSON results from the Dolt registry
Agent picks one, reads the endpoint and schema
Agent calls the tool DIRECTLY:
POST https://api.acme.com/fraud { ... }
Agent gets the result, uses it
Optionally:
ssh toolshed.sh report --tool acme.com/fraud --latency 45ms
--success
Optionally:
ssh toolshed.sh upvote acme.com/fraud --quality 5
--useful
ToolShed is involved in steps 2-3 (discovery) and 7-8 (reputation). It is never in the call path (step 5). Discovery happens organically at the edges.
A single Dolt database storing tool definitions, listings, invocation records, upvotes, reputation, and embeddings. Every mutation is a Dolt commit. The full history syncs to DoltHub — anyone can clone and verify.
There is no gateway proxy. The SSH server IS the registry service — it handles discovery, registration, reporting, and reputation. It never touches tool call traffic.
The invocation method is just a field in the tool record:
invoke: protocol: rest # or mcp, grpc, graphql endpoint: https://api.acme.com/fraud tool_name: fraud_detection
It's like how DNS doesn't care what protocol you speak once you've resolved the address. ToolShed is DNS, not a CDN. It tells agents where to go. It doesn't proxy the traffic.
SSH public key authentication solves the hardest bootstrapping problem in any registry: identity without signup.
First connection: 1. You run: ssh toolshed.sh 2. Your SSH client presents your public key 3. ToolShed computes: SHA256 fingerprint → that's your account ID 4. Account created automatically. Zero friction. Subsequent connections: Same key → same account → same history, reputation, tools
No email. No password. No OAuth flow. No API key to rotate. The SSH key you already have is your identity.
$ ssh toolshed.sh verify acme.com # Returns: Add this DNS TXT record: # toolshed-verify=sha256:your-key-fingerprint # Or: Place this at https://acme.com/.well-known/toolshed-verify.txt
Once verified, your key is bound to that domain. Tools crawled from
acme.com are attributed to your identity. Your upvotes
carry the weight of a domain-verified identity.
Python's subprocess.run. Node's
child_process.exec. Go's os/exec. No SDK
needed.
No credential files to leak, no env vars, no token refresh logic.
Mount a key, done. Works in CI/CD, sandboxes, agent runtimes.
ssh toolshed.sh search "x" returns structured JSON to
stdout. Perfect for piping.
ssh toolshed.sh (no args) opens a full TUI for
browsing.
Every entity in the system is a record — a structured document with a schema. No special servers for payment, reputation, or discovery. It's all records in the Dolt registry, with materialized views computed by whoever needs them.
A provider publishes a
toolshed.yaml file on their domain. The registry crawls
it and splits it into two parts: an immutable
definition (the contract) and a mutable
listing (the metadata). The registry hashes the
definition to produce a content_hash — the tool's
true identity.
version: "0.1" provider: domain: acme.com contact: tools@acme.com tools: - name: Fraud Detection description: Real-time transaction fraud scoring with ML version: "3.1.0" capabilities: [fraud, ml, financial, real-time] invoke: protocol: rest endpoint: https://api.acme.com/fraud tool_name: fraud_detection schema: input: transaction_id: { type: string } amount: { type: number, min: 0 } merchant_category: { type: string } output: risk_score: { type: number, min: 0, max: 100 } flags: { type: array, items: { type: string } } pricing: model: per_call price: 0.005 currency: usd payment: methods: - type: stripe_connect account_id: acct_acme_abc123 - type: free_tier limit: 100/month
When an agent calls a tool directly, it can report back for reputation:
id: inv_abc123 tool_id: acme.com/fraud-detection definition_hash: sha256:a1b2c3 key_fingerprint: SHA256:nThbg6kXUpJW... input_hash: sha256:deadbeef output_hash: sha256:cafebabe latency_ms: 45 success: true created_at: "2026-03-15T14:23:00Z"
ToolShed never sees the actual inputs or outputs. Only hashes.
After reporting a call, an agent can upvote. The system checks: has this SSH key reported an invocation of this tool? If yes, the upvote is linked. If no, it's rejected.
id: up_xyz789 tool_id: acme.com/fraud-detection key_fingerprint: SHA256:nThbg6kXUpJW... invocation_id: inv_abc123 invocation_hash: sha256:... ledger_commit: dolt:76qerj... quality: 5 useful: true created_at: "2026-03-15T14:23:05Z"
No payment proof needed. The SSH key + invocation record is the proof. You can't upvote a tool you haven't called.
Immutable contract: schema, invocation, capabilities
Mutable metadata: name, pricing, description → points to a definition
Record of a call: hashes, timing, success
Quality signal with proof-of-use (linked to a report)
SSH key fingerprint, domain, verification status
Materialized view from upvotes and reports
Inspired by the Unison programming language, tool definitions are identified by a hash of their content, not by a name or version number. Names and version labels are mutable metadata that point to immutable hashes.
New schema → new hash → new definition. Old hash still exists. Agents pinned to the old hash keep working.
Two definitions with different schemas are different hashes. They coexist. No coordination needed.
After a successful call, an agent stores
sha256:abc123 — immutable and precise. Names
can change; the hash is stable.
Two providers with the same schema and contract share a content hash. Discovery surfaces both providers for one definition.
“3.1.0” is for humans. The hash is the real identity.
tool_definitions is append-only.
dolt_history_tool_listings tracks every pointer
change. AS OF queries reproduce any point in time.
ToolShed is not a payment processor. Payment is a field on the tool record — the provider declares “here's how to pay me” and the agent/operator settles directly with the provider. ToolShed's job is to make tools findable and accountable, not to move money.
Free tools are first-class citizens. The registry works without any payment infrastructure.
pricing: model: free # or per_call, subscription, contact payment: methods: - type: free - type: stripe_connect account_id: acct_acme_abc123 - type: api_key signup_url: https://acme.com/developers - type: l402 endpoint: https://api.acme.com/l402/fraud price_sats: 50
The agent reads the payment methods and decides how to proceed. If it's free, just call. If it's Stripe, the operator handles billing. If it's L402, the agent pays per-call with Lightning. ToolShed surfaces this information — it doesn't process any of it.
ToolShed must compete on value (discovery, reputation, convenience) rather than being a required payment intermediary.
Reputation is not stored on the tool. It's derived — a materialized view computed from all upvote records and invocation reports in the Dolt registry. Nobody owns the score. Nobody can inflate it without actually calling the tool. Anybody can compute it.
-- REPUTATION for acme.com/fraud-detection: SELECT AVG(quality_score), COUNT(*), COUNT(DISTINCT key_fingerprint) FROM upvotes WHERE tool_id = 'acme.com/fraud-detection' AND invocation_exists = true -- linked to a valid invocation report -- Nobody owns this score. -- Nobody can inflate it without actually calling the tool. -- Anybody can compute it (clone the registry, run the query).
The v2 proof model is much simpler than payment-based proof:
1. Agent calls tool directly → reports back with hashes and timing 2. Agent upvotes: ssh toolshed.sh upvote acme.com/fraud --quality 4 3. Registry checks invocations: "has this SSH key reported a call to this tool?" → Yes, report inv_abc123 exists → upvote accepted and linked 4. No payment needed. The invocation record IS the proof.
| Attack | Why It's Hard |
|---|---|
| Sybil (fake accounts) | New SSH keys have zero history. Upvotes from fresh keys are near-worthless. |
| Self-upvoting | Must call your own tool and report it. Key matches provider → filtered. Patterns detectable. |
| Ballot stuffing | Requires actual invocation reports per key. Can't upvote without reporting a call. |
| Drive-by upvotes | Can't upvote without a linked invocation report. The invocation record is the gatekeeper. |
| Deleting bad reviews | Impossible. Upvotes live in the shared registry. Dolt commits are immutable. |
Because the registry is a Dolt database anyone can clone, anyone can build discovery algorithms over the data:
Clone the Dolt registry, write your own ranking SQL, expose it as an API. Competition between discovery algorithms improves quality for everyone.
Every table gets Git-style version control for free. Time-travel queries, schema diffs, branch-and-merge, and a tamper-evident audit trail.
-- Accounts (SSH key identity) CREATE TABLE accounts ( id VARCHAR(255) PRIMARY KEY, -- SHA256:nThbg6kXUpJW... domain VARCHAR(255), domain_verified BOOLEAN DEFAULT FALSE, key_type VARCHAR(32), -- ssh-ed25519, ssh-rsa, etc. public_key TEXT, created_at DATETIME, updated_at DATETIME ); -- Tool definitions (immutable, content-addressed) CREATE TABLE tool_definitions ( content_hash VARCHAR(71) PRIMARY KEY, -- sha256:... of (schema + invocation + capabilities + domain) provider_account VARCHAR(255) NOT NULL, provider_domain VARCHAR(255) NOT NULL, schema_json JSON NOT NULL, invocation_json JSON NOT NULL, capabilities_json JSON, created_at DATETIME, FOREIGN KEY (provider_account) REFERENCES accounts(id) ); -- Tool listings (mutable, human-readable metadata) CREATE TABLE tool_listings ( id VARCHAR(255) PRIMARY KEY, -- acme.com/fraud-detection definition_hash VARCHAR(71) NOT NULL, provider_account VARCHAR(255) NOT NULL, provider_domain VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, version_label VARCHAR(32), description TEXT, pricing_json JSON, payment_json JSON, source VARCHAR(32), -- 'push' or 'crawl' created_at DATETIME, updated_at DATETIME, FOREIGN KEY (definition_hash) REFERENCES tool_definitions(content_hash) ); -- Upvotes (proof-of-use quality signals) CREATE TABLE upvotes ( id VARCHAR(255) PRIMARY KEY, tool_id VARCHAR(255) NOT NULL, key_fingerprint VARCHAR(255) NOT NULL, invocation_id VARCHAR(255) NOT NULL, quality_score INT, useful BOOLEAN, created_at DATETIME, FOREIGN KEY (tool_id) REFERENCES tool_listings(id) ); -- Invocations (tool call records) CREATE TABLE invocations ( id VARCHAR(255) PRIMARY KEY, tool_id VARCHAR(255) NOT NULL, definition_hash VARCHAR(71) NOT NULL, key_fingerprint VARCHAR(255) NOT NULL, input_hash VARCHAR(71), output_hash VARCHAR(71), latency_ms INT, success BOOLEAN, created_at DATETIME ); -- Reputation (materialized view) CREATE TABLE reputation ( tool_id VARCHAR(255) PRIMARY KEY, verified_upvotes INT DEFAULT 0, avg_quality DECIMAL(3,2), unique_callers INT DEFAULT 0, computed_at DATETIME );
Company already has their tool running (API, MCP server, whatever)
They write a toolshed.yaml file with schema,
endpoint, pricing, payment
They (or anyone) trigger indexing:
ssh toolshed.sh crawl acme.com
Optionally: verify domain ownership via
ssh toolshed.sh verify acme.com
That's it. No SDK. No middleware. No infrastructure changes.
Agent needs fraud detection for a financial analysis task
Searches: ssh toolshed.sh search "fraud detection"
Gets ranked JSON results, validates schema matches its needs
Calls the tool directly:
POST https://api.acme.com/fraud { ... }
Optionally reports:
ssh toolshed.sh report --tool acme.com/fraud --latency
45ms
Optionally upvotes:
ssh toolshed.sh upvote acme.com/fraud --quality 5
Quality → Visibility → Usage → Revenue → Quality ∞
The registry is free. Search is free. Registration is free. Upvotes are free. The entire discovery and reputation system works without payment.
Stage 1 (MVP): The registry — seed it with real tools, make discovery work Stage 2 (Growth): Network effects — providers and agents concentrate here Stage 3 (Mature): Reputation data — the upvote/report graph is the real value Stage 4 (Scale): The registry IS the moat — like npm, whoever has the packages wins
Nobody complains that GitHub is “centralized” because Git is open and you can leave. Same energy. The registry is a Dolt database anyone can clone. The SSH server is open source anyone can run.
| You Know This | ToolShed Equivalent |
|---|---|
| DNS | Tool discovery — resolve a capability to an endpoint |
/.well-known/ |
Provider self-declaration of tools |
| npm Registry | Tool registry — search, discover, version |
| npmjs.com | toolshed.sh — the hosted service |
| SSH authorized_keys | Identity — your key is your account |
| terminal.shop | SSH as the primary user interface |
| Unison hashes | Content-addressed tool definitions |
| App Store ratings | Reputation — only from verified users with proof-of-use |
| Git + GitHub | Dolt + DoltHub — version control for the registry |
npm + SSH + Dolt, for AI agent tool calls, with AT Protocol's data philosophy and terminal.shop's interface model.
Self-reported invocation data could be fabricated. Mitigations: key reputation weighting, provider counter-attestation, statistical anomaly detection.
Should providers optionally report invocations too? When both sides agree, strong signal. When they don't, weak signal.
Stripe's Agent SDK, L402, Cashu — which payment systems work well for agent-to-provider settlement? The tool record supports declaring multiple methods.
How often should ToolShed re-crawl
/.well-known/toolshed.yaml? Provider-triggered
refresh? Webhook? Poll?
When a provider updates their schema (new hash), how do agents discover the migration path? Deprecation notices on old listings?
With free registration, how to prevent the registry from being flooded with low-quality tools? Reputation-weighted search helps, but cold-start is hard.