MCPサーバー

Reqbeat Hiring Signals

com.reqbeat/hiring-signals
ビジネス・業務 営業・CRM 公開・接続可能 MCP 2025-11-25

このMCPでできること

Searches hiring activity, qualifies companies, monitors requisition changes, and supports recruiting follow-up workflows.

cancel_watch
Cancel a watch
WHEN a watch should stop firing. Takes the `id` `watch_company` returned (or `list_watches` lists): {"watch_id": 42} -> {"id": 42, "canceled": true}. Idempotent -- cancelling a watch you already cancelled succeeds again. An id that is not one of your watches is an error, identical whether it belongs to someone else or does not exist. Frees the slot a free key's watch limit counts. Never billed. Needs your key: a blank one returns a signup link. Plane session only: `watch_subscriptions` is plane-owned.
破壊的操作あり 外部アクセスあり 冪等
入力スキーマ
{'type': 'object', 'title': 'cancel_watchArguments', 'required': ['watch_id'], 'properties': {'watch_id': {'type': 'integer', 'title': 'Watch Id'}, 'plane_api_key': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'title': 'Plane Api Key', 'default': None, 'description': 'Deprecated: pass the key in the `X-API-Key` header, or omit the header for demo mode. Removed in 1.2.'}}}
find_company
Find company by domain or name
WHEN you hold a company's website or name but not the `company_id` every company-scoped tool takes (`is_hiring`, `get_open_reqs`, `hiring_pulse`, `pre_action_brief`, `watch_company`). Pass exactly one of `domain` or `name`; both or neither is an error naming that rule. `domain` takes a bare host or a full URL and matches exactly ({"domain": "https://www.stripe.com/jobs"} -> the companies at `stripe.com`); `name` returns up to five candidates, each with a `match_confidence` -- 1.0 for an exact name, 0.8 for a match once legal suffixes are dropped. Each company carries `company_id`, `company_name`, `company_domain`, `country_code` and `coverage_status`, and no hiring signal: ask `is_hiring` for that. Nothing matching is an empty `companies` list, never an error. Never billed. No key yet? On the hosted HTTP endpoint send no `X-API-Key` header and the lookup runs on a shared demo credential until a per-IP limit is reached.
読み取り専用 外部アクセスあり 冪等
入力スキーマ
{'type': 'object', 'title': 'find_companyArguments', 'properties': {'name': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'title': 'Name', 'default': None}, 'domain': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'title': 'Domain', 'default': None}, 'plane_api_key': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'title': 'Plane Api Key', 'default': None, 'description': 'Deprecated: pass the key in the `X-API-Key` header, or omit the header for demo mode. Removed in 1.2.'}}}
get_changes
Change feed since cursor
The change feed, not a search: ledger events -- a req opened, re-observed, reposted or closed -- with `event_seq > since`, ascending, plus `next_cursor`. Replay with `next_cursor` instead of polling or re-searching; an empty page bills nothing and one `change` unit is metered per event returned. Filter by `company_id`, or by one exact `event_type`. `limit` is bounded -- page with the cursor rather than raising it. Free-tier callers see events at the same freshness floor as every other free read. This is the pull-based twin of `watch_company` (push via webhook).
読み取り専用 外部アクセスあり 冪等
入力スキーマ
{'type': 'object', 'title': 'get_changesArguments', 'required': ['since'], 'properties': {'limit': {'type': 'integer', 'title': 'Limit', 'default': 100}, 'since': {'type': 'integer', 'title': 'Since'}, 'company_id': {'anyOf': [{'type': 'integer'}, {'type': 'null'}], 'title': 'Company Id', 'default': None}, 'event_type': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'title': 'Event Type', 'default': None}, 'plane_api_key': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'title': 'Plane Api Key', 'default': None, 'description': 'Deprecated: pass the key in the `X-API-Key` header, or omit the header for demo mode. Removed in 1.2.'}, 'idempotency_key': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'title': 'Idempotency Key', 'default': None}}}
get_open_reqs
Open requisitions for a company
The company's current active reqs, deduped across boards -- ATS/board-only, freshness-floored. `function` must be a function id (as seen in prior results); a plain role name like 'engineering' is rejected with an explicit error rather than an empty result. `limit` is bounded: an oversized page is rejected rather than truncated.
読み取り専用 外部アクセスあり 冪等
入力スキーマ
{'type': 'object', 'title': 'get_open_reqsArguments', 'required': ['company_id'], 'properties': {'limit': {'type': 'integer', 'title': 'Limit', 'default': 50}, 'country': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'title': 'Country', 'default': None}, 'function': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'title': 'Function', 'default': None}, 'company_id': {'type': 'integer', 'title': 'Company Id'}, 'plane_api_key': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'title': 'Plane Api Key', 'default': None, 'description': 'Deprecated: pass the key in the `X-API-Key` header, or omit the header for demo mode. Removed in 1.2.'}, 'idempotency_key': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'title': 'Idempotency Key', 'default': None}}}
get_role
Get one role
One open role's detail, addressed by the `company_id` + `req_key` pair every `search_jobs` row already carries -- the follow-up call for a role you hold an identifier for, instead of re-pulling the whole company with `get_open_reqs`. Scoped exactly as `search_jobs` is: ATS-only and freshness-floored. The body adds `raw_title` (the posting's own title) and `boards`, the full deduped list of boards reporting this req. A role that does not exist, is closed, or has not reached the freshness floor is an explicit error, never an empty success -- and it is not billed. No key yet? On the hosted HTTP endpoint the first calls are free: send no `X-API-Key` header and the lookup runs on a shared demo credential, billed to nobody and marked as such, until a per-IP limit is reached.
読み取り専用 外部アクセスあり 冪等
入力スキーマ
{'type': 'object', 'title': 'get_roleArguments', 'required': ['company_id', 'req_key'], 'properties': {'req_key': {'type': 'string', 'title': 'Req Key'}, 'company_id': {'type': 'integer', 'title': 'Company Id'}, 'plane_api_key': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'title': 'Plane Api Key', 'default': None, 'description': 'Deprecated: pass the key in the `X-API-Key` header, or omit the header for demo mode. Removed in 1.2.'}, 'idempotency_key': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'title': 'Idempotency Key', 'default': None}}}
hiring_pulse
Hiring velocity and direction
One number set for one company: how many reqs it opened in the last 30 days, a `velocity` ratio of that against the 30 days before it, a `direction` of up / flat / down between the two, a surge flag, and `momentum` -- postings published per week, a flow rather than a stock. Use it to rank or score a company you already hold a `company_id` for. Freshness is controlled by `max_age` (seconds); a company with no ATS/board data yet returns `{job_id, status: "crawling"}` instead of a body -- poll again later, do not read it as "not hiring". For the whole picture in one round-trip use `pre_action_brief`; for a cheap yes/no use `is_hiring`.
読み取り専用 外部アクセスあり 冪等
入力スキーマ
{'type': 'object', 'title': 'hiring_pulseArguments', 'required': ['company_id'], 'properties': {'max_age': {'anyOf': [{'type': 'integer'}, {'type': 'null'}], 'title': 'Max Age', 'default': None}, 'company_id': {'type': 'integer', 'title': 'Company Id'}, 'plane_api_key': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'title': 'Plane Api Key', 'default': None, 'description': 'Deprecated: pass the key in the `X-API-Key` header, or omit the header for demo mode. Removed in 1.2.'}, 'idempotency_key': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'title': 'Idempotency Key', 'default': None}}}
is_hiring
Is this company hiring?
WHEN an agent already holds a company and needs to qualify it -- the cheap gate before spending a richer call. ATS/board-only and freshness-floored. Takes the integer `company_id` from an earlier result, not a company name or domain. company_id=1234 -> is_hiring true, open_req_count 7, coverage_status "ats_direct_hit". company_id=5678 -> is_hiring false with coverage_status "no_ats_signal" -- that company has no ATS coverage yet, which is not evidence it is quiet, so do not score it as a negative. No key yet? Pass `plane_api_key` as an empty string and the call answers with a signup link instead of an auth error. To find companies in the first place, use `who_is_hiring_for`.
読み取り専用 外部アクセスあり 冪等
入力スキーマ
{'type': 'object', 'title': 'is_hiringArguments', 'required': ['company_id'], 'properties': {'company_id': {'type': 'integer', 'title': 'Company Id'}, 'plane_api_key': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'title': 'Plane Api Key', 'default': None, 'description': 'Deprecated: pass the key in the `X-API-Key` header, or omit the header for demo mode. Removed in 1.2.'}, 'idempotency_key': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'title': 'Idempotency Key', 'default': None}}}
list_watches
List active watches
WHEN you need to see what you are subscribed to -- before adding a watch, or to find the `id` `cancel_watch` takes. Returns your live watches newest first, cancelled ones excluded: {} -> {"watches": [{"id": ..., "company_id": ..., "event_types": [...], "webhook_endpoint_id": ..., "status": "firing", ...}]}. Each also reports its heartbeat -- `last_fired_at`, `fires_last_7d`, `fires_last_30d`, `fires_last_hour` against `max_fires_per_hour`, `rate_limited`, and a one-word `status` -- so a watch silent because nobody is hiring reads differently from one that can never match or whose endpoint is failing. Never billed. Needs your key: a blank one returns a signup link. Plane session only: `watch_subscriptions` is plane-owned.
読み取り専用 外部アクセスあり 冪等
入力スキーマ
{'type': 'object', 'title': 'list_watchesArguments', 'properties': {'plane_api_key': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'title': 'Plane Api Key', 'default': None, 'description': 'Deprecated: pass the key in the `X-API-Key` header, or omit the header for demo mode. Removed in 1.2.'}}}
pre_action_brief
Pre-action brief for a company
Everything an agent needs before acting on one company, in one bounded round-trip instead of five: the hiring pulse, its top open reqs deduped across boards, first-hire-by-function events, hardest-to-fill (reposted) reqs and ATS-vendor migrations, pre-joined and each section capped so the payload stays compact. Use it right before writing outreach or a qualification note for a `company_id` you already hold. Honors `max_age` (seconds); a company with no ATS/board data returns `{job_id, status: "crawling"}`. If you only need the velocity number, `hiring_pulse` is cheaper.
読み取り専用 外部アクセスあり 冪等
入力スキーマ
{'type': 'object', 'title': 'pre_action_briefArguments', 'required': ['company_id'], 'properties': {'max_age': {'anyOf': [{'type': 'integer'}, {'type': 'null'}], 'title': 'Max Age', 'default': None}, 'company_id': {'type': 'integer', 'title': 'Company Id'}, 'plane_api_key': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'title': 'Plane Api Key', 'default': None, 'description': 'Deprecated: pass the key in the `X-API-Key` header, or omit the header for demo mode. Removed in 1.2.'}, 'idempotency_key': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'title': 'Idempotency Key', 'default': None}}}
register_webhook
Register a webhook endpoint
Register the delivery target a watch fires to, and get back the `webhook_endpoint_id` `watch_company` needs -- call this first if you do not already hold one. Idempotent: registering the same `url` twice returns the same id, so retrying is safe and never leaves you with two endpoints. `secret` is optional; supply one to verify the `X-Plane-Signature` on delivered payloads, omit it and one is generated (it is never returned). Registration itself is free -- the `watch_company` call that follows is what bills. Plane session only: `webhook_endpoints` is plane-owned and this tool reads no corpus table.
外部アクセスあり 冪等
入力スキーマ
{'type': 'object', 'title': 'register_webhookArguments', 'required': ['url'], 'properties': {'url': {'type': 'string', 'title': 'Url'}, 'secret': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'title': 'Secret', 'default': None}, 'plane_api_key': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'title': 'Plane Api Key', 'default': None, 'description': 'Deprecated: pass the key in the `X-API-Key` header, or omit the header for demo mode. Removed in 1.2.'}}}
search_jobs
Search open roles
Flat, role-granular job search -- the individual open roles across companies matching `role` (function) / `geo` (country) / `since`, one row per logical req (each with its own `company_id` + `req_key`), ATS-only + freshness-floored. Keyset-paginated via the opaque `cursor` (a prior call's `next_cursor`). Use `who_is_hiring_for` for the company-granular reverse view. `role` must be a function id (as seen in prior results); a plain role name like 'engineering' is rejected with an explicit error rather than an empty result -- pass plain language as `q` instead, which searches the posting's own title, expanded semantically to nearby titles, and reports each row's `relevance` (0-1). `q` is independent of `role`: pass both to search titles within one function. `sort` is 'relevance' (the default with a `q`) or 'recency'; omit both and the page keeps its stable default order. `limit` is bounded: an oversized page is rejected rather than truncated, so page through the full set with `cursor` instead of raising `limit`. No key yet? On the hosted HTTP endpoint the first calls are free: send no `X-API-Key` header and the search runs on a shared demo credential -- a smaller page, billed to nobody, and the result says so -- until a per-IP limit is reached, after which the answer becomes a signup link whose minted key finishes this exact search. On any other transport a blank key answers with that signup link straight away.
読み取り専用 外部アクセスあり 冪等
入力スキーマ
{'type': 'object', 'title': 'search_jobsArguments', 'properties': {'q': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'title': 'Q', 'default': None}, 'geo': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'title': 'Geo', 'default': None}, 'role': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'title': 'Role', 'default': None}, 'sort': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'title': 'Sort', 'default': None}, 'limit': {'type': 'integer', 'title': 'Limit', 'default': 20}, 'since': {'anyOf': [{'type': 'string', 'format': 'date-time'}, {'type': 'null'}], 'title': 'Since', 'default': None}, 'cursor': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'title': 'Cursor', 'default': None}, 'plane_api_key': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'title': 'Plane Api Key', 'default': None, 'description': 'Deprecated: pass the key in the `X-API-Key` header, or omit the header for demo mode. Removed in 1.2.'}, 'idempotency_key': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'title': 'Idempotency Key', 'default': None}}}
watch_company
Watch a company
Subscribe to a company's hiring events on a registered webhook -- `webhook_endpoint_id` must belong to the same customer as the authenticated key. Meters one `watch` unit. A free key holds a limited number of watches at once; the one past that is refused with the same 402 the REST route raises, and cancelling a watch returns the slot.
外部アクセスあり
入力スキーマ
{'type': 'object', 'title': 'watch_companyArguments', 'required': ['company_id', 'event_types', 'webhook_endpoint_id'], 'properties': {'company_id': {'type': 'integer', 'title': 'Company Id'}, 'event_types': {'type': 'array', 'items': {'type': 'string'}, 'title': 'Event Types'}, 'plane_api_key': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'title': 'Plane Api Key', 'default': None, 'description': 'Deprecated: pass the key in the `X-API-Key` header, or omit the header for demo mode. Removed in 1.2.'}, 'idempotency_key': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'title': 'Idempotency Key', 'default': None}, 'webhook_endpoint_id': {'type': 'integer', 'title': 'Webhook Endpoint Id'}}}
who_is_hiring_for
Find companies hiring for a role
WHEN an agent needs to FIND the companies worth working -- the sourcing step, before it knows which companies exist. Reverse who's-hiring-for {role, geo} search: companies with active reqs matching `role`/`geo`/`since`, deduped by company, keyset-paginated via `cursor`. `role` is free text matched against the posting title, not an id. `geo` is resolved to a stored country before matching; an unresolvable one is an explicit error, never a quietly partial page. `limit` is bounded -- page through the full set with `cursor` instead of raising it. Billed per company returned (~0.10 USD each) -- an empty result bills nothing. role="backend engineer", geo="USA" -> the companies with matching active reqs, each with its pulse and its matched reqs. geo="Atlantis" -> an explicit unresolvable-country error rather than an empty page. No key yet? On the hosted HTTP endpoint the first calls are free: pass `plane_api_key` as an empty string and the search runs on a shared demo credential -- a smaller page, billed to nobody -- until a per-IP limit is reached, after which the answer becomes a signup link whose minted key finishes this exact search. On any other transport a blank key answers with that signup link straight away. Already holding a company_id and only need a yes/no? Use `is_hiring`.
読み取り専用 外部アクセスあり 冪等
入力スキーマ
{'type': 'object', 'title': 'who_is_hiring_forArguments', 'properties': {'geo': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'title': 'Geo', 'default': None}, 'role': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'title': 'Role', 'default': None}, 'limit': {'type': 'integer', 'title': 'Limit', 'default': 20}, 'since': {'anyOf': [{'type': 'string', 'format': 'date-time'}, {'type': 'null'}], 'title': 'Since', 'default': None}, 'cursor': {'anyOf': [{'type': 'integer'}, {'type': 'null'}], 'title': 'Cursor', 'default': None}, 'plane_api_key': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'title': 'Plane Api Key', 'default': None, 'description': 'Deprecated: pass the key in the `X-API-Key` header, or omit the header for demo mode. Removed in 1.2.'}, 'idempotency_key': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'title': 'Idempotency Key', 'default': None}}}
write_outcome
Record a conversion outcome
Write back a conversion outcome for `company_id` -- the label-flywheel substrate. Appends to `outcome_labels` scoped to the caller's own customer. Plane session only: `outcome_labels` is plane-owned (Phase 1 dropped its one foreign key into the corpus) and this tool reads no corpus table.
外部アクセスあり
入力スキーマ
{'type': 'object', 'title': 'write_outcomeArguments', 'required': ['company_id', 'outcome', 'observed_at'], 'properties': {'outcome': {'type': 'string', 'title': 'Outcome'}, 'req_key': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'title': 'Req Key', 'default': None}, 'company_id': {'type': 'integer', 'title': 'Company Id'}, 'observed_at': {'type': 'string', 'title': 'Observed At', 'format': 'date-time'}, 'plane_api_key': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'title': 'Plane Api Key', 'default': None, 'description': 'Deprecated: pass the key in the `X-API-Key` header, or omit the header for demo mode. Removed in 1.2.'}}}
追加
write_outcome
2026年9月17日12:37
追加
cancel_watch
2026年9月17日12:37
追加
list_watches
2026年9月17日12:37
追加
watch_company
2026年9月17日12:37
追加
register_webhook
2026年9月17日12:37
追加
find_company
2026年9月17日12:37
追加
get_changes
2026年9月17日12:37
追加
pre_action_brief
2026年9月17日12:37
追加
get_role
2026年9月17日12:37
追加
search_jobs
2026年9月17日12:37
追加
who_is_hiring_for
2026年9月17日12:37
追加
hiring_pulse
2026年9月17日12:37
追加
get_open_reqs
2026年9月17日12:37
追加
is_hiring
2026年9月17日12:37