JobStreet MCP Server
by emansih
README.md
# jobstreet-mcp
A [Model Context Protocol](https://modelcontextprotocol.io) server (stdio transport) for searching
[JobStreet Singapore](https://sg.jobstreet.com) jobs, written in TypeScript. All tools are read-only and
need no sign-in.
> **Unofficial / undocumented API.** This server calls the same public JSON endpoints the JobStreet
> website uses (SEEK platform: REST `/api/jobsearch/v5/*` and GraphQL `/graphql`). They are not a
> supported public API and can change or break without notice; the server validates responses and fails
> with a clear error on schema drift. Please respect JobStreet/SEEK's terms of use and rate limits: the
> client throttles to at most 2 requests/second and caches results for 5 minutes. Not affiliated with
> SEEK or JobStreet.
## Tools
| Tool | Inputs | Description |
|---|---|---|
| `search_jobs` | `keywords`, `location`, `workTypes`, `workArrangements`, `classificationIds`, `subclassificationIds`, `salaryType`, `salaryMin`, `salaryMax`, `listedWithinDays`, `sortBy`, `page` (default 1), `pageSize` (default 30, max 100) | Search jobs. Returns `totalCount`, `page`, `pageSize`, `hasMore`, `searchUrl` and trimmed `jobs`. |
| `get_job_details` | `jobId` | Full job details with the description converted to plain text. |
| `get_search_counts` | same filters as `search_jobs` (no paging) | Facet counts by classification, work type and location without fetching jobs. |
| `suggest_keywords` | `query`, `count` (default 10) | Keyword autocomplete. |
| `suggest_locations` | `query`, `count` (default 10) | Location autocomplete; use the text as `location`. |
| `list_classifications` | none | The 30 top-level classification IDs. Subclassification IDs come from `search_jobs` results. |
Filter values:
- `workTypes`: `full_time`, `part_time`, `contract_temp`, `casual_vacation`
- `workArrangements`: `on_site`, `hybrid`, `remote`
- `salaryType`: `annual`, `monthly`, `hourly`. Salary bounds are SGD integers. If `salaryMin` or
`salaryMax` is given without `salaryType`, `monthly` is used. With only `salaryMax`, the minimum is 0;
with only `salaryMin`, there is no upper bound. `salaryType` alone (no bounds) is ignored.
- `listedWithinDays`: `1`, `3`, `7`, `14`, `31`
- `sortBy`: `relevance` (default), `date`
Resources: `jobstreet://classifications`, `jobstreet://about`.
API details are in [docs/jobstreet-sg-api-handover.md](./docs/jobstreet-sg-api-handover.md).
## Install
Requires Node.js >= 20.
```sh
npx -y jobstreet-mcp
# or install globally
npm install -g jobstreet-mcp
```
## Usage
### Claude Desktop
Add to `claude_desktop_config.json`:
```json
{
"mcpServers": {
"jobstreet": {
"command": "npx",
"args": ["-y", "jobstreet-mcp"]
}
}
}
```
### Claude Code
```sh
claude mcp add jobstreet -- npx -y jobstreet-mcp
```
## Development
Uses [pnpm](https://pnpm.io) (version pinned via `packageManager`).
```sh
pnpm install
pnpm dev # run from source with tsx (watch mode)
pnpm typecheck
pnpm test
pnpm build # outputs to dist/
pnpm start # run the built server
```
Code layout: `src/server.ts` registers the tools (`createServer({ fetch })` takes an injectable `fetch`
for tests); `src/jobstreet/` holds the HTTP client (throttle, cache, timeout), parameter mapping, response
validation and the HTML-to-text converter. The stdio entry point is `src/index.ts`; never write to stdout
there other than MCP messages (log to stderr).
## Releasing
CI (`.github/workflows/ci.yml`) typechecks, tests and builds on every push to `main` and on pull requests.
Publishing (`.github/workflows/publish.yml`) runs when a tag matching `v*` is pushed:
1. Add an npm automation/granular access token with publish rights as the repository secret `NPM_TOKEN`
(GitHub repo -> Settings -> Secrets and variables -> Actions).
2. Make sure `package.json` has a `repository` field pointing at the GitHub repo
(required for npm provenance).
3. Bump the version and tag it; the tag must equal `v<package.json version>`:
```sh
pnpm version patch # or minor / major (creates the commit and the vX.Y.Z tag)
git push --follow-tags
```
The workflow installs, typechecks, tests, builds and runs
`pnpm publish --access public --provenance --no-git-checks`.
## License
[Apache-2.0](./LICENSE)
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues