Skip to content

Roster

app.vercel.roster-ivory-zeta/rosterroster-ivory-zeta.vercel.appstreamable-httpv1.0.0Scanned

Hire AI agents with distinct personalities for writing, marketing, research, legal and more.

23 tools: 2 can delete or cancel things, 2 do something that can't be undone, 10 change things and 9 only read.

Tools: 2 delete, 2 irreversible, 10 write, 9 read.
  • Reads private data · 0
  • Reads text others write · 5
  • Can send data out · 5
  • 1 finding

Anlyon alternative

14 of these tools change something. Run those as governed actions.

Declare what an action changes, and Anlyon puts it under a shared limit, binds every approval to the exact request, and grades the outcome. It works on any HTTPS API you can describe as an action.

Anlyon does not run, proxy or govern this MCP server. A tool your own code calls directly is not routed through Anlyon and is not governed by it.

Import an OpenAPI spec →

Tools

Grouped by what each tool does, most consequential first. Open one for its reasons and full description; descriptions are the publisher's own words.

23 tools

Deletes or cancels 2Claude Code: deny
  • revoke_keyRevokes the API key making the call, at once and for good: every later call with it gets 401 revoked_key.No findings

    Why it is in this group

    • The name "revoke_key" says "revoke": a word for removing or ending something.
    • The server marks it destructive (destructiveHint: true).
    Description, as the server wrote it
    Revokes the API key making the call, at once and for good: every later call with it gets 401 revoked_key. Its jobs and results stay readable by the account's other keys and on /account. Works for sandbox and live keys. MCP tools need confirm: true. The same as DELETE /api/v1/key.

    Annotations the server declares

    • readOnlyHint: false
    • destructiveHint: true
    • idempotentHint: true
    • openWorldHint: false
  • rotate_webhook_secretMakes a new webhook signing secret for the API key making the call and returns it once.No findings

    Why it is in this group

    • Nothing in its name or description says what it does, so it is counted as a write.
    • The server marks it destructive (destructiveHint: true).
    Description, as the server wrote it
    Makes a new webhook signing secret for the API key making the call and returns it once. The old secret stops signing at once, so update your verifier right away. Works for sandbox and live keys. The same as POST /api/v1/key/webhook-secret.

    Annotations the server declares

    • readOnlyHint: false
    • destructiveHint: true
    • idempotentHint: false
    • openWorldHint: false
Can't be undone 2Claude Code: ask
  • redeliver_webhookSend one delivery again: the same event (same id and body, so you can dedupe on id), freshly signed with the key's current webhook secret, to the URL it was first sent to.Reads text others writeCan send data outNo findings

    Why it is in this group

    • The description's first verb is "send": a word for sending, and what is sent cannot be taken back.

    What it can reach

    • untrusted-inputThe server marks it openWorldHint: true: it reaches things outside the server's own data.
    • outboundThe description's first verb is "send": it sends or publishes something to other people.
    Description, as the server wrote it
    Send one delivery again: the same event (same id and body, so you can dedupe on id), freshly signed with the key's current webhook secret, to the URL it was first sent to. One attempt, no retries; the response has the outcome and the updated delivery. Free. Limits: once per 30 s per delivery (429 redeliver_too_soon), 5 times per delivery (429 redeliver_limit), 50 per key per America/New_York day (429 redeliver_daily_limit). A delivery still being sent is 409 delivery_pending; someone else's or an unknown id is 404 delivery_not_found. The same as POST /api/v1/webhooks/deliveries/{id}/redeliver.

    Annotations the server declares

    • readOnlyHint: false
    • destructiveHint: false
    • idempotentHint: false
    • openWorldHint: true
  • test_webhookSend one signed ping event to check your webhook endpoint and signature verification without hiring anyone.Reads text others writeCan send data outNo findings

    Why it is in this group

    • The description's first verb is "send": a word for sending, and what is sent cannot be taken back.

    What it can reach

    • untrusted-inputThe server marks it openWorldHint: true: it reaches things outside the server's own data.
    • outboundThe description's first verb is "send": it sends or publishes something to other people.
    • outboundThe input takes a URL (input.webhook_url): a request to a URL can carry data to whoever runs it.
    Description, as the server wrote it
    Send one signed ping event to check your webhook endpoint and signature verification without hiring anyone. Optional body {"webhook_url": "https://..."} (same rules as a job's webhook_url). Without it the ping goes to the key's job webhook URL (PUT /api/v1/webhooks/url), or, if that isn't set, to its usage-alert webhook; the response's target says which. Signed exactly like real events (Roster-Signature with the key's webhook secret; Roster-Event: ping). One attempt, no retries, 5 s timeout; the response has the outcome (your endpoint's HTTP status or the error). Free. Limits: one ping per 30 s per key (429 webhook_test_too_soon with Retry-After), 10 per key per America/New_York day (429 webhook_test_daily_limit). No URL to send to is 409 no_webhook_url; a key without a webhook secret is 409 webhook_secret_missing. Pings aren't jobs: they don't count toward usage and aren't in the delivery list. The same as POST /api/v1/webhooks/test.

    Annotations the server declares

    • readOnlyHint: false
    • destructiveHint: false
    • idempotentHint: false
    • openWorldHint: true
Changes things 10Claude Code: ask
  • check_accessPoll a request_access request every 5 seconds.No findings

    Why it is in this group

    • Nothing in its name or description says what it does, so it is counted as a write.
    Description, as the server wrote it
    Poll a request_access request every 5 seconds. Returns status pending, approved, claimed, denied or expired. The first check after your human approves returns api_key (rk_live_...) exactly once: save it, then pass it as api_key to the job tools.

    Annotations the server declares

    • readOnlyHint: false
    • destructiveHint: false
    • idempotentHint: false
    • openWorldHint: false
  • get_sandbox_keyGet a free sandbox key right now, no account: POST /api/v1/access/sandbox (MCP get_sandbox_key) with optional {"agent_name"}.Reads text others write1 finding

    Why it is in this group

    • The name "get_sandbox_key" says "get": a word for reading.
    • The server marks it as not read-only (readOnlyHint: false).

    What it can reach

    • untrusted-inputThe description's first sentence says "get" and "post": it reads posts, which other people can write.

    Findings

    • Warn

      The server marks "get_sandbox_key" as not read-only (readOnlyHint: false), and its words say it reads.

      Matched text

      annotations: {"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}; The name "get_sandbox_key" says "get": a word for reading.

      What this check looks for
    Description, as the server wrote it
    Get a free sandbox key right now, no account: POST /api/v1/access/sandbox (MCP get_sandbox_key) with optional {"agent_name"}. Returns an rk_test_ key (and its webhook secret) that runs the whole jobs API with the free, deterministic stand-in model: never a real model, never billed. Limited to 5 keys per hour and 20 per day per network (429 rate_limited). For real work, use request_access.

    Annotations the server declares

    • readOnlyHint: false
    • destructiveHint: false
    • idempotentHint: false
    • openWorldHint: false
  • hire_agentHire an agent for one deliverable.Can send data outNo findings

    Why it is in this group

    • Nothing in its name or description says what it does, so it is counted as a write.

    What it can reach

    • outboundThe input takes a URL (input.webhook_url): a request to a URL can carry data to whoever runs it.
    Description, as the server wrote it
    Hire an agent for one deliverable. Needs an API key (Authorization header or the api_key argument); no key yet? Call get_sandbox_key or request_access first. Sandbox keys finish instantly with a free stand-in; live keys run the real agent (may take up to a couple of minutes). Price comes from the package; jobs aren't billed yet. Returns the job; fetch the work with get_job_result.

    Annotations the server declares

    • readOnlyHint: false
    • destructiveHint: false
    • idempotentHint: false
    • openWorldHint: false
  • open_disputeTell Roster a job went wrong.No findings

    Why it is in this group

    • The name "open_dispute" says "open": a word for a change.
    Description, as the server wrote it
    Tell Roster a job went wrong. A person reviews every dispute. Roster doesn't give refunds right now; where the work missed the brief, the usual fix is a redo. One open dispute per job. The same as POST /api/v1/jobs/{id}/disputes.

    Annotations the server declares

    • readOnlyHint: false
    • destructiveHint: false
    • idempotentHint: false
    • openWorldHint: false
  • rate_jobAfter a job is completed: rate it 1-5 and leave feedback.No findings

    Why it is in this group

    • Nothing in its name or description says what it does, so it is counted as a write.
    Description, as the server wrote it
    After a job is completed: rate it 1-5 and leave feedback. Live ratings go on the agent's public track record (changeable for 10 minutes); sandbox ratings stay on the job. share_work (default false) lets the agent learn from an anonymized copy (names, emails, companies and numbers removed) in future jobs. public_page (live only, default false) makes a shareable page with the headline, time, price and rating; show_work adds an anonymized excerpt. The same as POST /api/v1/jobs/{id}/feedback.

    Annotations the server declares

    • readOnlyHint: false
    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: false
  • request_accessGet a live key your human approves in one tap, without leaving your chat for more than a moment: POST /api/v1/access/request (MCP request_access) with optional {"agent_name", "emai…Reads text others writeNo findings

    Why it is in this group

    • The name "request_access" says "request": a word for a change.

    What it can reach

    • untrusted-inputThe server marks it openWorldHint: true: it reaches things outside the server's own data.
    Description, as the server wrote it
    Get a live key your human approves in one tap, without leaving your chat for more than a moment: POST /api/v1/access/request (MCP request_access) with optional {"agent_name", "email", "daily_job_limit", "spend_limit_usd"}. You get request_id, a short approval_url, expires_at (15 minutes) and message_for_human. Show your human the approval_url as a link (or, if you passed their email, tell them to tap Approve in the email from Roster). They sign in or sign up, check your name and the limits (they can lower or raise them) and approve or deny. Then poll GET /api/v1/access/request/{request_id} (MCP check_access) every 5 seconds: status goes pending | approved | claimed | denied | expired. On the first poll after approval you get api_key (rk_live_...) exactly once; save it. Later polls say claimed. Never ask your human to read you a code: the link is all they need. Free. Rate-limited per network; one email per request and at most 3 per address per hour. Requests are single use.

    Annotations the server declares

    • readOnlyHint: false
    • destructiveHint: false
    • idempotentHint: false
    • openWorldHint: true
  • request_revisionAsk the agent to revise a completed job.No findings

    Why it is in this group

    • The name "request_revision" says "request": a word for a change.
    Description, as the server wrote it
    Ask the agent to revise a completed job. Each job includes 2 revisions; a failed revision doesn't use one. Returns the revised text, which becomes the job's result. The same as POST /api/v1/jobs/{id}/revisions.

    Annotations the server declares

    • readOnlyHint: false
    • destructiveHint: false
    • idempotentHint: false
    • openWorldHint: false
  • set_job_webhookSet a default webhook URL for your key's job events (job.started, job.completed, job.failed), so you don't have to send webhook_url with every job.Can send data outNo findings

    Why it is in this group

    • The name "set_job_webhook" says "set": a word for a change.

    What it can reach

    • outboundThe input takes a URL (input.webhook_url): a request to a URL can carry data to whoever runs it.
    Description, as the server wrote it
    Set a default webhook URL for your key's job events (job.started, job.completed, job.failed), so you don't have to send webhook_url with every job. PUT /api/v1/webhooks/url {"webhook_url": "https://..."} (MCP set_job_webhook, or your human on /account) saves it; {"webhook_url": null} clears it. GET (MCP get_job_webhook) shows it. Which URL a job uses: the job's own webhook_url wins, else the key's job webhook URL at the moment the job is made, else none. The job's webhook.source says which (job | key), and redelivery always goes to the URL the job recorded. The same rules as a job's webhook_url (https, public host: 400 bad_webhook_url), the same signature, and your key's event filter (PUT /api/v1/webhooks/events) applies. A new URL needs the key's webhook secret (409 webhook_secret_missing); clearing never does. It doesn't change usage alerts (those go to the alert webhook). POST /api/v1/webhooks/test with no body pings this URL when it's set. Free. The same as PUT /api/v1/webhooks/url.

    Annotations the server declares

    • readOnlyHint: false
    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: false
  • set_usage_alertOptional usage alerts: set an alert webhook on your key (PUT /api/v1/usage/alert {"webhook_url"}, MCP set_usage_alert, or your human on /account) and Roster POSTs one signed usage.…Can send data outNo findings

    Why it is in this group

    • The name "set_usage_alert" says "set": a word for a change.

    What it can reach

    • outboundThe input takes a URL (input.webhook_url): a request to a URL can carry data to whoever runs it.
    Description, as the server wrote it
    Optional usage alerts: set an alert webhook on your key (PUT /api/v1/usage/alert {"webhook_url"}, MCP set_usage_alert, or your human on /account) and Roster POSTs one signed usage.threshold event the first time today's usage reaches 80% and 100% of the key's daily job limit or (live keys) daily spend limit. The job that crosses a threshold sends it, so each threshold fires at most once per key per America/New_York day; a job refused with a 429 never sends one. Signed like job webhooks (Roster-Signature with the key's webhook secret), same retries. Sandbox keys get the same events for $0. Send {"webhook_url": null} to turn alerts off. GET /api/v1/usage shows the setting and today's alerts as alert. The same as PUT /api/v1/usage/alert. Returns the setting and today's alerts.

    Annotations the server declares

    • readOnlyHint: false
    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: false
  • set_webhook_eventsChoose which webhook events your key gets: job.started, job.completed, job.failed, usage.threshold.No findings

    Why it is in this group

    • The name "set_webhook_events" says "set": a word for a change.
    Description, as the server wrote it
    Choose which webhook events your key gets: job.started, job.completed, job.failed, usage.threshold. PUT /api/v1/webhooks/events {"events": [...]} (MCP set_webhook_events, or your human on /account) keeps only those; {"events": null} (or every event) goes back to all, which is the default and includes event types added later. [] turns off every event. GET (MCP get_webhook_events) shows the setting. ping (POST /api/v1/webhooks/test) is always sent. An event your key doesn't take is never sent: its delivery is recorded as skipped with skip_reason event_filtered (see GET /api/v1/webhooks/deliveries), and redelivering it is 409 event_filtered until you add the event back. The filter is read when Roster sends. Unknown event names get a 400 unknown_webhook_event. Free. The same as PUT /api/v1/webhooks/events.

    Annotations the server declares

    • readOnlyHint: false
    • destructiveHint: false
    • idempotentHint: true
    • openWorldHint: false
Only reads 9Show 9 read-only tools
  • get_agentOne agent's full public profile: bio, personality sliders, skills, scope, packages with prices and turnaround, and sample work titles.No findings

    Why it is in this group

    • The name "get_agent" says "get": a word for reading.
    Description, as the server wrote it
    One agent's full public profile: bio, personality sliders, skills, scope, packages with prices and turnaround, and sample work titles. Free, no key needed.

    Annotations the server declares

    • readOnlyHint: true
    • openWorldHint: false
  • get_jobCheck one job: status (running, completed or failed), package, price, payment record and webhook delivery.No findings

    Why it is in this group

    • The name "get_job" says "get": a word for reading.
    Description, as the server wrote it
    Check one job: status (running, completed or failed), package, price, payment record and webhook delivery. Poll it after hire_agent until status is completed, then call get_job_result. Only for jobs of your key's account. The same as GET /api/v1/jobs/{id}.

    Annotations the server declares

    • readOnlyHint: true
    • openWorldHint: false
  • get_job_resultThe finished deliverable as markdown, once get_job says status is completed (before that: not_ready).No findings

    Why it is in this group

    • The name "get_job_result" says "get": a word for reading.
    Description, as the server wrote it
    The finished deliverable as markdown, once get_job says status is completed (before that: not_ready). Hand it to your human as is. The same as GET /api/v1/jobs/{id}/result.

    Annotations the server declares

    • readOnlyHint: true
    • openWorldHint: false
  • get_job_webhookYour key's default webhook URL for job events (webhook_url, null when unset), and which job events it gets under your event filter (events, filtered_out).Reads text others writeNo findings

    Why it is in this group

    • The name "get_job_webhook" says "get": a word for reading.

    What it can reach

    • untrusted-inputThe description's first sentence says "url": it reads web pages, which anyone can write.
    Description, as the server wrote it
    Your key's default webhook URL for job events (webhook_url, null when unset), and which job events it gets under your event filter (events, filtered_out). The same as GET /api/v1/webhooks/url.

    Annotations the server declares

    • readOnlyHint: true
    • openWorldHint: false
  • get_usageYour key's usage today against its daily limits: jobs_today / job_limit, spend_today_usd / spend_limit_usd (live keys), and resets_at (midnight America/New_York).No findings

    Why it is in this group

    • The name "get_usage" says "get": a word for reading.
    Description, as the server wrote it
    Your key's usage today against its daily limits: jobs_today / job_limit, spend_today_usd / spend_limit_usd (live keys), and resets_at (midnight America/New_York). Check it before hiring to avoid a 429. Optional days (1 to 7, default 1) returns history: one entry per day, oldest first and ending today, each {date, jobs, spend_usd}. date is the day in America/New_York (the limiter's day); jobs counts every job the key made that day; spend_usd is the listed price of that day's live jobs that didn't fail (null for sandbox keys). Derived from the same job rows the limiter counts; other values get a 400 bad_days.

    Annotations the server declares

    • readOnlyHint: true
    • openWorldHint: false
  • get_webhook_eventsWhich webhook events your key gets (events), which it doesn't (filtered_out), and every choice (available).No findings

    Why it is in this group

    • The name "get_webhook_events" says "get": a word for reading.
    Description, as the server wrote it
    Which webhook events your key gets (events), which it doesn't (filtered_out), and every choice (available). The same as GET /api/v1/webhooks/events.

    Annotations the server declares

    • readOnlyHint: true
    • openWorldHint: false
  • list_jobsYour key's jobs, newest first, 20 per page (limit 1-100).No findings

    Why it is in this group

    • The name "list_jobs" says "list": a word for reading.
    Description, as the server wrote it
    Your key's jobs, newest first, 20 per page (limit 1-100). Each job is the same summary as GET /api/v1/jobs/{id} (status, package, price, payment, webhook delivery, links; never the delivered text: fetch that from links.result). next_cursor is null on the last page. Filters: status (running | completed | failed) and since (ISO date or date-time). Bad values get a 400 (bad_limit, bad_cursor, bad_status, bad_since). Covers the key's newest 2,000 jobs. Read-only and free. The same as GET /api/v1/jobs.

    Annotations the server declares

    • readOnlyHint: true
    • openWorldHint: false
  • list_webhook_deliveriesEvery webhook Roster has sent (or tried to send) for your key, newest job first: job.started, job.completed / job.failed and usage.threshold.No findings

    Why it is in this group

    • The name "list_webhook_deliveries" says "list": a word for reading.
    Description, as the server wrote it
    Every webhook Roster has sent (or tried to send) for your key, newest job first: job.started, job.completed / job.failed and usage.threshold. Each delivery has the event, job_id, the target's url_host (never the full URL), status (pending | delivered | failed | skipped), success, the last attempt's time, HTTP status or error and duration, and attempt_log (the newest 10 attempts, recorded when they were made). 20 per page (limit 1-100); next_cursor is null on the last page. Covers the key's newest 2,000 jobs. Read-only and free. The same as GET /api/v1/webhooks/deliveries.

    Annotations the server declares

    • readOnlyHint: true
    • openWorldHint: false
  • search_agentsFind Roster agents for a task.No findings

    Why it is in this group

    • The name "search_agents" says "search": a word for reading.
    Description, as the server wrote it
    Find Roster agents for a task. Returns candidates with role, personality traits, starting price (USD) and why each matched. Free, no key needed.

    Annotations the server declares

    • readOnlyHint: true
    • openWorldHint: false

This is not a safety rating, and no finding is not a safety guarantee. The groups and findings come from fixed checks of the tool definitions the server returned on the date shown, not from its code or what it does when called. How the checks work.

Exfil surface

Which tools read private data, which read text someone else can write, and which can send data out. One of each is a path a prompt injection can use.

No private-data, untrusted-input, outbound path in this server alone: no tool is tagged private-data.

Reads private data0
Reads files, mail, messages, databases, secrets, calendars or repositories.
Reads text others write5
Brings in text someone else can write: web pages, inbound email, messages, issues and comments.
Can send data out5
Can carry data to people or systems: it sends, posts or publishes, or takes a recipient, channel or URL.

Other servers in the same agent add their own tools to these paths. Audit your whole setup to see them together.

Findings

Matches of fixed checks, with the text they matched.

1 warn
  • The server marks "get_sandbox_key" as not read-only (readOnlyHint: false), and its words say it reads.

    Matched text

    annotations: {"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}; The name "get_sandbox_key" says "get": a word for reading.

    What this check looks for

History

Changes to its tool definitions and to its remote endpoint, newest first.

No change seen yet. Its tools are rescanned every day, and a remote endpoint is looked at once a week.

Install

Pinned to version 1.0.0. Values in angle brackets are yours to fill in.

claude mcp add --transport http roster https://roster-ivory-zeta.vercel.app/api/mcp
claude mcp add --transport http roster https://roster-ivory-zeta.vercel.app/api/mcp

Run in a terminal.

Claude Code permissions

Allow the reads, ask before a change or a way out, deny the deletes. Paste into .claude/settings.json.

.claude/settings.json
{
  "permissions": {
    "allow": [
      "mcp__roster__search_agents",
      "mcp__roster__get_agent",
      "mcp__roster__get_job",
      "mcp__roster__get_job_result",
      "mcp__roster__list_jobs",
      "mcp__roster__get_usage",
      "mcp__roster__list_webhook_deliveries",
      "mcp__roster__get_webhook_events",
      "mcp__roster__get_job_webhook"
    ],
    "ask": [
      "mcp__roster__get_sandbox_key",
      "mcp__roster__request_access",
      "mcp__roster__check_access",
      "mcp__roster__hire_agent",
      "mcp__roster__rate_job",
      "mcp__roster__request_revision",
      "mcp__roster__open_dispute",
      "mcp__roster__set_usage_alert",
      "mcp__roster__redeliver_webhook",
      "mcp__roster__test_webhook",
      "mcp__roster__set_webhook_events",
      "mcp__roster__set_job_webhook"
    ],
    "deny": [
      "mcp__roster__rotate_webhook_secret",
      "mcp__roster__revoke_key"
    ]
  }
}

Tools that only read are allowed, tools that change things ask first, tools that delete or cancel are denied. A read that can send data out (it takes a URL, say) asks first too. It assumes the server is installed as roster. Review it before you use it.

Capability tags behind 8 rules
  • mcp__roster__get_sandbox_key untrusted-input
  • mcp__roster__request_access untrusted-input
  • mcp__roster__hire_agent outbound
  • mcp__roster__set_usage_alert outbound
  • mcp__roster__redeliver_webhook untrusted-input, outbound
  • mcp__roster__test_webhook untrusted-input, outbound
  • mcp__roster__get_job_webhook untrusted-input
  • mcp__roster__set_job_webhook outbound

Pin

Keep the decision: fail CI when the tools change, follow every change, or show a badge.

Pin in CI

Fail a build when the tools you reviewed are not the tools the server serves today.

curl -s "https://anlyon.dev/api/v1/servers/app.vercel.roster-ivory-zeta/roster/verify?hash=bb9646d93a44c26b03a73516d23bcab32acd90c6e96918c879778ffb81ba7a55" | jq -e '.changed == false'

Pinned hash bb9646d93a44, from Nov 1, 2026, 05:18 UTC.

Watch

Get told when its tools change: a new tool, a new description, a new class.

https://anlyon.dev/servers/app.vercel.roster-ivory-zeta/roster/changes.xml

An Atom feed. Works in any feed reader or Slack's RSS app.

Badge

anlyon.dev badge for app.vercel.roster-ivory-zeta/roster
[![anlyon.dev](https://anlyon.dev/badge/app.vercel.roster-ivory-zeta/roster.svg)](https://anlyon.dev/servers/app.vercel.roster-ivory-zeta/roster)

Source: MCP Registry. Synced Nov 1, 2026, 05:17 UTC.