Search a live index of millions of open jobs from employer career sites and 100+ ATS platforms.
Copy the AI prompt to install this server into Claude Code, Cursor, or another agent β or use 1-click editor setup below.
π‘ Paste the JSON block into your client's configuration file under mcpServers, then restart the application.
Remote MCP server exposing Jobo's live job index β millions of listings collected from employer career sites and 150+ applicant tracking systems β to LLM clients.
Full client setup (Claude, ChatGPT, Cursor, Codex CLI) and the tool reference: jobo.world/docs/connectors/mcp.
/mcp endpoint, stateless. Serves MCP spec 2026-07-28
natively and every 2025-era client through the built-in legacy fallback (SDK v2
createMcpHandler, one factory for both eras).jobs:read.The hosted deployment is https://jobs-mcp.jobo.world. To run your own copy instead:
Starts the Streamable HTTP server on $PORT (default 3002); point your client at
http://localhost:3002/mcp. This changes where the gateway runs, not its auth model β it's still an
OAuth resource server gated on Jobo account sign-in, since the upstream API validates every request against
the Authorization Server regardless of which copy of the gateway forwarded it. Set MCP_RESOURCE_URL to
match whatever host you actually serve it from β see Configuration below.
Jobo.Enterprise/Jobo.Enterprise.Mcp was deliberately re-scoped to analytics-only in v4, which removed
search_jobs, get_job_details, list_filters, search and fetch. Adding job tools back there would
undo that decision, so this is a second server against the same External API.
The /api/mcp/jobs/* endpoints were never removed β McpController.cs still serves them, and its own
comment notes the GET search is "convenient for the canonical ChatGPT search(query) tool". This server
is a thin OAuth-forwarding gateway in front of endpoints that were built for it.
The immediate payoff: search + fetch restore Deep Research compatibility. Without that canonical
pair a server cannot be used as a ChatGPT Deep Research connector at all.
| Tool | Purpose |
|---|---|
search | Canonical Deep Research contract: {query} β {results: [{id, title, url}]}. |
fetch | Canonical Deep Research contract: {id} β {id, title, text, url, metadata}. |
search_jobs | Structured search β location, work model, employment type, experience level, source, skills, industries, salary, date, facets, paging. |
get_job_details | Full listing for clients not using the Deep Research contract. |
list_filters | Accepted values for every filter, with live counts. |
search/fetch deliberately take the minimum arguments the contract allows. Anything with structure
should go through search_jobs, where filters are real parameters rather than hopeful free text.
fetch returnstext is self-contained prose, because Deep Research reads it and never opens the URL. It is built from
the AI-extracted fields (responsibilities, qualifications, benefits, compensation) in preference to the
raw employer HTML, which is boilerplate-heavy and frequently longer than it is useful. The raw description
is available via get_job_details with include_description: true.
The server is a gateway, not the cryptographic authority. The C# External API validates the JWT with
OpenIddict against the same issuer, audience and jobs:read scope; verifying the signature a second time
here would only let the two validators drift. So this does the minimum a gateway must:
401 with the resource-metadata challenge, starting the OAuth flow.exp, no signature check) so long-lived clients
refresh rather than forwarding a dead token.req.auth, so every tool call forwards the token the client
just sent β never one captured at session-initialize.No session map. That map lived in process memory, so every restart or redeploy stranded clients with
"No active session", and it pinned the deployment to a single replica. Redis cannot back it either: the
value is a live transport object holding open streams. Each POST is served by a fresh server and transport
with no mcp-session-id issued.
| Variable | Default | Notes |
|---|---|---|
JOBO_API_URL | https://connect.jobo.world | Upstream External API. |
MCP_RESOURCE_URL | https://jobs-mcp.jobo.world | OAuth audience. Must differ from the analytics server's mcp.jobo.world. |
OAUTH_AUTH_SERVER_URL | https://enterprise.jobo.world | Authorization Server. |
PORT | 3002 | Analytics server uses 3001. |
node --test dist/format.test.js covers the mapping logic, including that search and fetch return
exactly the shapes Deep Research requires. For the wire path, point the server at a stub:
Then tools/list and tools/call over HTTP with any JWT-shaped bearer whose exp is in the future β
the gateway forwards it and the stub answers. A real token is only needed against the live API.
Published to the official MCP Registry as world.jobo/job-search (the mcpName in package.json;
server.json in this directory is the registry manifest). Publishing is automated: the mcp-v* tag
workflow publishes npm first, then pushes server.json to the registry under the DNS-TXT-verified
world.jobo/* namespace β see ../RELEASING.md. There is no review queue and aggregators poll roughly
hourly. Note the official registry has no per-server web page by design β it is a metadata API for
aggregators. The downstream surfaces differ: PulseMCP emits a dofollow link, Glama and mcp.so are
nofollow. Manual directory submissions (Claude, ChatGPT, aggregator claims) live in
../MCP-DISTRIBUTION.md.
No reviews yet β be the first to share how this listing worked for you.
Showcase your server listing on GitHub or your project documentation. Embed this dynamic SVG badge to highlight official listing status and live engagement.
[](https://allmcps.com/mcp/jobo-job-search)<a href="https://allmcps.com/mcp/jobo-job-search"><img src="https://allmcps.com/api/badge/jobo-job-search?style=directory" alt="Jobo Job Search on AllMCPs" /></a>