forager.ai
forager.
Search Forager's job-posting events, or just their count.
setup & usage
create an API key on app.forager.ai (key management — creation/deletion — is dashboard only, not from oto), then paste it into oto.
account_id exists if your key has access to several Forager accounts — leave it empty otherwise, it is resolved automaticallyUnlike most oto connectors, every search or lookup call bills one credit on the Forager subscription (forager_account(op="me") shows the balance). Only forager_account and forager_autocomplete are free.
op="totals" (job posts, organizations, role search) to learn a volume before paying for the full results pageforager_account(op="balance_log"|"balance_totals") traces consumptionlocations, industries/industries_exclude, keywords/organization_keywords, web_technologies/organization_web_technologies, person_skills expect integer identifiers, never a string. Passing locations=["Paris"] matches nothing. Resolve first via forager_autocomplete:
forager_autocomplete(op="locations", q="Paris") → get the id → forager_job_post(op="search", filters={"locations": [<id>], "is_remote": true})Forager combines job postings, company data and contact enrichment, in 6 tools:
forager_job_post(op="search", filters={"title": "engineer", "organization_ids": [...]})forager_job_post(op="totals", filters={"is_remote": true})forager_organization(op="search", filters={"industries": [<SaaS id>], "employees_start": 50, "employees_end": 200})forager_organization(op="website", domain="acme.com")forager_person(op="detail", linkedin_public_identifier="janedoe")forager_person(op="work_emails"|"personal_emails"|"phone_numbers", person_id=...) (personal_emails only returns consumer addresses — Gmail, Outlook… — never a company domain)forager_person(op="reverse_by_email", email="...") / op="reverse_by_phone"forager_person(op="role_search", filters={"role_title": "...", "organization_industries": [...]})forager_feedback(op="work_email", email="...", contact_status="invalid", is_correct_person=false) — each call creates a NEW feedback row, never an upsertGET/POST /api/api_keys/ and GET/DELETE /api/api_keys/{prefix}/ exist on the Forager side but are deliberately not exposed as tools: creating a key would expose a secret in the agent context, and deleting one could silently break another integration. Management exclusively on app.forager.ai.
forager_person(op="work_emails"|"personal_emails"|"phone_numbers") returns [] when nothing is found (not billed). op="reverse_by_email"|"reverse_by_phone" raises an error in the same case (Forager answers 404) — the two lookup families do not signal "nothing found" the same way, confirmed live.
Built from Forager's official OpenAPI spec (unlike Grain/Fireflies, a real machine-readable spec exists), then live-tested on a real Trial key (50 credits, 36 spent — one call per op of the 6 tools). Everything works end to end. Two real discoveries along the way:
forager_autocomplete returns ids as strings ("9839"), to be cast to integers before passing them back into a filters — see the note above on ID filtersforager_job_post(op="totals") and op="search") returned different total_search_results on the same filter (500 vs 949) during the test — no explanation found on the client side, keep it in mind if a number looks surprisingStill unconfirmed (not tested to save balance): the exact behavior on a badly typed filter, and the shape of test_scores on person_detail_lookup.
this connector accepts multiple comptes: each stored credential becomes a named account (one name per compte), at your level, your team's or your org's.
_account="<name>" on the tool; list them: oto_identity(op='list', connector='forager') (scope='org' or scope='group' for the org's or team's)oto_identity(op='set', connector='forager', identity_id='<name>'); rename: op='rename' with new_name_account) and adding upoutils
usage
claude plugin marketplace add otomata-tech/oto-plugin — mcp + skill configured.pipx install oto-cli then oto forager …