Herdr UI
Herdr의 TUI가 뛰어나며, 창을 통해 추가되는 기능
어떤 웹사이트든 API로 변환해 에이전트가 호출할 수 있게 합니다. 사이트 프론트엔드에서 학습하고 변경 시 스스로 복구합니다
Turn any website into an API your agent can call. Learns from the site's own frontend, heals itself when the site changes.
개발 도구TypeScript · JavaScriptGitHub @goodnight000직접 설치운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
설치형 프로젝트는 배포 도메인 없이도 확인할 수 있습니다. 개인 저장소는 GitHub 로그인으로, 조직 저장소는 위의 저장소 확인 파일로 직접 확인해 주세요.
메이커가 쓴 소개는 위의 한 줄이 전부입니다. 더 자세한 내용은 저장소 README에서 읽을 수 있습니다. 저장소 README ↗
README 전체를 불러오는 중입니다.
README 전문 보기 ↗When an agent needs a website that has no API, it learns one. Every other agent gets it for free. Learned from the site's own requests, called over plain HTTP, verified and repaired by the agents that use it.
The agent internet · Quick start · How it works · Agents · Catalog · Sites · Help build it · Docs
Most of the web was built for people with a mouse. Goodreads stopped giving out API keys in 2020. Google Flights has no public API. So an agent that needs either one opens a browser, clicks, waits, reads the screen, and pays for every step in time and tokens.
reCAPTCHA digitized millions of books with work people were doing anyway: you typed two words to prove you were human, and one of them came from a scanned page. API Anything does the same for the web, with agents.
When an agent needs a site nobody has shared yet, it learns the site's own request, proves it works, and shares it with every cookie and token stripped out. The next agent that needs that site skips the browser and gets JSON from one HTTP request. Every call after that is a vote on whether the operation still works. When the site changes, the first agent to repair the operation repairs it for everyone.
It's live. Browse the shared catalog. Its home page also lists the sites agents asked for that nobody has shared yet. How the catalog works
Same agent, same prompt, started together. Left: it drives headless Chrome. Right: it calls API Anything's Google Flights operation.
Claude Opus 5.5 in Claude Code, 2026-09-28. Shown at 3× speed with no cuts; the timers show real elapsed time. MP4 · how it was recorded
One site, one model, a few dozen runs. Method, raw numbers and limits.
1. Connect it to your agents (Node 22.13+):
npx -y api-anything setup
It connects the MCP server to Claude Code, Codex, Cursor and Claude Desktop, adds the skill to the agents that take skills, and asks one question: help build the shared catalog? The default is yes. Or paste this into your coding agent and let it do the setup:
Set up API Anything for me: https://github.com/goodnight000/api-anything/blob/main/INSTALL.md
2. Restart the agent and ask it something:
What does Goodreads rate Piranesi?
3. Or call an operation yourself:
npx -y api-anything call hacker-news search query=sqlite
{"ok":true,"class":"ok","tier":1,"data":[
{"title":"Hosting SQLite databases on GitHub Pages or any static file hoster", ...}, ...],
"ms":185}
tier: 1 means one plain HTTP request, with no browser and no account. A failure says what
happened (class), why (reason) and what to do next (next).
mcp add command where it has one. Other entries in their configs are left alone, and each file
is backed up to <file>.bak-api-anything before its first edit. --dry-run prints what it would
change.API_ANYTHING_BROWSER names any other.~/.api-anything/key.json). There is no account.--yes shares without asking, --no-share turns sharing off; add --share-only to change only that.
Installed another way, your agent asks the question the first time it learns something to share.
See what leaves your machine.Install the command globally, then connect any client:
npm install -g api-anything
claude mcp add --scope user api-anything -- api-anything mcp # Claude Code
codex mcp add api-anything -- api-anything mcp # Codex
api-anything mcp --print-config # any other client
Setup details for every client · instructions for an agent installing it
fetch. If the site blocks that, fetch
from inside a browser page. As a last resort for a read, run the page and read its own response.Replay, fallback and repair in detail · design
Over MCP, an agent calls operations. It doesn't need a shell for that.
| tool | what it does |
|---|---|
find_sites | search this machine and the shared catalog by what you need, a domain or a URL |
learn_site | learn a read nobody shared yet from a page URL and three values, answer with it, and share it |
list_sites | the sites on this machine, with how many operations each has |
list_operations | a site's operations, each with a JSON Schema of its args, and the site's notes; pulls a shared site it doesn't have yet, with its reads only |
call_operation | call a read; it never sends a write |
call_write_operation | call a write; exists only on a server started with --allow-writes |
get_job | the result of a call that was still running after about 25 s |
login | refresh a session from the browser profile you chose, or open a window to sign in |
Each answer is JSON text, and an object answer is also sent as structuredContent. To build
operations by hand, an agent needs a shell and the skill.
--print-config prints the add command for Claude Code, Codex, Gemini CLI and VS Code, and the JSON
entry for Cursor and Claude Desktop. It uses absolute paths, because a client started from the Dock
or a menu may not get your shell's PATH:
api-anything mcp --print-config # reads only
api-anything mcp --print-config --allow-writes # also serve call_write_operation
--sites also serves each operation of the sites you name as a tool of its own, with its args as a
JSON Schema, so the agent skips the list_operations step. Each op costs about 200 tokens of tool
list, so it's opt-in:
api-anything mcp --sites goodreads,hacker-news # goodreads__searchBooks, ...
A tool call still running after about 25 s (a sign-in window, a long repair) answers
class: "pending" with a job, and keeps running. get_job waits for it and never runs it again.
The same call made while it runs joins it, so a second login doesn't open a second window, and a
write still in flight is never sent beside itself.
Client timeouts · troubleshooting
api-anything sites # the sites you can call
api-anything ops goodreads # params, returns and caveats
api-anything call goodreads searchBooks q=piranesi # JSON out; a failure exits nonzero
api-anything call google-flights search origin=SFO destination=NYC date=2026-12-01 --max-tier 1
api-anything call goodreads getBook bookId=50202953 --dry # the request, credentials redacted
api-anything <command> --help explains each command. Reference.
import { call } from "api-anything";
const r = await call("goodreads", "searchBooks", { q: "piranesi" });
if (r.ok) console.log(r.tier, r.data);
else console.log(r.class, r.reason, r.next, r.retry);
// a write needs allowWrites at every entry point
await call("my-site", "postComment", { text: "Ship it" }, { allowWrites: true });
npm install api-anything. examples/reading-list.mjs builds a
five-book table from Goodreads with no model and no browser.
Over MCP, an agent calls learn_site with a page URL and three values, and the operation is
learned, checked with a value it never saw, and shared. From the CLI, give the page URL with a
placeholder and two example inputs:
api-anything add hn-demo links \
--trigger 'https://news.ycombinator.com/from?site={domain}' \
--example domain=github.com --example2 domain=github.io --match path=/from \
--html '{"items":"tr.athing","fields":{"title":".titleline > a","url":".titleline > a@href"}}'
api-anything call hn-demo links domain=arxiv.org # 30 arxiv.org stories, tier 1
The browser loads the page once per example. The part of the request that changed with the input
becomes a parameter. You, or your agent, pick the request and the fields; API Anything builds the
template without an LLM. If example 2 gets example 1's data, the op is marked unproven: the
server may not read that param at all. A learned op sends the browser's own headers. Where plain HTTP is
refused for them (Hacker News's /from answers 419), a read is sent once more without them before
any browser is used.
Watch it learn and call, 25 s recording →
Tell an agent what you want from a site. The skill has it:
name(inputs) -> fields, and wait for your approval;capture --outline, a summary of what each request returns;One run on Goodreads took 6.3 minutes and $1.19 and produced search, book details, an author's books and reviews.
How it was explored, tested and compared
The catalog is a small Cloudflare Worker that stores operations and counts reports. Agents fill it, verify it and repair it as a side effect of using it.
api-anything search book ratings # or goodreads.com, or a page's URL
api-anything pull goodreads # checked against the shared rules first
api-anything call goodreads searchBooks q=piranesi
Your agent does this on its own: find_sites searches the catalog, and calling a site this machine
doesn't have fetches it, reads only. To share one by hand, prove it, then publish it:
api-anything check hn-demo links domain=arxiv.org --expect result # confirmed on the site
api-anything verify hn-demo # pass, fail or inconclusive
api-anything publish hn-demo # preview only
api-anything publish hn-demo --yes # upload, signed by this install
A new operation is a candidate until installs other than its uploader report it working from different networks; then it is served as live. Operations that write, that needed a login, or that send to another site's host wait for a maintainer, and are never promoted by reports.
Whether sharing is on or off, a search goes to the catalog: the words, domain or URL your agent passes
to find_sites, and the name of a shared site it calls before this machine has it. The catalog keeps
no search words. With sharing on:
With sharing off (api-anything setup --no-share --share-only), or before you answered, nothing is
shared or reported, and the catalog
still works for reads. How the catalog works
cookie:name), never their values, and a spec
holding a live credential is refused before it is saved.publish previews exactly what each upload sends, every host the op sends to, and anything that
may be yours, such as an email or an account id. Nothing is sent until --yes.unproven. The catalog runs the same rules again on every upload.enum, a min or a max. A call outside them is input, and nothing is sent.--allow-writes.Every call answers in fields, so an agent or a script can act without parsing prose.
| field | values | it tells you |
|---|---|---|
class | ok drift auth rate blocked input error refused duplicate | what happened |
write | not_sent not_applied accepted applied may_have_applied | what a write did |
retry | safe after_wait after_fix no | whether to send it again; retryAfterMs says when |
nextCall | login relearn fix_args check_site allow_writes ... | the one step to take next; over MCP, with the tool and its args |
nextPage, hasMore | the site's own cursor | how to get the next page of a list |
heal | {strategy, changes} | how a call that repaired the op did it, and what changed in its request; api-anything revert undoes it |
Writes are guarded at every step.
--allow-writes (MCP: call_write_operation, library: allowWrites).--write places no order.duplicate, unless you pass --again.
--idempotency-key on the first call makes a repeat return that call's record.Idempotency-Key: crypto.randomUUID()) is made fresh for each call, not replayed.accepted is a 2xx. Only a readback that finds the new item makes it applied.Against the local test site the suite uses. No write operation is bundled.
api-anything login linkedin
login imports that site's cookies from a browser profile you're already signed in to, so there's
usually no password to type. If several profiles are signed in, it asks which one. If none can be
imported, it opens a window to sign in by hand. A spec holds references to cookies and tokens, never
their values, so a refreshed session works without re-learning anything. No password goes in one
either: a trigger step that would type into a password or one-time-code field fails instead.
laravel_session, _app_session). login notes which ones a signed-out visit gets, and those
never count as signed in.login says so and keeps the session you had.[redacted] in every reason and next.login opens a window.30 read operations across 14 sites, bundled with the package and served by the catalog. They cover
selected features, not whole sites. api-anything ops <site> lists each op's params and caveats.
| site | operations | account |
|---|---|---|
google-flights | search · top · priceCalendar | no |
goodreads | searchBooks · getBook · getReviews · getWorkId · authorBooks | no |
rottentomatoes | searchMovies · getMovie | no |
hacker-news | frontPage · search | no |
x | getUser · getProfile | no |
instagram | getProfile · getPosts | no |
youtube | search | no |
steam | search | no |
airbnb | search | no |
amazon | search | no |
rightmove | locations | no |
pinterest | searchSuggestions | no |
linkedin | getMe · getProfile · getCompany · searchPeople · searchCompanies | yours |
dominos-au | findStores · findDeliveryStore · getMenu | 2 of 3 |
dominos-au came in through publish from a contributor; its last two ops were learned signed in.
goodreads was built by the explorer above. Everything agents share after this lands in the
catalog first.
The catalog grows when agents use it. Three ways to speed that up:
learn_site or
api-anything learn at one, and sharing does the rest.sites/ passes the same rules a shared one
does. ContributingFrom a checkout (Node 22.13+):
npm ci # install; also builds dist/
npm run cli -- <command> # the CLI from source: npm run cli -- call hacker-news search query=sqlite
npm test # unit + offline e2e; the browser tests skip without a Chromium browser
npm run check # typecheck src and test
npm run lint # what CI runs: formatting and lint, no changes
npm run format # apply formatting and safe lint fixes
npm run build # compile src to dist/
npm run demo -- 'agent memory' # examples/research.mjs: a research brief from Hacker News
npm run smoke:pack # pack, install the tarball in a temp dir, run its CLI and library (needs the npm registry)
learn_site learns from one page load per value, from a URL template. A site whose data appears
only after clicks or typing, or only on in-app navigation, needs the CLI's capture and add
with --steps or --soft-from. It learns reads only.blocked.verify proves an op only as far as its examples and checks go: a few cases a human confirmed,
not a test suite.readback that finds it says applied.| doc | what's in it |
|---|---|
| Setup for agents | install, connect each client, timeouts, troubleshooting |
| Reference | creating operations, replay and repair, logging in, safety, limits |
| Design | the authoritative spec, and the reasons behind it |
| Catalog | the shared catalog: promotion, reports, what it stores and what it leaves open |
| Benchmark · explorer | how every number on this page was measured |
| Demos | recorded terminal runs, with transcripts and tapes |
| Contributing | add a site spec, run the checks |