Skip to main content
Glama
sahilrit
by sahilrit

openactors

A free, self-hosted MCP server that exposes web scrapers as Apify-compatible Actors. Point any MCP client at it instead of a paid scraping service.

Tool names match mcp.apify.com, so an existing client config works after changing one line.

Why this exists

mcp.apify.com is four layers, and only two of them are worth paying for:

Layer

Reality

The MCP server

MIT-licensed and open source. A few hundred lines of glue over a REST API.

The platform — datasets, key-value stores, run records

Crawlee, MIT, and it is Apify's own engine. Free to self-host.

~62,000 Store Actors

Third-party and proprietary. The actual product.

Residential proxy IPs

~$1–4/GB. The actual moat.

openactors reimplements layer 1, reuses layer 2 wholesale, and rewrites only the handful of Actors worth having. It is free for targets that don't need rotating residential IPs — which covers documentation, blogs, public JSON APIs, and most of the open web.

It is not a clone of the Apify Store. Unknown Actor ids return a clear error rather than pretending to work.

Related MCP server: Apify MCP Server

Install

npm install && npm run build

Connect

Local, over stdio — the normal case:

{
  "mcpServers": {
    "openactors": {
      "command": "node",
      "args": ["/absolute/path/to/openactors/dist/src/server.js"]
    }
  }
}

Remote, over HTTP:

AUTH_TOKEN=$(openssl rand -hex 24) PORT=8080 npm run start:http
{
  "mcpServers": {
    "openactors": {
      "url": "https://your-host/mcp",
      "headers": { "Authorization": "Bearer <your token>" }
    }
  }
}

The HTTP server is stateless per request, like Apify's hosted one, but shares a single run history across them so get-actor-run can still find a run that call-actor just reported. /health lists the installed Actors.

Set AUTH_TOKEN before exposing the port. This server runs arbitrary scrapers on request; an open one is someone else's scraping proxy. It is optional only so that local use stays frictionless, and the server warns at startup when it is unset.

Docker

docker build -t openactors .
docker run -p 8080:8080 -e AUTH_TOKEN=... -v openactors-storage:/app/storage openactors

Built on the Playwright image, because maps/google-maps needs a real browser and its system libraries are the tedious part. The image tag tracks the playwright dependency — bumping one without the other fails at browser launch rather than at build time.

Tools

Discovery-based, following Apify's design: rather than one tool per scraper, a few meta-tools let the agent discover capabilities at runtime. That's what lets the Actor count grow without bloating the tool list.

Tool

Purpose

search-actors

Find an Actor by keyword

fetch-actor-details

Read its input JSON Schema

call-actor

Run it; returns a preview plus a datasetId

waitSecs controls how long to wait — see below

get-actor-run / get-actor-run-list

Status and history of runs

get-actor-log

Per-item failures that didn't fail the whole run

abort-actor-run

Stop a run in progress; keeps what it collected

get-dataset-items

Page through results, optionally projecting fields

get-dataset / get-dataset-schema

Item count; inferred field shape

get-key-value-store-record

Read a stored record by key

Long runs

MCP clients abandon a request after about sixty seconds, which is far short of a crawl that reads a page per item. call-actor therefore starts a run and waits only waitSecs for it (default 50, under that limit). If the run is still going you get the runId back with stillRunning: true, and poll get-actor-run until it finishes, then read results with get-dataset-items. waitSecs: 0 returns immediately.

This matters more than it sounds: without it, the request dies while the work carries on invisibly, and nobody is holding the id needed to find it again. Over REST the same control is ?waitForFinish=, matching Apify's parameter.

Tool results are capped at a character budget and tell you how to page for the rest, because a scraped page can be tens of thousands of characters and a tool result goes straight into the agent's context.

Actors

Actor

Replaces

Notes

web/site-crawler

apify/website-content-crawler

Any site → clean Markdown. Boilerplate stripped via Readability. Runs from your own IP.

jobs/ats-boards

paid ATS scrapers

Open roles straight from Greenhouse, Lever, Ashby, SmartRecruiters, Workable and Recruitee. No scraping — these are the public no-auth JSON APIs each ATS publishes so companies can embed listings. Nothing to block.

web/rag-browser

apify/rag-web-browser

Search the web and get the top results as Markdown in one call. Tries Brave, then DuckDuckGo.

maps/google-maps

compass/crawler-google-places

Local businesses with rating, category, address and phone. Drives a real browser — the slowest and most fragile Actor here.

linkedin/jobs

LinkedIn scrapers

Job listings from LinkedIn's public endpoint. No account, no cookie, no browser.

linkedin/jobs

Uses the endpoint LinkedIn's own logged-out job search calls, so no account, cookie or login is involved and there is nothing that can be restricted. Plain HTTP, no browser, paced three seconds between pages.

{ "keywords": "performance marketing", "location": "United Kingdom", "remoteOnly": true, "postedWithinDays": 30 }

Both filters were checked against live data rather than assumed: f_TPR is exact (a one-day window returns only today and yesterday; ninety days reaches back to July), and f_WT is real — remote and on-site result sets are near-disjoint. LinkedIn's own labelling is imperfect though, so an occasional listing whose title says on-site still comes through under remoteOnly.

Pages hold ten postings and consecutive offsets are disjoint, so paging advances by the number of cards received. Results are deduplicated by URL with tracking parameters stripped.

Console

AUTH_TOKEN=secret npm run start:http   # then open http://localhost:8080

A single page served by the server: browse Actors and run them with arbitrary input, watch runs with their duration, memory and item counts, read logs, manage schedules and tasks, and download any dataset as JSON, CSV or Excel.

Self-contained — no CDN, no external fonts, nothing fetched from the network — so it works offline and under a strict content policy, which is the right default for a tool that runs scrapers on your own machine. The page itself is served unauthenticated; every request it makes carries the token, so it reveals nothing without one.

Connecting Claude (OAuth + tunnel)

Claude's connector reaches your server from Anthropic's cloud, not from your machine, so localhost is invisible to it and a local stdio server cannot be used. It also speaks only OAuth — its UI has no field for a static token. Both gaps are covered:

scripts/install-tunnel.sh                        # once
OAUTH_PASSWORD='something-long' scripts/tunnel.sh

That prints a public HTTPS URL. Paste <url>/mcp into Claude as a custom connector; Claude discovers the OAuth endpoints, registers itself, and sends you to a consent page that asks for OAUTH_PASSWORD.

The consent step is not ceremony. Auto-approving would let anyone who found the URL complete the flow and mint a token for a server that runs arbitrary scrapers on your machine. For the same reason, the launcher refuses to open a tunnel if something is already listening on the port — it would otherwise publish that other server, which may have no authentication at all.

Tokens and client registrations survive a restart, so restarting the server does not force you to re-add the connector.

A permanent URL

A quick tunnel's hostname changes every restart, which means re-adding the connector each time. For a stable one:

.bin/cloudflared tunnel login                       # once; opens a browser
scripts/named-tunnel.sh setup jobs.yourdomain.com
OAUTH_PASSWORD='…' scripts/named-tunnel.sh run jobs.yourdomain.com
OAUTH_PASSWORD='…' scripts/named-tunnel.sh install jobs.yourdomain.com   # start at login

This needs a domain on your Cloudflare account — Cloudflare's constraint, not this script's: named tunnels route through a zone you control, and there is no free Cloudflare-provided hostname for them. Any domain works, including one already on Cloudflare for something else; a subdomain is enough.

install registers two launchd agents — one for the tunnel, one for the server — that start at login and restart if they die, which is what makes the URL genuinely permanent rather than merely stable.

Two agents invoking their binaries directly, rather than one agent running a shell script: macOS denies /bin/bash access to ~/Documents, so a shell-based agent dies instantly with "Operation not permitted" while the same command works from a terminal. Agent logs go to ~/Library/Logs/openactors/ for the same reason — launchd cannot create files in ~/Documents, and the symptom is an agent with a healthy PID and completely empty logs.

A DNS caveat worth knowing: some ISP resolvers return NXDOMAIN for *.trycloudflare.com. Claude is unaffected — it resolves through its own DNS — but your browser may not open the consent page. Point your Mac at 1.1.1.1 or 8.8.8.8 (System Settings → Network → DNS) if that happens.

REST API

Paths mirror Apify's, including its ~ separator for namespaced Actor ids — a / in an id is otherwise indistinguishable from a path separator, which is exactly why Apify chose ~. A client written against Apify's API mostly needs its base URL changed.

AUTH_TOKEN=secret npm run start:http

curl -H "Authorization: Bearer secret" localhost:8080/v2/acts
curl -H "Authorization: Bearer secret" -X POST localhost:8080/v2/acts/jobs~ats-boards/runs \
     -d '{"boards":["ashby:linear"],"titleIncludes":["engineer"]}'
curl -H "Authorization: Bearer secret" "localhost:8080/v2/datasets/<id>/items?format=csv&fields=title,url"

Endpoint

Purpose

GET /v2/acts · GET /v2/acts/:id

List Actors; read one with its input schema

POST /v2/acts/:id/runs?timeout=

Start a run

GET /v2/actor-runs · /:id · /:id/log

Run history, detail, log

POST /v2/actor-runs/:id/abort · /resurrect

Stop a run; re-run a finished one

GET /v2/datasets/:id · /:id/items

Item count; export (see below)

GET /v2/key-value-stores/:id/records/:key

Read a stored record

GET/POST /v2/actor-tasks · DELETE /:id · POST /:id/runs

Saved Actor configurations

Input is validated against the Actor's schema before a run starts, as Apify does. A misspelled parameter returns 400 naming the unknown field rather than running a full crawl that silently ignores it and returns plausible, wrong results. Schema defaults are applied, and numeric strings from query parameters are coerced.

Exports

?format= accepts json, jsonl, csv, xml, html, rss and xlsx, with fields=, omit= (which wins over fields, as on Apify), clean=1 to drop #-prefixed debug fields, and attachment=1 for a download filename.

Run states

The full Apify set: READY, RUNNING, TIMING-OUT, ABORTING, SUCCEEDED, FAILED, TIMED-OUT, ABORTED. The distinctions matter — a run that exceeded its limit is a different diagnosis from one a caller stopped, and an earlier version reported both as ABORTED, making a too-short timeout look like user action. Items collected before a timeout are kept.

Runs are persisted, so a run started by the scheduler is inspectable from the REST API or an MCP client, and survives a restart. A run found still RUNNING at startup is recorded as failed — its process is gone and nothing will finish it.

Webhooks

cp webhooks.example.json webhooks.json    # or just set WEBHOOK_URL

Events use Apify's names — ACTOR.RUN.CREATED, .SUCCEEDED, .FAILED, .ABORTED, .TIMED_OUT, .RESURRECTED — and the payload carries the same actorId / actorRunId / resource shape, so a consumer written for Apify keeps working.

Each webhook may filter by events and by actors. Delivery retries three times with backoff, treats a non-429 4xx as a settled rejection rather than retrying it, and can never change a run's outcome: a dead endpoint is logged against the run and nothing more.

Process isolation

Every Actor runs in its own child process. The server never imports Actor code.

This is not defensive decoration. Scraper code drives browsers and parses hostile HTML, and three failure modes will otherwise take down the MCP server and the scheduler that depends on it:

Failure

In-process

Isolated

process.exit() or a segfault

Server dies

Run reports FAILED, items already written are kept

Throw from a stray callback

Server dies

Run reports FAILED with the message

Synchronous infinite loop

Unrecoverable

Killed at the timeout

Runaway allocation

Machine memory exhausted

Killed at the heap ceiling

The infinite loop is the case that settles the design: a loop that never yields cannot be interrupted by an AbortController, a timer, or a promise rejection, because none of them ever get to run. Only killing the process works, and only a separate process can be killed.

An abort asks the Actor to stop first — a cooperative Actor checking ctx.signal exits cleanly and keeps its results — and escalates to SIGKILL only after a grace period, since an Actor ignoring the abort is exactly the one a catchable signal will not stop either.

memoryMbytes (MCP) and ?memory= (REST) set the heap ceiling, default 2048.

The cost is about 420ms per run for the fork and module load. That is real, and it is why this is worth stating rather than burying: for a crawl measured in seconds it is noise, and for a run-every-six-hours digest it is irrelevant. If you ever need thousands of tiny runs a minute, this is the trade to revisit.

Anti-blocking

Requests carry complete, internally consistent browser headers from Apify's own header-generator, rather than a hand-written User-Agent whose sec-ch-ua and Accept headers contradict the browser it claims to be. One identity is held per session — changing browser between pages of a single crawl is itself anomalous — and a 429 or 403 rotates it, since retrying with the identity that just got refused repeats the failed request. Crawlee's session pool is enabled for crawls, and browser runs jitter their viewport.

Daily digest

Saved searches, run on a schedule, reporting only what you have not already seen. This is what turns the Actors from something you remember to run into something that works while you sleep.

cp searches.example.json searches.json   # then edit
npm run digest

Each search names an Actor and its input:

{
  "searches": [{
    "name": "Performance marketing in India, posted this week",
    "actor": "linkedin/jobs",
    "input": { "keywords": "performance marketing", "location": "India", "eligibleFrom": "IN" },
    "display": ["title", "company", "location", "postedAt"]
  }],
  "output": { "dir": "digests", "keepDays": 90 }
}

Output is written to digests/YYYY-MM-DD-HHMM.md and .html, plus latest.*. Filenames carry the time, not just the date: a digest reports what is new since the last run, so on a sub-daily schedule two runs sharing a date-only name would overwrite each other and the earlier results would be lost.

Items are recognised by url (override with key), and a key is remembered for keepDays — comfortably longer than a posting stays listed, or an old role would fall out of memory and be reported as new again. An item with no usable key counts as new: showing a role twice is a smaller failure than never showing it. A search that fails is reported in the digest rather than taking the other searches down with it, and state is saved only after every search completes, so an interrupted run cannot mark items seen that were never reported.

Renaming a search resets its history — names key the state.

Finding work that is remote and open to you

A country search on a general board returns roles that are remote within that country — remote from Austin, still requiring US work authorisation. Measured here twice, across hundreds of postings: none were open from India.

jobs/remote-boards reads RemoteOK, Remotive and Himalayas instead. These publish an explicit restriction field — Worldwide, USA, Germany, Austria — which is the difference between "remote" and "remote and open to you", and eligibleFrom judges against it.

Two things learned the hard way from those feeds. RemoteOK's tags are close to noise — a retail role tagged dev, node, math, a quality-systems role tagged marketing — so matching runs on titles, not tags. And its feed carries local jobs with city restrictions, which worldwideOnly removes.

Himalayas serves twenty roles per request against a feed of six figures, so it is walked by cursor; without paging it contributes almost nothing.

Set expectations from the numbers. In one sweep of 617 listings, four were open from India. That is not the tool underperforming — it is the supply.

Verifying the remote claim

A saved search can set verifyRemote: true. Every posting is then opened and read before it reaches the digest, and roles whose text contradicts the remote tag are dropped — of 242 roles LinkedIn tagged remote here, 74 said otherwise in the body.

keepVerdicts controls what survives, defaulting to remote and unclear: most postings never state the arrangement, and dropping those would discard the majority of the market on the strength of an omission. Verification failing is never fatal — the unverified roles still appear, because losing a day's results to a broken check is worse than showing a few that turn out to be hybrid.

jobTypes restricts to employment types, including freelance — which maps onto LinkedIn's contract code, since it has no separate freelance category. The filter is real but leaky: sampled properly, about a quarter of the contract pool also appears under full-time.

Knowing when a search has broken

A scraper whose target changed returns nothing, and in a digest that is indistinguishable from a quiet week — so the digest keeps arriving, keeps looking healthy, and keeps saying nothing new for as long as nobody checks.

Each search's total yield is tracked across runs. A collapse to under a fifth of normal is flagged at the top of the digest, escalates to broken if it persists, and makes the run exit non-zero so a scheduler surfaces it.

Three details decide whether this is useful or just noise:

  • Judged on total scraped, not on what is new. "New" legitimately falls to zero once a search has caught up; total does not.

  • The baseline is the 75th percentile, which has to survive two opposite failure modes. A plain median lets a sustained breakage rewrite normal — once the broken runs outnumber the healthy ones it sinks to meet them and the alert vanishes exactly when it matters. Anchoring on the maximum fixes that and hands the baseline to a single freak run, after which everything looks broken.

  • A search that has never returned anything is never flagged. The globally-open watch is legitimately empty most days, and alerting on it would train you to ignore the alerts.

Duplicates and decisions

Several searches legitimately match the same posting — four keyword variants over one job market overlap heavily. Roles are deduplicated across searches within a run, so a job appears once rather than in every section that matched it. In practice that is around 30 rows a run here.

Roles you have marked stop appearing at all:

mark-job    urls: [...]  mark: applied | ignored
get-marked-jobs
unmark-job  urls: [...]

Chasing what has gone quiet

Applications recorded with mark-job are tracked, and any that has been silent past followUpAfterDays (default 7) appears at the top of the digest — above new roles, because a conversation already started is worth more than another listing, and anything below a hundred new rows never gets read.

get-follow-ups    afterDays: 7
record-response   url: …  response: replied | rejected | interview | offer
record-follow-up  urls: [...]

Two rules stop it becoming noise. Any response at all — including a rejection — ends the chase, because following up after a reply reads as not having read their message. And a recorded follow-up resets the clock, so one silence is not flagged every single day.

That is what separates a working list from a feed: without it every role you have already decided about comes back forever, and the only record of your own decisions is your memory.

On volume: LinkedIn returns a rotating sample of a large corpus rather than the whole thing, so early runs surface a lot that is technically new to you. It settles as the seen-set fills. Narrowing postedWithinDays shrinks the corpus and settles it faster.

Scheduling

Two ways, and the in-app one is now the default recommendation.

In-app schedules

Managed over REST or MCP and run by the server itself, so they are portable, inspectable and editable from a client:

curl -X POST localhost:8080/v2/schedules -H "Authorization: Bearer $TOKEN" \
  -d '{"id":"jobs-6h","cron":"0 */6 * * *","task":"remote-growth","timezone":"Asia/Kolkata"}'

A schedule points at either an Actor with inline input, or a saved task. The cron expression is validated when the schedule is saved rather than when it fires — a schedule that silently never runs is far harder to notice than one that refuses to be created. nextRunAt is written before the run starts, so a run that overruns its interval cannot be started twice.

launchd (macOS)

Still supported for the digest specifically, since it survives reboots without the server running:

./scripts/schedule.sh install                      # daily at 08:00
DIGEST_EVERY_HOURS=6 ./scripts/schedule.sh install # 00:00, 06:00, 12:00, 18:00
./scripts/schedule.sh status
./scripts/schedule.sh run                          # once, exactly as the scheduler would
./scripts/schedule.sh uninstall

DIGEST_EVERY_HOURS must divide 24; DIGEST_HOUR and DIGEST_MINUTE offset the times. Sub-daily schedules use fixed clock times rather than an interval timer, which would drift and restart from zero on every reboot.

launchd rather than cron: it survives reboots, needs no always-running process, and catches up a run missed because the Mac was asleep — which matters for a laptop that is not reliably awake at 08:00. Logs land in logs/.

The agent runs the built dist/ output, so re-run npm run build after changing an Actor or the schedule keeps running the old code.

Proxies

Everything works from your own IP by default, which is what makes it free. When a target starts blocking, this is the seam.

What this is and is not. Residential IPs are rented from a provider; no amount of code produces them. What is software here is the other half of Apify Proxy — session stickiness, rotation, country targeting and ban handling — and that is what this implements, with the provider left pluggable.

Simplest form, unchanged:

PROXY_URL=http://user:pass@host:port

For a residential gateway, proxy.json (or the PROXY_* variables):

{
  "mode": "gateway",
  "preset": "iproyal",
  "user": "your-account",
  "password": "your-password",
  "country": "US",
  "sessionTtlSecs": 1800
}

Presets exist for apify, iproyal, oxylabs, dataimpulse and evomi. Anything else works via a username template, because every vendor encodes the same three parameters differently:

Provider

Username shape

Apify

groups-RESIDENTIAL,session-{session},country-{country}

IPRoyal

{user}-country-{country}-session-{session}

Oxylabs

customer-{user}-cc-{country}-sessid-{session}

DataImpulse

{user}__cr.{country};sid.{session}

{session}, {country} and {user} are substituted; a template whose placeholder is empty is cleaned up rather than left with stray separators that would break authentication.

Sessions are keyed on the run id, so one run holds one address across all its requests. This matters more than raw rotation: a crawl that changes IP between pages looks less like a person, not more. Sessions expire after sessionTtlSecs (default 30 minutes, matching how residential pools recycle), and the same session drives both the exit IP and the generated browser fingerprint — a request arriving from a new address wearing the old fingerprint, or the reverse, is more distinctive than either change alone.

A 403 or 429 counts a strike against the session; two retires it. One block can be bad luck, and discarding a working address for it burns the pool faster than the blocks do.

GET /health reports whether a proxy is active, its mode, country and live session count — never the credentials.

Cost, so the trade is explicit: residential bandwidth runs roughly $1–4/GB. Only maps/google-maps at volume and heavy crawling need it; the ATS job APIs, LinkedIn's public endpoint and ordinary site crawling do not.

Composition and metrics

An Actor can run another:

const nested = await ctx.call('jobs/ats-boards', { boards: ['ashby:linear'] });
for (const job of nested.items) await ctx.pushData({ ...job, tagged: true });

The request goes back to the parent, so a nested run gets the same validation, isolation and limits as any other rather than a second execution path with its own rules. A nested run that does not succeed throws in the caller — returning it quietly would let an Actor build results on top of a run that produced nothing and report success for both. Nesting is capped at three levels.

Nested runs are exempt from the concurrency limit by necessity: the caller is already holding a slot and waiting, so queueing the callee behind it would deadlock outright at a limit of one.

Every run reports peakMemoryMb, cpuMs and computeUnits (gigabyte-hours, the unit Apify bills in — the honest measure of what a run cost to execute, whoever is paying). Memory is measured as RSS rather than heap, because the browser and parser buffers a crawl uses live outside the JS heap.

Limits and housekeeping

Concurrency. Runs are capped at MAX_CONCURRENT_RUNS (default: one less than the core count). This became necessary the moment Actors moved into child processes — each run is a real OS process with its own heap, so an unbounded burst exhausts the machine rather than merely slowing it. Queued runs sit in READY, which is exactly what that state means, so a client polling can tell "queued" from "running". A run aborted while still queued gives its slot straight back rather than starting work nobody wants.

Storage retention. Every run creates a dataset, so they accumulate — a few hundred within a day of ordinary use. clean-up-storage (MCP) removes storages past a retention window; stores holding configuration are never touched, and it defaults to a dry run, because a cleanup that deletes on first acquaintance is a trap.

match takes a regular expression on the storage name and waives the age check, since a name is the more specific instruction of the two. Age alone cannot separate throwaway storages from real ones when both were created the same day — exactly the state a testing session leaves behind. An invalid pattern is refused rather than treated as "match everything", which would delete the lot. Pass protect to keep named storages regardless.

Notes on fragility

Composition and metrics

An Actor can run another:

const nested = await ctx.call('jobs/ats-boards', { boards: ['ashby:linear'] });
for (const job of nested.items) await ctx.pushData({ ...job, tagged: true });

The request goes back to the parent, so a nested run gets the same validation, isolation and limits as any other rather than a second execution path with its own rules. A nested run that does not succeed throws in the caller — returning it quietly would let an Actor build results on top of a run that produced nothing and report success for both. Nesting is capped at three levels.

Nested runs are exempt from the concurrency limit by necessity: the caller is already holding a slot and waiting, so queueing the callee behind it would deadlock outright at a limit of one.

Every run reports peakMemoryMb, cpuMs and computeUnits (gigabyte-hours, the unit Apify bills in — the honest measure of what a run cost to execute, whoever is paying). Memory is measured as RSS rather than heap, because the browser and parser buffers a crawl uses live outside the JS heap.

Limits and housekeeping

Concurrency. Runs are capped at MAX_CONCURRENT_RUNS (default: one less than the core count). This became necessary the moment Actors moved into child processes — each run is a real OS process with its own heap, so an unbounded burst exhausts the machine rather than merely slowing it. Queued runs sit in READY, which is exactly what that state means, so a client polling can tell "queued" from "running". A run aborted while still queued gives its slot straight back rather than starting work nobody wants.

Storage retention. Every run creates a dataset, so they accumulate — a few hundred within a day of ordinary use. clean-up-storage (MCP) removes storages past a retention window; stores holding configuration are never touched, and it defaults to a dry run, because a cleanup that deletes on first acquaintance is a trap.

match takes a regular expression on the storage name and waives the age check, since a name is the more specific instruction of the two. Age alone cannot separate throwaway storages from real ones when both were created the same day — exactly the state a testing session leaves behind. An invalid pattern is refused rather than treated as "match everything", which would delete the lot. Pass protect to keep named storages regardless.

Notes on fragility

The Actors are not equally durable, and it's worth knowing which is which:

  • jobs/ats-boards is the most durable. It reads documented JSON APIs; a break would be a provider changing its public contract.

  • web/site-crawler and web/rag-browser are moderately durable. Search engines reshape their result markup, which is why search tries more than one and says in the log which one answered.

  • maps/google-maps is the least durable, by a distance. Google generates every class name in a Maps card, so parsing works off the card's rendered text instead — but Google still varies what it renders. Review counts, for example, appear on some cards and not others; absent means null, never zero. The parser is in parse.ts, separate from the browser driving, so it can be unit-tested against captured card text.

Limits, stated plainly

  • Free for sites that don't fingerprint hard. Google Maps at volume will need residential IPs; that is a PROXY_URL change, not a rewrite.

  • maps/google-maps needs a browser. Playwright's bundled Chromium does not support macOS 12, so the launcher prefers your installed Google Chrome and falls back to bundled Chromium elsewhere.

  • Free search has no SLA. Querying an engine from one IP without a key draws intermittent 429s; that is why there is a fallback chain rather than one engine.

  • Run history is in memory and is lost on restart. Scraped results are on disk and are not.

  • Respect the terms of service of whatever you point this at.

What is and isn't verified

Worth being precise about, since "it's built" and "it's known to work" are different claims:

Verified end to end, against the live internet: the MCP wire contract over both stdio and HTTP; web/site-crawler (single and multi-page, with link following); jobs/ats-boards against live Greenhouse, Lever, Ashby and SmartRecruiters boards; web/rag-browser search and direct fetch; maps/google-maps driving a real browser; the Apify actor-id aliases; and the LinkedIn gate refusing to run.

Unit tested: the six ATS normalizers, the Google Maps card parser against captured real card text, and the LinkedIn daily budget.

Not verified: the Workable adapter (no populated Workable board was reachable — marked verified: false in providers.ts), and the Docker image (never built; the base tag was confirmed to exist upstream, nothing more).

Note that the real bugs found so far were caught by using the tool, not by the test suite: a second crawl silently returning nothing, and hybrid roles being reported as remote. The suite now covers both.

License

MIT

Available Tools

26 tools
abort-actor-runAbort Actor runA

Stop a run that is still in progress. Items already collected are kept.

ParametersJSON Schema
NameRequiredDescriptionDefault
runIdYes

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the responsibility for behavioral disclosure. It does this well by stating both the precondition ('still in progress') and the key side effect ('Items already collected are kept'). It doesn't cover every edge case such as idempotence or the terminal run status, but the most decision-relevant behavior is disclosed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences with no filler. The action is front-loaded, and the critical side effect about preserving collected items is stated immediately.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter tool with no output schema, the description covers the essential action, precondition, and consequence. It could be more complete by noting what happens when the run is not in progress or whether the abort is final, but those are minor gaps for this simple operation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema provides only a required string runId with no description, and the description doesn't explicitly define runId. However, the tool name and the phrase 'a run' make it inferable that runId identifies the run to abort, so the parameter is usable but not directly enriched.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Stop') and resource ('a run that is still in progress'), making the tool's purpose unmistakable. It also distinguishes itself from read-only siblings like get-actor-run and from the opposite operation resurrect-actor-run.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clearly conveys when to use the tool: when a run is in progress and needs to be stopped. It doesn't explicitly name alternatives or exclusions, but the 'still in progress' precondition provides enough context to avoid most misuse.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

call-actorCall an ActorA

Run an Actor and return its results. The shape of input depends on the Actor — read it from fetch-actor-details first. Returns a preview of the items plus a datasetId for retrieving the rest via get-dataset-items. A run that partially fails still returns what it collected; check get-actor-log for detail.

ParametersJSON Schema
NameRequiredDescriptionDefault
actorYesActor id, e.g. "jobs/ats-boards".
inputNoThe Actor's input object.
waitSecsNoHow long to wait for the run before returning. If it is still going, you get the runId and can poll get-actor-run, then read results with get-dataset-items. The default sits under the 60-second request timeout most MCP clients use — set 0 to start a long crawl and return immediately.
timeoutSecsNo
memoryMbytesNoHeap ceiling for the Actor process. Raise it for a large crawl; a run that exceeds it is killed rather than exhausting the machine.

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations available, the description carries the behavioral disclosure burden. It does well by revealing partial-failure semantics, the fact that only a preview is returned, and that the datasetId is needed for full retrieval. It does not mention cost or that the run may keep executing after waitSecs, but the waitSecs schema covers the polling behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact, with no filler. It front-loads the core operation, then adds the most important caveats and follow-up steps in clear, short sentences.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite having no output schema or annotations, the description covers the essential workflow: input dependency, return shape, retrieval path, and failure behavior. Combined with the detailed waitSecs schema, an agent has enough context to call the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description adds real semantic value for the `input` parameter by warning that its shape depends on the Actor and pointing the agent to fetch-actor-details. The schema already describes most other parameters well, though `timeoutSecs` remains undocumented in both the description and the schema, which prevents a top score.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the operation: 'Run an Actor and return its results.' It also distinguishes the tool from siblings like run-actor-task and get-actor-run by describing the return contract (preview plus datasetId). The explicit link to fetch-actor-details reinforces what this tool is and is not.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives concrete workflow guidance: read fetch-actor-details first, retrieve the rest via get-dataset-items, and check get-actor-log for partial failures. It does not explicitly contrast call-actor with run-actor-task or state when scheduling would be a better fit, so it stops short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

clean-up-storageClean up old storageA

Delete datasets and stores older than keepDays. Every run creates a dataset, so these accumulate; configuration stores are never removed. Use dryRun first.

ParametersJSON Schema
NameRequiredDescriptionDefault
matchNoRegular expression on the storage name. When given, only matching storages are considered and the age check is waived — useful for clearing throwaway storages created the same day as real ones.
dryRunNo
keepDaysNo

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description itself must convey risk. It does say this deletes data and that config stores are never removed, and it points to dryRun as a safe first step. However, it never states that non-dryRun deletion is permanent or irreversible, nor what dryRun actually produces, leaving a partial picture.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, no filler. The action is front-loaded, the rationale is one clause, and the safety instruction is last. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive, 3-parameter tool with no output schema, this is adequate but not complete: it covers why to clean, what is protected, and a dry-run-first guideline. It leaves open what 'older than' is measured against, whether deletion is recoverable, and what result the tool returns, especially in dryRun mode.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema covers only 1 of 3 parameters (match). The description adds meaning for keepDays ('older than') and introduces dryRun as a safety flag, but it does not explain dryRun's behavior when true/false; match's regex semantics are the schema's contribution. This is partial compensation for the 33% coverage gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first sentence names a concrete operation ('Delete'), a specific resource scope ('datasets and stores'), and a condition ('older than keepDays'). The title and sibling list confirm this is the storage cleanup tool, so an agent can select it without confusing it with actor/task tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

States 'Use dryRun first,' an explicit operating rule. It also gives the motivating scenario ('every run creates a dataset, so these accumulate') and a safety boundary ('configuration stores are never removed'). It doesn't spell out when-not-to-use, but no sibling tool competes for this job.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

create-actor-taskCreate or update an Actor taskB

Save a named Actor configuration so a search worth repeating gets an id instead of a body of JSON to retype. Re-using an existing id updates it.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesLowercase letters, digits and hyphens, e.g. "remote-growth-roles".
actorYesActor id, e.g. "jobs/ats-boards".
inputNo
titleNo

TDQS

B3.2/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It discloses the upsert-like behavior ('Re-using an existing id updates it'), but omits important behavioral details such as whether fields are merged or replaced, permission requirements, side effects, or what the call returns.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is short and front-loaded with the core purpose. The second sentence efficiently captures the update behavior, though the 'search worth repeating' phrasing is slightly informal and could be more precise.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given four parameters, no annotations, no output schema, and low schema coverage, the description leaves substantial gaps: it does not explain all parameters, required fields, return values, or edge cases around updating an existing task. It only covers the basic save/update behavior.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 50%, and the description does not explain the undocumented 'input' or 'title' parameters. It vaguely refers to 'a body of JSON to retype', which hints at the input parameter, but adds no concrete semantics for required parameters or defaults.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses the specific verb 'Save' with a named Actor configuration as the resource, and clarifies that reusing an existing id updates it. This clearly differentiates the tool from siblings like run-actor-task, call-actor, and delete-actor-task.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'a search worth repeating' implies the tool is meant for saving reusable configurations, but it does not explicitly state when to use this tool versus run-actor-task or call-actor, nor does it mention exclusions or alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

create-scheduleCreate or update a scheduleB

Run an Actor or a saved task on a cron schedule, executed by the server itself. Give either actor with inline input, or task. Re-using an id updates it.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesLowercase letters, digits and hyphens.
cronYesStandard 5-field cron, e.g. "0 */6 * * *".
taskNo
actorNo
inputNo
titleNo
enabledNo
timezoneNoIANA zone, e.g. "Asia/Kolkata". Defaults to UTC.

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations available, the description carries the burden of behavioral disclosure. It reveals that the tool schedules recurring server-side execution and that reusing an id updates the existing schedule, which is valuable. It does not disclose side effects of updates or any other operational details, but the core mutation behavior is visible.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and front-loaded. Each sentence contributes meaningful information: the scheduling behavior, the actor/task choice, and the upsert semantics. There is no redundancy or filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

This is a mutation tool with no annotations, no output schema, and low parameter coverage, yet the description omits important operational details such as the exact update semantics, response behavior, and how settings like timezone or enabled apply. It provides a useful core but is not complete enough for an agent to confidently handle edge cases.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is only 38%, so the description must compensate. It does add meaning by explaining the mutually exclusive actor/input versus task options and the id update behavior. However, it leaves several parameters such as title, enabled, and timezone unexplained, and the description only partially compensates for the low schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's core purpose: 'Run an Actor or a saved task on a cron schedule, executed by the server itself.' It also clarifies the create-vs-update behavior with 'Re-using an id updates it.' However, it does not explicitly distinguish this tool from related siblings like run-actor-task or create-actor-task.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage context by specifying server-side scheduled execution and the choice between 'actor' with inline 'input' or 'task'. It does not state when to prefer this tool over alternatives or provide exclusions, leaving some inference required.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

delete-actor-taskDelete an Actor taskA

Remove a saved task. The runs and datasets it produced are kept.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYes

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden of behavioral disclosure. It usefully explains that runs and datasets produced by the task are preserved, which is an important non-obvious side effect. However, it does not mention irreversibility, required permissions, or what kind of response to expect.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences with no redundant wording. The action is front-loaded, and the second sentence earns its place by clarifying a meaningful side effect that an agent would otherwise not know.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a low-complexity one-parameter delete tool with no output schema and no annotations, the description covers the core action and the most important behavioral consequence. It is concise and sufficient for an agent to understand what will happen, though it omits return-value and permission details.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema declares one required string 'id' with no description, and schema description coverage is 0%, so the description must compensate. It indirectly indicates that 'id' refers to the saved task being removed, which is sufficient given the single simple parameter, but it does not explicitly document the parameter or its origin/format.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Remove') and resource ('a saved task'), and immediately clarifies the scope by stating that runs and datasets are kept. This distinguishes it from sibling tools like delete-schedule or cleanup operations, making the tool's purpose immediately clear.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The usage context is only implied: use this when you want to remove a saved actor task. It does not explicitly contrast with siblings such as get-actor-task or run-actor-task, nor does it state when not to use the tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

delete-scheduleDelete a scheduleA

Remove a schedule. Runs it already produced are kept.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYes

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the burden of behavioral disclosure. It usefully states that runs already produced are kept, which is a meaningful side-effect that an agent should know before deleting. It omits less critical details like error handling, but the main behavior is transparent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two short sentences with no filler. The primary action is front-loaded, and the second sentence adds valuable nuance about retained runs without extra words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple one-parameter deletion tool, the description covers the action and the most important behavioral consequence. It does not mention error behavior or prerequisites, but the tool's low complexity makes this acceptable.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, and the description does not explain the id parameter at all. An agent must infer that id refers to the schedule identifier. This is a minor gap because there is only one required parameter with a self-explanatory name, but the description adds no parameter-level meaning.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Remove a schedule') and the resource, immediately distinguishing it from sibling tools like delete-actor-task. The added sentence about produced runs being kept makes the scope even more precise.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The intended context is clear: use this when a schedule needs to be removed. It does not explicitly discuss when not to use it, but sibling tools operate on different resources, so the intended use is unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

fetch-actor-detailsFetch Actor detailsA

Get the full JSON Schema for an Actor's input, plus its description. Call this before call-actor so you know which fields are required and how they are named.

ParametersJSON Schema
NameRequiredDescriptionDefault
actorYesActor id, e.g. "jobs/ats-boards".

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations present, the description carries the full burden of behavioral disclosure. It conveys a read operation ('Get') and describes the return value, but it does not explicitly state that the operation is side-effect-free, mention auth requirements, or outline error behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, each earning its place: the first defines what the tool returns, the second gives actionable sequencing advice. There is no redundant or filler content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple one-parameter introspection tool, the description covers what is returned and the correct moment to call it. The lack of an output schema is compensated by the description naming the return contents. Minor gaps around side-effects and errors do not materially impair an agent's ability to invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The sole parameter is fully documented in the input schema ('Actor id, e.g. "jobs/ats-boards"'), and schema description coverage is 100%. The description adds no new meaning to the parameter, so it sits at the baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Get') and a precise resource ('the full JSON Schema for an Actor's input, plus its description'). It also differentiates itself from the sibling call-actor by positioning itself as the necessary precursor.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says 'Call this before call-actor so you know which fields are required and how they are named,' giving clear when-to-use guidance with a rationale. It does not, however, name conditions where this tool should not be used or point to alternatives beyond call-actor.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get-actor-logGet Actor run logA

Read the log of a run. This is where an Actor reports per-board or per-page failures that did not fail the run as a whole — check it when a run succeeded but returned fewer items than you expected.

ParametersJSON Schema
NameRequiredDescriptionDefault
tailNoReturn only the last N lines.
runIdYes

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the behavioral transparency burden. It adds meaningful context by revealing that the log contains non-fatal per-board or per-page failures, not just a generic log dump. This helps the agent interpret partial-success scenarios, though it doesn't describe output format or access requirements.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no filler. It front-loads the core action, then immediately provides the key use case and the nature of the log content. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is simple with two parameters and no output schema. The description explains what the log contains and when to check it, which is sufficient for an agent to decide to call it. It doesn't detail the return format, but for a log-reading tool with a tail parameter, the expected line-based output is reasonably inferable.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 50%: the tail parameter is described in the schema, but runId is not. The description does not compensate by explaining runId or adding meaning to either parameter. It only implicitly refers to 'a run,' leaving the required parameter's semantics underspecified.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'Read the log of a run.' It further differentiates the tool by explaining the log contains per-board or per-page failures that did not fail the whole run, which clearly separates it from sibling run-focused tools like get-actor-run or abort-actor-run.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives an explicit use case: 'check it when a run succeeded but returned fewer items than you expected.' It clearly indicates when to use the tool, though it does not name alternatives or explicitly state when not to use it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get-actor-runGet Actor runA

Get the status, item count and dataset id of a previous run. Use this after call-actor to check whether a run succeeded, failed, or was aborted.

ParametersJSON Schema
NameRequiredDescriptionDefault
runIdYes

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description must carry the behavioral burden. 'Get' and 'status' convey a read-only polling operation and name the returned data points, but there is no statement about side effects, error behavior, or what happens for a runId that doesn't exist.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two focused sentences, with the resource and returned fields front-loaded and the usage guidance in the second sentence. Every word adds value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple one-parameter getter with no output schema, the description covers the returned fields (status, item count, dataset id), the trigger (after call-actor), and the decision it supports. It lacks only minor details such as runId provenance or format, but is otherwise complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema is just a runId string with zero description coverage, and the description compensates only indirectly by calling it a 'previous run' after call-actor. This tells the agent that runId identifies an earlier run, but does not specify where to obtain it or any expected format.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'Get the status, item count and dataset id of a previous run.' The phrase 'previous run' and the focus on run-level output distinguish it from list, log, and abort sibling tools, and tying it to call-actor clarifies its role.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly directs use to 'after call-actor' for checking success, failure, or abort, giving a clear trigger condition. It does not mention exclusions or point to alternatives like get-actor-run-list, so it falls short of a full routing guide.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get-actor-run-listList Actor runsA

List recent Actor runs in this server session, newest first.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It does disclose ordering and session/recency scoping, but it does not describe pagination/truncation behavior, auth requirements, or what the returned list contains; 'list' does weakly imply a read-only operation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The entire description is one short sentence that front-loads the action and immediately gives the key constraints (recent, session-scoped, newest first). There is no redundant or filler text.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter list tool this is mostly complete: it states scope, ordering, and resource. The main gap is that with no output schema, the agent is not told what fields each run entry will contain, though 'list' makes the general return shape predictable.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With schema_description_coverage at 0%, the description needed to compensate by explaining the 'limit' parameter, but it does not mention it at all. The schema's default/min/max provide some information, yet no semantic meaning is added by the prose.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific action ('List'), resource ('Actor runs'), and scope ('recent... in this server session') plus ordering ('newest first'). This clearly tells an agent what the tool does and how it differs from singular tools like get-actor-run.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrasing implies this is for browsing recent runs rather than querying or fetching a specific run, but it never explicitly names alternatives such as search-actors or get-actor-run. No when-not conditions are given, leaving the routing decision somewhat to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get-actor-taskGet Actor tasksA

List saved tasks, or fetch one by id.

ParametersJSON Schema
NameRequiredDescriptionDefault
idNo

TDQS

A3.7/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full behavioral burden. It conveys that the tool is read-only, but does not disclose return format, pagination, ordering, error behavior, or any permissions or side effects. For a tool with no structured annotations, this is a notable gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single efficient sentence that front-loads the primary behavior and states the alternative in a few words. No filler or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read tool with one optional parameter, the description captures the main calling modes. However, with no output schema and no annotations, it omits return value expectations and any list-related behavior such as pagination or result structure, which an agent would need for reliable invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, but the description compensates by explaining the id parameter's meaning: invoking with an id fetches one saved task, while omitting it lists tasks. This adds meaningful behavioral semantics beyond the bare 'string' property in the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'List saved tasks, or fetch one by id.' This clearly identifies the tool as a retrieval operation for actor tasks and distinguishes it from siblings like delete-actor-task, create-actor-task, and run-actor-task, which are not retrieval operations.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies when to use the tool: when you need to list saved tasks or retrieve one by id. However, it does not explicitly state when not to use it or mention alternative tools, leaving the comparison to the agent to infer.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get-datasetGet dataset metadataA

Get the item count of a dataset without reading the items themselves.

ParametersJSON Schema
NameRequiredDescriptionDefault
datasetIdYes

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the burden. It discloses a useful behavioral trait: the operation does not read the underlying items, implying it is lightweight and non-invasive. However, it does not describe return behavior, error cases, authorization requirements, or any other side effects, leaving much undisclosed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single focused sentence that front-loads the core purpose ('item count') and adds the key differentiator without any wasted words. It earns its place and remains memorable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter tool, the description gives the essential function, but it lacks an output schema and does not describe what the response contains (e.g., a bare integer or an object with a count field). It also does not mention sibling relationships or edge cases, leaving some uncertainty for an agent, though the overall complexity is low.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate for parameter documentation. The only parameter, datasetId, is self-explanatory from its name and the resource context, and the description's mention of 'dataset' loosely ties to it. Still, no format, validation, or usage detail is added beyond the schema, but the parameter is simple enough that this is acceptable.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Get'), a resource ('dataset'), and a precise scope ('item count'), and distinguishes the tool from siblings like get-dataset-items by noting it does not read the items. However, the title 'Get dataset metadata' implies a broader purpose than the description's narrow 'item count' focus, creating mild ambiguity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'without reading the items themselves' implies that this tool is appropriate when only a count is needed, and not when item content is required. But it does not name alternatives such as get-dataset-items or get-dataset-schema, nor does it state explicit when-to-use or when-not-to-use conditions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get-dataset-itemsGet dataset itemsA

Page through the results of a previous Actor run. Use the datasetId returned by call-actor. Use fields to project only the keys you need — this matters when items contain long text such as page content or job descriptions.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
fieldsNoOnly return these top-level keys.
offsetNo
datasetIdYes

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden for behavioral disclosure. It communicates that the operation is a read/pagination action and adds a useful performance-oriented note about using fields for long-text items. However, it does not describe the response shape, empty-result behavior, or any paging semantics beyond the schema defaults.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences: the first states the operation and the datasource, the second gives actionable projection advice. No filler, and the most important usage context is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple paginated read tool without an output schema, the description is nearly sufficient: it names the source of datasetId, explains pagination, and warns about large payloads. The main gap is that it never explicitly states the return format, though 'page through' and 'items' strongly imply a paginated list of objects.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 25%, so the description must compensate. It does add real meaning to datasetId ('returned by call-actor') and fields ('project only the keys you need'). But limit and offset are not semantically explained in the description; the agent must rely on schema defaults and names to infer their role.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Page through') and resource ('results of a previous Actor run'), clearly separating this from sibling tools that manage actor runs or datasets themselves. It also grounds the datasetId in the output of call-actor, which makes the tool's role in the workflow unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear context: this tool is for paging through items after an Actor run, and the datasetId should come from call-actor. It does not explicitly name alternatives or state when not to use this tool, so it stops short of a 5, but the intended usage is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get-dataset-schemaGet dataset schemaA

Infer the shape of a dataset from a sample of its items. Use this to learn which fields exist before requesting them via fields, instead of pulling whole items to find out.

ParametersJSON Schema
NameRequiredDescriptionDefault
datasetIdYes
sampleSizeNo

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full disclosure burden. It adds useful behavioral context: the schema is inferred from a sample (implying it may be approximate) and the tool is intentionally cheaper than fetching full items. However, it does not describe the output format, warn that sampling may miss rare fields, or mention any error conditions or caveats about inference reliability.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, both load-bearing. The first states the function, the second states the use case and the alternative approach to avoid. No filler, no repetition of schema information, and the most important information (what it does) is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a low-complexity tool (2 params, 1 required) the core is covered. But with no output schema and no annotations, the description could usefully state what the returned schema contains (e.g., field names and types) and explicitly note that a sample-based schema may be incomplete for heterogeneous datasets. These gaps leave the agent partially guessing about the result's reliability and shape.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It does add meaning: 'from a sample of its items' explains the role of sampleSize, and the dataset context clarifies datasetId. However, it never explicitly ties sampleSize to the sampling behavior or explains the accuracy/cost tradeoff, leaving the agent to infer the parameter's impact from the default and bounds in the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('infer'), a clear resource ('the shape of a dataset'), and a concrete mechanism ('from a sample of its items'). It differentiates itself from siblings: the phrase 'instead of pulling whole items to find out' implicitly distinguishes it from get-dataset-items, and 'requesting them via fields' shows it's a lightweight discovery step rather than a data-fetching or metadata-fetching tool like get-dataset.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives an explicit when-to-use: 'learn which fields exist before requesting them via fields'. It also signals the negative case ('instead of pulling whole items to find out'), which steers the agent away from the heavier alternative. However, it never names the alternative tool (get-dataset-items) or states a clear when-not-to-use condition, so it stops just short of the explicit-exclusion bar.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get-follow-upsApplications worth chasingA

Lists roles applied to that have gone quiet, longest wait first. Anything that has had a response — including a rejection — is excluded, and an application already chased inside the window is not chased again.

ParametersJSON Schema
NameRequiredDescriptionDefault
afterDaysNoSilence before a chase is due.

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the behavioral burden itself. It discloses the key behaviors: only unresponsive and unchased applications are included, rejection responses count, and results are sorted by longest wait first. It implies a read-only list operation, though it does not detail output fields, pagination, or access requirements.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One dense sentence front-loads the purpose, then adds ordering, then exclusion rules. Every clause earns its place and there is no redundant or filler language.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple tool with one optional, fully documented parameter and no output schema, the description is complete enough for correct invocation. It specifies what is listed, the ordering, and the exact filter conditions, leaving no critical gap for an agent to guess at.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description adds operational meaning by tying afterDays to 'gone quiet' and to the 'window' for already-chased applications, helping clarify the parameter's real-world effect beyond the schema's single-line description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific operation: listing roles applied to that have gone quiet, with explicit ordering ('longest wait first') and clear exclusion criteria. This is far more specific than the generic title and distinguishes the tool from the mutation-focused sibling tools like record-follow-up and record-response.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clearly communicates when this tool is appropriate: return applications with no response and no prior chase within the window. It gives solid inclusion/exclusion criteria, but it never names alternative tools or explicitly says 'use this instead of X', so it stops short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get-key-value-store-recordGet key-value store recordA

Read a single record from a key-value store by key.

ParametersJSON Schema
NameRequiredDescriptionDefault
keyYes
storeIdNodefault

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description must establish the operation's nature, and it does make the non-mutating read behavior explicit. It does not describe missing-key behavior, error semantics, or the shape of the returned record, but the operation is simple enough that these are modest gaps.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The definition is a single front-loaded sentence with no filler. Every word contributes to the action, object, and lookup criterion.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read operation with only two parameters and no output schema, the core invocation information is present: read a single record by key. The main remaining gap is the unmentioned storeId parameter and expected behavior when the key is absent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description needed to compensate for both parameters. It confirms that 'key' is the lookup key but never explains 'storeId', its default, or how it selects the target store.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb ('Read'), a precise resource ('single record from a key-value store'), and the lookup mechanism ('by key'). This cleanly separates it from the sibling tools, which target actors, datasets, schedules, and tasks rather than key-value stores.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The action is clearly scoped to fetching one record by key, and none of the listed siblings perform a comparable key-value read, so mis-selection is unlikely. It stops short of explicitly stating when not to use the tool, but no competing alternative is present.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get-marked-jobsList marked jobsA

List roles recorded as applied or ignored, newest first.

ParametersJSON Schema
NameRequiredDescriptionDefault
markNoOmit to list both.
limitNo

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the burden of behavioral disclosure. It clearly indicates a read-only listing operation, defines the set of items returned, and adds the 'newest first' ordering behavior. It does not discuss pagination, errors, or auth, but for a simple list tool this is reasonably transparent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single front-loaded sentence with no filler. Every element adds value: the action, the filtered scope, and the ordering. It is appropriately sized for the tool's simplicity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple two-parameter list tool, the description covers core selection and invocation needs: what is listed, the filter values, and the ordering. However, with no output schema, it does not describe the shape of the returned roles, and it offers no sibling differentiation or limit semantics. The description is adequate but not complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 50%: the 'mark' parameter is well documented in the schema with 'Omit to list both', and the description reinforces the applied/ignored meanings. The 'limit' parameter has no semantic description in the schema or tool description beyond its name and constraints, so the description only partially compensates.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('List') and a precise resource ('roles recorded as applied or ignored'), directly matching the tool's purpose. It also adds the 'newest first' ordering, making the behavior clear. The mark filter distinguishes this from sibling list-like tools such as get-follow-ups.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The intended use is implied: call this tool to list roles marked as applied or ignored. However, there is no explicit guidance about when not to use it or which sibling tool should be preferred instead, such as get-follow-ups or search-related tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get-schedulesList schedulesA

List schedules with their next and last run times.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden of disclosing behavior. 'List' implies a read-only operation and the return fields are named, but it does not mention side-effect guarantees, pagination, or what exactly constitutes a schedule. This is adequate but not rich.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence, front-loaded, with no filler or redundancy. Every word adds meaning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter, no-output-schema list tool, this description is nearly complete: it names the resource and the two key fields returned. Ordering and pagination are left unspecified, but those are minor for a simple listing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so the baseline is 4. The description appropriately does not invent parameters and focuses on the returned data instead.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('List') and resource ('schedules') and specifies the returned fields (next and last run times). This clearly separates it from mutation siblings like create-schedule and delete-schedule.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is given about when to use this tool instead of alternatives. The sibling list includes create-schedule and delete-schedule, but the description does not explicitly state that this is the read-only listing option.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

mark-jobMark a job as applied or ignoredA

Record that you have applied to a role or dismissed it. Marked roles stop appearing in future digests, which is what turns the digest from a feed into a working list. Accepts several URLs at once.

ParametersJSON Schema
NameRequiredDescriptionDefault
markYes
noteNoOptional label kept alongside the mark.
urlsYesJob URLs, as shown in the digest.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

There are no annotations, so the description carries the behavioral burden. It discloses a persistent side effect ('Marked roles stop appearing in future digests') and a batching behavior ('Accepts several URLs at once'). It does not mention reversibility or overwrite behavior, but it is transparent about the main outcome.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences, each contributing: the action, the behavioral consequence, and the multi-URL capability. There is no fluff or repetition of schema details.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the simple schema and no output schema, the description covers the action, the enum semantics, the key side effect, and the batching behavior. It is nearly complete for correct invocation; a return-value description would be nice but is not essential here.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 67%, so the schema already documents urls and note. The description adds meaning to the mark enum by equating the values with 'applied ... or dismissed' and reinforces urls as a multi-item input, but it does not substantially clarify the note parameter beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Record') and resource ('a role' / 'job'), and names the two possible outcomes: applied or ignored. It also distinguishes the tool by explaining that marked roles stop appearing in future digests, which separates it from siblings like get-marked-jobs and unmark-job.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear usage context: use it when you have applied to or dismissed a role, and the consequence is that the role leaves the digest. It does not explicitly name alternatives or exclusions, but the situation is unambiguous enough for an agent to know when to call it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

record-follow-upNote that you chasedA

Records that you followed up, so the same silence is not flagged again immediately.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlsYes

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

There are no annotations, so the description carries the full burden of behavioral disclosure. It clearly reveals that this is a state-changing operation and explains the observable consequence: the same silence will not be flagged again immediately. It does not mention idempotency or error handling, but the key side effect is disclosed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence communicates the action, target, and purpose with no wasted words. The most important information is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple tool with one required array parameter and no output schema, the description is largely sufficient: it states what is recorded and why. The main gaps are the implicit meaning of the urls parameter and the lack of guidance about related tools, but these are minor given the tool's low complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema only provides the parameter name and type, and schema description coverage is 0%. The description never explicitly defines what 'urls' should contain, though context implies it is the list of followed-up URLs. This is only partial compensation for a completely undocumented parameter.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Records'), identifies the resource (follow-ups on URLs), and explains the intended outcome: preventing the same silence from being flagged again. This gives a clear sense of what the tool does and how it differs from query-oriented siblings like get-follow-ups or record-response.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies the right context: call it after you have followed up and want to suppress an immediate re-flag. However, it does not explicitly name alternatives or state when not to use it, so the usage guidance is only implicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

record-responseRecord what an employer saidA

Note that an employer replied, rejected, invited you to interview or made an offer. Stops that application appearing in follow-ups.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlYes
responseYes

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the behavioral disclosure burden. It usefully reveals the non-obvious side effect that the application stops appearing in follow-ups. However, it does not clarify whether the action updates an existing record, is reversible, what happens on repeated calls, or what the return value indicates.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two short sentences with no redundant wording. It front-loads the core action and then states the important behavioral consequence, making it easy to scan and parse.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with no annotations, no output schema, and sparse input schema, the description leaves essential gaps. It does not explain what url should contain, when exactly to invoke the tool relative to follow-up records, or what the response/result of the call will be. The core idea is clear, but the agent cannot confidently invoke it correctly from this definition alone.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It does explain the meaning of the response parameter by enumerating the four categories. However, it gives no semantics for the required url parameter, leaving the agent without enough information to know what URL to provide.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action: recording an employer's response (replied, rejected, interview, offer) and ties it to a specific resource. It distinguishes itself from the sibling tool record-follow-up by focusing on the employer's response and by describing a concrete consequence for follow-up visibility.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies when to use it: after an employer has replied, rejected, invited, or offered. However, it does not explicitly state when not to use it, mention alternatives like record-follow-up, or provide any exclusions or prerequisites.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

resurrect-actor-runResurrect an Actor runA

Re-run a finished run with the same Actor and input, optionally with a longer timeout — the usual reason a run needs resurrecting. Creates a new run, so the original's results and diagnosis stay intact.

ParametersJSON Schema
NameRequiredDescriptionDefault
runIdYes
timeoutSecsNo

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden of behavioral disclosure. It explicitly says the operation creates a new run and that the original's results and diagnosis stay intact, which is important for an action that could otherwise be confused with modifying or deleting the original run.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, no filler, and the essential behavior and consequence are front-loaded. Every sentence contributes useful information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple two-parameter tool, the description covers purpose, behavior, and the main parameter use case. It lacks some edge-case guidance, such as what happens if the run is still active or whether only certain terminal states qualify, but overall it is sufficiently complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It does add meaning for timeoutSecs by framing it as 'optionally with a longer timeout,' and runId is implicitly tied to the 'finished run' being re-run. However, neither parameter is explicitly mapped to schema fields, leaving some inference required.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'Re-run a finished run with the same Actor and input.' It also clarifies the key distinction from related run tools by explaining that this operation creates a new run rather than modifying or resuming the original.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear context: use this when a run finished and needs to be re-run, usually to apply a longer timeout. It does not explicitly name sibling alternatives or state when not to use it, but the intended situation is clear enough for an agent to route correctly.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

run-actor-taskRun an Actor taskB

Run a saved task. Any fields given in input override the saved ones for this run only, so one task covers a family of similar searches.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYes
inputNoFields to override for this run.

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It usefully discloses that input overrides saved fields only for this run and is non-persistent, but it does not mention whether execution is synchronous or asynchronous, what the return value is, or that running a task consumes resources. These are important behavioral gaps.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no filler. The primary purpose is front-loaded, and the override behavior is stated in a compact, useful way.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema and no annotations, the description must cover more ground. It explains the core run semantics but omits the return format, asynchronous behavior, and what exactly the id identifies. For a side-effecting run tool, these omissions leave the agent with material uncertainty.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema describes the input parameter but not the id parameter. The description clarifies the override semantics for input, adding meaning beyond the schema, but leaves the id parameter implicit. With 50% schema coverage, the description partially compensates but does not fully close the gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Run a saved task') and the resource (an Actor task), and adds meaningful detail about input override behavior. It does not explicitly differentiate from siblings like call-actor or create-actor-task, so it stops short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The intended use is implied: run a task that was previously saved. There is no explicit guidance on when to use this tool versus alternatives such as call-actor or create-actor-task, nor any when-not-to-use conditions, so the agent has to infer the boundary from sibling names.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search-actorsSearch ActorsA

Search available Actors (scrapers and data collectors) by keyword. Returns each Actor's id, title and description. Start here when you need to extract data from the web. Pass an empty search to list everything available.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
searchNoKeywords, e.g. "job listings" or "crawl documentation".

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden. It discloses the return shape, the empty-search behavior, and clarifies the domain of Actors. It doesn't address possible pagination or matching semantics, but for a safe search operation this is reasonably transparent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences with no filler. The action, return value, use case, and special search behavior are all communicated efficiently, and the most important operational detail ('start here') is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple search/list tool, the description covers the main invocation concerns: what it searches, what it returns, and how to retrieve all entries. A small gap is that the effect of 'limit' on the result set is only implicit in the schema, and there is no mention of pagination even though no output schema exists.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already describes the 'search' parameter with examples, so the description's added context focuses on the empty-search case. The 'limit' parameter is left to schema constraints with no behavioral explanation, so the description partially compensates for the 50% schema coverage but doesn't fully close the gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states a specific verb ('Search'), a specific resource ('available Actors'), and defines Actors as 'scrapers and data collectors.' It also states the exact return fields (id, title, description), which distinguishes it from sibling tools like call-actor or fetch-actor-details.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit guidance on when to start here ('when you need to extract data from the web') and how to list everything ('pass an empty search'). It does not explicitly mention when not to use it or name alternative sibling tools, so it stops short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

unmark-jobRemove a job markA

Forget that a role was applied to or ignored, so it can appear again.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlsYes

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden and does state the core behavioral effect: the mark is removed and the job can surface again. It does not, however, disclose whether the action is irreversible, idempotent, or scoped to existing marks, leaving some behavior implicit.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, front-loaded sentence that uses the key verb at the start and packs purpose and effect without filler. Every word contributes value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is simple, but the description plus schema are thin: no output schema, no parameter documentation, and no relationship to mark-job or get-marked-jobs. It is minimally adequate but leaves an agent to infer input semantics and result expectations.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has 0% description coverage for the sole 'urls' parameter, and the description does not mention it at all. While the parameter name is somewhat self-explanatory, the description adds no meaning about URL format, what a valid target is, or how multiple URLs are handled.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a concrete verb ('Forget') with a specific resource (a job mark) and the observable effect ('so it can appear again'). It clearly distinguishes this from mark-job by describing the inverse state change.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Use is implied through the description: call this to make a previously applied-to or ignored job eligible again. However, there is no explicit when-to-use/when-not-to-use guidance or mention of sibling tools like get-marked-jobs, so the agent must infer the selection criteria.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. 26 tool updatesv0.1.0
    • First observedabort-actor-run
    • First observedcall-actor
    • First observedclean-up-storage
    • First observedcreate-actor-task
    • First observedcreate-schedule
    • First observeddelete-actor-task
    • First observeddelete-schedule
    • First observedfetch-actor-details
    • First observedget-actor-log
    • First observedget-actor-run
    • First observedget-actor-run-list
    • First observedget-actor-task
    • First observedget-dataset
    • First observedget-dataset-items
    • First observedget-dataset-schema
    • First observedget-follow-ups
    • First observedget-key-value-store-record
    • First observedget-marked-jobs
    • First observedget-schedules
    • First observedmark-job
    • First observedrecord-follow-up
    • First observedrecord-response
    • First observedresurrect-actor-run
    • First observedrun-actor-task
    • First observedsearch-actors
    • First observedunmark-job

TDQS

A3.6/5.0
Disambiguation4/5

Tools are grouped into clear clusters—actors, runs, tasks, datasets, schedules, and job tracking—and each tool targets a distinct resource and action. A few pairs like call-actor vs run-actor-task and mark-job vs record-response are somewhat close, but their descriptions clearly separate them.

Naming Consistency4/5

Most tools follow a lowercase hyphenated verb-noun pattern, which is readable and mostly predictable. There are minor inconsistencies such as fetch vs get, call vs run, clean-up vs delete, and list naming varies (get-actor-run-list vs get-actor-task vs get-schedules).

Tool Count2/5

At 26 tools, the set is over the 25-tool threshold and feels heavy for an agent to navigate. The actor, dataset, schedule, and job-tracking concerns are broad enough that the server may be trying to cover too much in one surface.

Completeness4/5

The set covers actor discovery, execution, run inspection, saved tasks, datasets, schedules, storage access, and job follow-up workflows with no obvious dead ends. Minor gaps exist: key-value store access is read-only and there is no individual dataset deletion, though clean-up-storage partially covers cleanup.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    A
    maintenance
    Remote MCP server for web scraping with anti-bot evasion. Provides stealth HTTP fetching, headless browser with Cloudflare bypass, CSS selectors, YouTube transcripts, and Markdown conversion.
    1
    MIT
  • A
    license
    B
    quality
    C
    maintenance
    Local MCP server providing web search, web scraping, YouTube metadata/subtitles/downloads, image generation (MFLUX on macOS), and Playwright CLI browser automation tools.
    15
    MIT

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/sahilrit/openactors'

If you have feedback or need assistance with the MCP directory API, please join our Discord server