Read-only Taiwan job search: 104, Yourator, and Greenhouse, Lever and Workday career sites.
English · 繁體中文
A read-only Model Context Protocol server for Taiwan job boards. It lets Claude, Codex, Gemini, Cursor and any other MCP-capable AI assistant or agent search 104 人力銀行, Yourator and foreign companies' own career sites (Greenhouse, Lever, Workday) for Taiwan job postings and company profiles. More sources may be added later.
Write areas and job categories as plain Chinese names (台北市大安區, 軟體工程師) and the server turns them into 104 codes. No account, no API key.
Unofficial. Not affiliated with or endorsed by 104. It calls 104's public web endpoints. Keep the request rate low and follow 104's terms of use. No job data ships with this project.
source, or search them all at once with source="all".search_jobs, get_job, get_company, salary_overview, lookup_code, sources. Every tool carries MCP read-only annotations, which clients that gate tool use can read to skip per-call confirmation.lookup_code browses the whole area and category tree level by level.id and company_id, so an agent can go posting → details → company without extra lookups.salary_overview summarises pay (median, quartiles, min, max) over a sample of postings, grouped by pay unit.full. Set TW_JOBS_FORMAT=json for the complete structured data..mcpb bundle.Requires uv. The commands below fetch the server from PyPI and run it; nothing is installed permanently. To try the unreleased code instead, use uvx --from git+https://github.com/HsuanC0921/tw-jobs-mcp tw-jobs-mcp.
claude mcp add tw-jobs -s user -- uvx tw-jobs-mcp
codex mcp add tw-jobs -- uvx tw-jobs-mcp
or edit ~/.codex/config.toml:
[mcp_servers.tw-jobs]
command = "uvx"
args = ["tw-jobs-mcp"]
startup_timeout_sec = 60 # the first run downloads dependencies
Download tw-jobs-mcp-<version>.mcpb from Releases and open it, or add the JSON below to claude_desktop_config.json.
mcpServers clientsAdd to ~/.gemini/settings.json, ~/.cursor/mcp.json (or .cursor/mcp.json), Windsurf's mcp_config.json, or the client's equivalent:
{
"mcpServers": {
"tw-jobs": {
"command": "uvx",
"args": ["tw-jobs-mcp"]
}
}
}
.vscode/mcp.json uses servers and needs a type:
{
"servers": {
"tw-jobs": {
"type": "stdio",
"command": "uvx",
"args": ["tw-jobs-mcp"]
}
}
}
Clients that connect by URL, or a server shared inside a team:
uvx tw-jobs-mcp --transport streamable-http --port 8000
# endpoint: http://127.0.0.1:8000/mcp
docker build -t tw-jobs-mcp .
docker run --rm -p 8000:8000 tw-jobs-mcp
claude mcp add --transport http tw-jobs http://127.0.0.1:8000/mcp
codex mcp add tw-jobs --url http://127.0.0.1:8000/mcp
The HTTP server has no authentication. Keep it on localhost or a private network, or put an authenticating reverse proxy in front of it.
git clone https://github.com/HsuanC0921/tw-jobs-mcp
cd tw-jobs-mcp
claude mcp add tw-jobs -- uv run --project "$PWD" tw-jobs-mcp
The server already tells a model how to use it. The skill in skills/tw-jobs goes further for agents that load skills: how to turn a plain request into arguments, which source to pick, how to read the notes, and what to report. It follows the open Agent Skills format.
/plugin marketplace add HsuanC0921/tw-jobs-mcp, then /plugin install tw-jobs@tw-jobs-mcp. Or copy skills/tw-jobs to ~/.claude/skills/.skills/tw-jobs to ~/.agents/skills/ (or .agents/skills/ in a repository).| Tool | What it does |
|---|---|
search_jobs | Search postings. Returns a table: id, company_id, title, company, pay, location, education, skills, posted date. |
get_job | Full posting: description, requirements, skills, salary, working hours, vacation, business trip, welfare. The description is clipped at 1,500 characters unless full=true. |
get_company | Company profile; with_openings=true adds its current openings; full=true lifts the clipping. |
salary_overview | Pay statistics over the first 1 to 5 pages (30 postings each) of a search, grouped by pay unit. |
sources | Live check of which sources (104, Yourator, each career board) are reachable right now and which are blocked. |
lookup_code | Find an area or category code by name, or browse the tree with parent. |
search_jobs arguments (all optional):
| Argument | Meaning |
|---|---|
keyword, keyword_en | Search words: 1 to 3 short terms. keyword is Chinese for 104, keyword_en English for the other sources (foreign sites list English titles). The AI fills both, each translating the other, so a Chinese request finds foreign postings and an English one finds 104 postings; users never see them |
area, jobcat | Lists of Chinese names, e.g. ["台北市", "新北市"], ["軟體工程師"] |
salary_min, salary_unit | Salary floor and its unit: 月薪 (default), 年薪, 日薪, 時薪. A server-side filter |
education | 高中職, 專科, 大學, 碩士, 博士: postings whose education requirement includes it (or has none) |
my_years | Your years of experience: only postings asking for no more than that |
job_type | 全職, 兼職, 高階, 派遣 |
remote_only | Fully or partly remote only |
new_only | Posted within 7 days |
sort | relevance (default), newest, salary |
page, per_page | Paging, up to 30 per page |
source picks where to search. Result ids say where a posting lives, and get_job / get_company route on them: a bare id is 104, y: is Yourator, g: and l: are Greenhouse and Lever boards, w: is Workday. Pass ids back exactly as listed.
source | Covers | Filters it applies |
|---|---|---|
104 (default) | Taiwan's largest board | all of them |
yourator | Start-ups, foreign-company offices | keyword, area, sort=newest |
boards | Taiwan roles on companies' own Greenhouse / Lever boards | keyword, area, remote_only |
workday | Taiwan roles at 38 foreign employers on Workday, from chips and hardware to pharma and finance | keyword, area |
all | The four above, interleaved | per source; a failing source is reported, not fatal |
Filters a source cannot apply are named in a 註:…未套用 line under the table, so nothing is silently ignored. salary_overview and lookup_code are 104-only.
Add boards with TW_JOBS_BOARDS, e.g. g:gitlab,l:kraken,-g:stripe (g: Greenhouse, l: Lever, a leading - removes one). A board without Taiwan roles simply returns nothing.
TW_JOBS_WORKDAY does the same for Workday: acme.wd1/External,-micron (tenant.wdN/site, a leading - removes). Each Workday search reads only the first 60 rows per company, so narrow deep searches with a keyword. These are the same unauthenticated calls the companies' own career pages make; check each company's terms before heavy use.
Left out on purpose: 1111 (same kind of board as 104, smaller), Cake (Cloudflare challenge on every request) and LinkedIn (its terms prohibit automated access).
Find .NET backend jobs in Taipei paying at least 50,000 a month, and tell me what the market pays.
I have two years of experience. Show remote backend postings in New Taipei, read the top three, and compare the companies.
search_jobs(keyword="後端工程師", area=["台北市"])
共 1716 筆,第 1/86 頁
id|company_id|職稱|公司|薪資|地點|學歷|技能|刊登
8mve7|1a2x6bmz67|後端工程師|途銳資訊股份有限公司|月45000~70000|台北市南港區|專科~碩士|PHP/MySQL/AWS/Linux/Git|10-02
…
| Variable | Default | Meaning |
|---|---|---|
TW_JOBS_TRANSPORT | stdio | stdio or streamable-http (same as --transport) |
TW_JOBS_HOST, TW_JOBS_PORT | 127.0.0.1, 8000 | Bind address for the HTTP transports |
TW_JOBS_CACHE_TTL | 300 | Seconds to keep responses; 0 turns the cache off |
TW_JOBS_BOARDS | built-in list | Extra career boards, comma separated (see Sources) |
TW_JOBS_WORKDAY | built-in list | Extra Workday sites, tenant.wdN/site (see Sources) |
TW_JOBS_FORMAT | text | json returns every field as compact JSON instead of the text tables |
104 sits behind Cloudflare, which answers ordinary HTTP clients with a 403. curl_cffi sends the TLS fingerprint of a real Chrome instead, which gets through. Area and category names are resolved locally against 104's public code tables (src/tw_jobs_mcp/j104/data/).
company_id on postings.salary_overview is a sample of the most relevant postings, not a census, and many postings do not publish pay (undisclosed_share).uv sync
uv run pytest # offline: unit tests plus stdio and HTTP protocol tests
uv run pytest -m live # against the real 104 site
uv run python scripts/update_codes.py # refresh the area and category tables
MIT. Provided as is, without warranty.
Source-derived launch command. Check the maintainer’s required arguments and credentials before running:
uvx tw-jobs-mcpMerge this template into ~/Library/Application Support/Claude/claude_desktop_config.json. Keep existing servers. Add any arguments, credentials, and permissions required by the maintainer; this template has not been install-tested.
{
"mcpServers": {
"io-github-hsuanc0921-tw-jobs-mcp": {
"command": "uvx",
"args": [
"tw-jobs-mcp"
]
}
}
}Restart Claude Desktop completely for changes to take effect. Confirm the server appears connected in the client’s tool list, then try a read-only example from its documentation.
Claude Desktop setup referencetw-jobs-mcppypiTaiwan Jobs 台灣求職 works with any MCP-compatible client. Copy the config snippet from the Configuration section above and add it to the file shown for your client, then restart the application.
~/Library/Application Support/Claude/claude_desktop_config.jsonRestart Claude Desktop completely for changes to take effect.~/.cursor/mcp.jsonRestart Cursor for changes to take effect..vscode/mcp.jsonReload VS Code window for changes to take effect.~/.codeium/windsurf/mcp_config.jsonRestart Windsurf for changes to take effect..mcp.jsonSave at the project root, then start Claude Code in that project and review the MCP server approval prompt. Keep real credentials out of shared files.