Connect
A remote MCP server with eight tools, drawing the same credits as the REST API. There is nothing to install:
- Claude, or any client that supports MCP OAuth: add the URL as a connector. The first tool call asks you to sign in, and there is no key to copy.
- Claude Code:
claude mcp add --transport http walletlink https://walletlink.social/api/mcp --header "Authorization: Bearer wts_live_YOUR_KEY"
- Cursor: create a key from the account menu at walletlink.social and choose Add to Cursor.
- Any other client: the same URL, with a key in an
Authorization: Bearer header. Keys are free for any signed-in account.
Listing the tools needs no credential. The MCP page has the config block and what a connection can reach, and the docs have a config for each client.
How it works
It also runs backwards: give it an X handle or a Farcaster username and it returns the wallets attached to that person.
Coverage, stated honestly
The number most tools quote is the one that flatters them. Two numbers matter here, and conflating them will make you plan a campaign you cannot run.
The chain decides this more than the collection does: Base sits at the top of that range because Base is where Farcaster lives, Ethereum near the bottom. The measured per-chain table lives in the coverage docs. Use your chain’s figure, not an average.
Having an account and reaching it are different claims. Of 482,968 X handles resolved, 70.1% are live, 19.7% suspended and 10.2% are names nobody holds. Matches carry that answer wherever the handle has been resolved.
Coverage would be higher if we guessed. Contacting the wrong person is worse than contacting fewer people.
Features
Pricing
Credit packs, bought once and metered in matches. A match is a wallet resolved to an X handle or a Farcaster account; a wallet that resolves to nothing costs nothing. Credits last 12 months from purchase. There are no subscriptions.
Every pack includes the same features; packs differ only in how many matches they hold. lib/packs.ts is the source of truth: the pricing modal, the checkout, the comparison pages and the schema.org offers all read from it.
API, MCP and the agent rail
Three doors into the same index, drawing the same match balance. The full reference, including credit costs, rate limits and error codes, is at docs.walletlink.social; the README does not restate it.
REST. Keys are self-serve from the account menu for any signed-in account, including one on the free allowance. A call draws credits only for wallets that resolve, so the key and the balance are separate questions.
MCP. https://walletlink.social/api/mcp, eight tools over the same endpoints, with a bearer key or an OAuth 2.1 connection. Listed in the official MCP registry as social.walletlink/wallet-identity. The design rationale (why the access token is an api_keys row, why the server bills nothing of its own) lives in the header of app/api/mcp/route.ts.
The skill file. https://walletlink.social/skill.md, for an agent that installs a capability from a URL rather than a config block: the tools, what each costs, how to authenticate, how to read a result. Generated from the same constants and canonical sentences as everything else, so it cannot quote a price the product does not charge.
Onchain rail. POST /api/x402/buy sells a $1 Agent pack for USDC on Base with no account, no card and no email: pay, and the response carries a fresh API key. /api/x402/recover reissues a key to the wallet that paid, on a signed challenge.
Apify. Wallet to Twitter & Farcaster Lookup wraps the REST API as a marketplace Actor, for people who buy tooling by browsing rather than by reading docs. Free to run, and it takes the caller’s own key, so it spends the same free allowance and the same packs. Source in integrations/apify-actor/.
Architecture
Negatives are persisted deliberately. “Checked, nothing there” is an answer worth keeping, and it is what stops the pipeline paying repeatedly to rediscover the same absence.
Tech stack
Project structure
docs-site/ and docs/ are deliberately separate. docs/ holds operational runbooks and is not the Mintlify content root.
Public on purpose
This repo is public deliberately. The product’s core claim is that every match carries the class of evidence behind it and none of it is inferred, and public code is what makes that claim checkable. What stays out is equally deliberate: docs/ is internal and never published, and operational secrets live in a private ops repo.
Getting started
Open localhost:3000. The app runs without a database; caching, history and the API need one. .env.example documents every variable: DATABASE_URL enables anything stateful, the Stripe keys enable payments, and identity-source credentials are listed beside their entries.
Commands
npm run check:<guard> runs one gate alone (palette, design, contrast, og, invariants, figures, height); package.json names them all.
Contributing
Changes go through a branch and a PR, never straight to main. The PR template asks for an explicit docs decision and CI enforces it: a PR touching the public API surface fails unless docs-site/ moves with it, or carries the no-docs-needed label.
See CLAUDE.md for conventions, including house style (sentence case headings, curly apostrophes, “onchain” as one word).
Security
Report a vulnerability privately, never in a public issue. SECURITY.md has the channels, the scope, the testing rules and what to expect; the preferred channel is a private report on GitHub. The same contacts are published for machines at /.well-known/security.txt.
Changelog
See CHANGELOG.md.
License
AGPL-3.0. See LICENSE.
Author
made with 🌠 by @starl3xx