Skip to main content
Glama
HsuanC0921

tw-jobs-mcp

by HsuanC0921

tw-jobs-mcp

English · 繁體中文

test License: MIT Python 3.11+ MCP

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 boards (Greenhouse, Lever) 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.

Highlights

  • Three sources that complement each other: 104 for breadth; Yourator for start-ups and foreign-company offices; career boards (Appier, Ubiquiti, Canonical, Stripe, MongoDB, Pinkoi, Binance and more) for roles that foreign companies post on their own sites and never on 104. Pick one with source, or search them all at once with source="all".

  • Five tools, all read-only: search_jobs, get_job, get_company, salary_overview, lookup_code. Every tool carries MCP read-only annotations, which clients that gate tool use can read to skip per-call confirmation.

  • Filters that really filter: keyword, area, job category, salary floor (monthly, yearly, daily or hourly), job type, remote, posted in the last 7 days, years of experience, education. Each filter was checked against the live site.

  • Chinese names in, codes out: ambiguous names return a list of candidates instead of a wrong guess. lookup_code browses the whole area and category tree level by level.

  • Chains together: every search result carries id and company_id, so an agent can go posting → details → company without extra lookups.

  • Salary market view: salary_overview summarises pay (median, quartiles, min, max) over a sample of postings, grouped by pay unit.

  • Frugal with context: replies are compact text, not JSON. A page of 20 postings is a 20-line table of about 2,000 characters (under a fifth of the same data as compact JSON), and the five tool definitions total about 2,000 characters. Long texts are clipped unless you ask for full. Set TW_JOBS_FORMAT=json for the complete structured data.

  • Clean results: the two paid postings 104 pins to the top of every page are removed by default.

  • Polite by design: one request per second, responses cached for five minutes.

  • Several ways to run: stdio for local clients, streamable HTTP / SSE for remote ones, a Dockerfile, a Claude Desktop .mcpb bundle, and ready-made prompts and a code-table resource.

Related MCP server: recruiting-jobs-mcp

Install

Requires uv. The commands below run the server straight from GitHub; nothing is installed permanently.

Claude Code

claude mcp add tw-jobs -s user -- uvx --from git+https://github.com/HsuanC0921/tw-jobs-mcp tw-jobs-mcp

OpenAI Codex CLI

codex mcp add tw-jobs -- uvx --from git+https://github.com/HsuanC0921/tw-jobs-mcp tw-jobs-mcp

or edit ~/.codex/config.toml:

[mcp_servers.tw-jobs]
command = "uvx"
args = ["--from", "git+https://github.com/HsuanC0921/tw-jobs-mcp", "tw-jobs-mcp"]
startup_timeout_sec = 60   # the first run downloads dependencies

Claude Desktop

Download tw-jobs-mcp-<version>.mcpb from Releases and open it, or add the JSON below to claude_desktop_config.json.

Gemini CLI, Cursor, Windsurf, Cline and other mcpServers clients

Add 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": ["--from", "git+https://github.com/HsuanC0921/tw-jobs-mcp", "tw-jobs-mcp"]
    }
  }
}

VS Code (GitHub Copilot)

.vscode/mcp.json uses servers and needs a type:

{
  "servers": {
    "tw-jobs": {
      "type": "stdio",
      "command": "uvx",
      "args": ["--from", "git+https://github.com/HsuanC0921/tw-jobs-mcp", "tw-jobs-mcp"]
    }
  }
}

Remote (HTTP) and Docker

Clients that connect by URL, or a server shared inside a team:

uvx --from git+https://github.com/HsuanC0921/tw-jobs-mcp 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.

From a clone

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

Tools

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.

lookup_code

Find an area or category code by name, or browse the tree with parent.

search_jobs arguments (all optional):

Argument

Meaning

keyword

Search words

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

with_sponsored

Keep the two paid postings 104 pins to each page (removed by default)

Sources

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. 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

all

The three 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.

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).

Also exposed: the prompts job_hunt and compare_postings, and the resource template tw-jobs://codes/{kind} (area or jobcat).

Examples

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
…

Configuration

Variable

Default

Meaning

TW_JOBS_TRANSPORT

stdio

stdio, streamable-http or sse (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_FORMAT

text

json returns every field as compact JSON instead of the text tables

How it works

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/).

Limits, on purpose

  • Read-only. No login, applying or bookmarking. Handing an AI your job-board password is not worth the risk.

  • No company-name search. 104 puts a Cloudflare challenge in front of that endpoint. Reach companies through the 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).

Development

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

License

MIT. Provided as is, without warranty.

Available Tools

6 tools
get_companyB
Read-onlyIdempotent

公司簡介(company_id 來自搜尋結果或 get_job)。with_openings=True 附目前職缺。

ParametersJSON Schema
NameRequiredDescriptionDefault
fullNo
company_idYes
with_openingsNo

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare the safe read-only, idempotent, non-destructive profile, so the description doesn't need to repeat that. It adds one useful behavioral detail — that with_openings=True attaches current job openings — but says nothing about what the default response contains or what the full parameter changes.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, front-loaded with purpose and parameter guidance, with no filler. Every sentence earns its place by conveying purpose or parameter behavior.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with three parameters, zero schema descriptions, and no output schema, the description is incomplete. It covers company_id sourcing and with_openings but fails to explain the 'full' parameter or what the returned company profile actually includes.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must carry parameter meaning. It explains company_id's source and the effect of with_openings=True, but completely omits the third parameter 'full', leaving a significant semantic gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names the specific resource (公司簡介/company profile) and states what the tool returns, distinguishing it clearly from job-focused siblings like get_job and search_jobs. However, it does not explicitly name or contrast with any alternative tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It tells the agent where the required company_id comes from (搜尋結果或 get_job), which is useful prerequisite context. But it provides no when-to-use/when-not guidance and does not mention any alternative tools or conditions for choosing this tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_jobA
Read-onlyIdempotent

職缺完整內容(job_id 來自 search_jobs)。說明預設截斷,full=True 看全文。

ParametersJSON Schema
NameRequiredDescriptionDefault
fullNo
job_idYes

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent, non-destructive and openWorld, so the safety profile is covered. The description adds a trait the annotations do not: the default response is truncated and full=True is needed for the complete text, which materially affects how an agent invokes the tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single tightly packed sentence with parentheticals: the surface (full job content), the input source (search_jobs), and the full-text flag are all front-loaded with zero filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple two-param read with no output schema, it discloses the key operational fact (default truncation) and the input source. It does not describe the return shape or what fields a truncated vs full response contains, which is a minor gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must carry the params. It explains that `full` toggles between truncated and complete text, and it clarifies the provenance of the required `job_id`, covering both parameters' meaning beyond the bare schema types.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

"職缺完整內容" states a specific resource (full job posting) and the parenthetical names search_jobs as the origin of job_id, which differentiates it from the sibling listing tool. It stops short of an explicit verb (get/retrieve) and does not contrast with get_company/salary_overview, so it is clear but not maximally distinguishing.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The parenthetical "job_id 來自 search_jobs" implies the workflow (search first, then fetch), and "full=True 看全文" hints at the option, but there is no explicit when-to-use/when-not or comparison against alternatives like get_company.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

lookup_codeA
Read-onlyIdempotent

查地區(area)或職類(jobcat)代碼。name 留空則列 parent 的下一層(parent 也空=最上層)。

ParametersJSON Schema
NameRequiredDescriptionDefault
kindYes
nameNo
parentNo

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, openWorldHint and destructiveHint=false, so the safety profile is covered. The description adds the traversal behavior (empty name returns children of parent), which is genuine context beyond the annotations, but says nothing about output shape or result limits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short, front-loaded sentences with zero filler; the primary purpose is stated first and the parameter behavior second. Nothing is redundant.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 3-parameter lookup with no output schema and 0% schema coverage, the description covers the parameter interplay but does not document the full set of valid kind values or what a returned code list looks like. Adequate but with visible gaps given the complete absence of structured parameter documentation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must carry the load, and it does reasonably well: it implies kind takes 'area' or 'jobcat', and it explains the interaction between name and parent (empty name = list next level; empty parent = top level). It omits the default values and exact accepted kind strings, keeping it from a 5.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description pairs a specific verb (查/look up) with a specific resource (地區 area codes, 職類 jobcat codes), so an agent understands this is a reference-code lookup tool. It does not, however, differentiate itself from siblings like search_jobs or get_job, so it stops short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The second sentence gives implied usage: empty name lists the next level under parent, and empty parent means top level. That tells the agent how to invoke it for hierarchy traversal, but there is no explicit when-to-use guidance or comparison against the sibling lookup/search tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

salary_overviewB
Read-onlyIdempotent

薪資行情:取前 pages(1~5)頁有公開薪資的職缺,依單位統計筆數、最低、四分位、中位、最高。 參數同 search_jobs。樣本統計,非全站。

ParametersJSON Schema
NameRequiredDescriptionDefault
areaNo
pagesNo
jobcatNo
keywordNo
job_typeNo
my_yearsNo
new_onlyNo
educationNo
remote_onlyNo

TDQS

B3.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/idempotent/openWorld/non-destructive, so the safety profile is covered. The description adds genuinely useful behavior beyond that: it is a sample statistic (樣本統計,非全站) and covers only the first 1~5 pages, warning the agent its results are not population-wide.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Dense and front-loaded: purpose, computed statistics, page cap, and the sampling caveat all land in a few short clauses with no filler. The '參數同 search_jobs' clause briefly offloads detail, which is efficient but leaves gaps.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description helpfully names the returned statistics (count/min/quartiles/median/max). However, for a 9-param tool with zero schema coverage and no enum hints, delegating parameter semantics to search_jobs leaves the definition incomplete for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Nine parameters sit at 0% schema description coverage, and the description only compensates with '參數同 search_jobs', delegating semantics to a sibling schema. The 'pages(1~5)' hint documents one param's range, but the remaining eight (area, jobcat, keyword, job_type, my_years, new_only, education, remote_only) are unexplained.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific operation (取有公開薪資的職缺並統計) and the exact resource computed: 筆數、最低、四分位、中位、最高. It is clearly a salary-statistics tool rather than a listing tool, but sibling differentiation is only implicit via '參數同 search_jobs' rather than an explicit contrast with search_jobs/get_job.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The '參數同 search_jobs' note tells the agent params mirror a sibling and 'pages(1~5)' bounds the sampling, but there is no explicit when-to-use vs when-to-prefer search_jobs, and no stated prerequisites or constraints beyond the sample caveat.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_jobsA
Read-onlyIdempotent

搜尋職缺,回傳表格(id 給 get_job,company_id 給 get_company)。 source:104(預設,最完整)|yourator(新創、外商)|boards(外商官網職缺)|all(合併)。 後兩者只支援 keyword、area、sort=newest(boards 另支援 remote_only),其餘條件會在註記中說明未套用。 area/jobcat 填中文名稱(台北市、軟體工程師),對不到唯一結果會回候選。 salary_min 單位 salary_unit:月薪|年薪|日薪|時薪。education:高中職|專科|大學|碩士|博士。 my_years=你的年資,只列要求不超過的。job_type:全職|兼職|高階|派遣。 sort:relevance|newest|salary。per_page≤30。預設濾掉置頂廣告。

ParametersJSON Schema
NameRequiredDescriptionDefault
areaNo
pageNo
sortNorelevance
jobcatNo
sourceNo104
keywordNo
job_typeNo
my_yearsNo
new_onlyNo
per_pageNo
educationNo
salary_minNo
remote_onlyNo
salary_unitNo月薪
with_sponsoredNo

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnly, idempotent, non-destructive, openWorld), so the bar is lower. The description still adds real behavior: per_page is capped at 30, sponsored/pinned ads are filtered by default, and unmatched area/jobcat values return candidate lists rather than failing.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Dense and front-loaded, with the highest-value routing info (id→get_job, source table) first. Every clause carries semantic weight; it reads as a compact parameter legend rather than prose, though the run-on formatting slightly reduces scannability.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 15-parameter tool with no output schema, the description does well by naming the table return and covering most high-value filters. Gaps remain for page, new_only, with_sponsored, and keyword, so it is not fully complete but is well above adequate.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the full burden. It documents source, area/jobcat (Chinese names with fuzzy-match fallback), salary_min + salary_unit units, education, job_type, sort, my_years semantics, and per_page limit — substantial compensation, though page, new_only, with_sponsored, and keyword remain undefined.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('搜尋職缺' / search job listings) and immediately clarifies the return shape ('回傳表格'), routing the id to get_job and company_id to get_company. This differentiates it cleanly from its detail-lookup siblings without opening their schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit per-source routing guidance (104 default/most complete, yourator for startups, boards for foreign official sites, all for merged) and warns that the latter two sources only support keyword/area/sort=newest, so other filters are silently dropped. Strong selection guidance, though no explicit 'don't use this when' framing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

sourcesA
Read-onlyIdempotent

即時檢查 104、Yourator 與各外商職缺板目前哪些連得上,哪些被擋。

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false, and openWorldHint, so the safety and network-dependence profile is covered. The description adds value by naming the specific external boards probed and implying a reachable/blocked result shape, but it says nothing about timing, rate limits, or caching behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence with no filler that front-loads the action (即時檢查) and then the resources inspected. Every clause carries information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a parameterless probe with no output schema, the description conveys what is examined and the binary outcome (reachable vs. blocked). It leaves the exact result format unspecified, but that is a minor gap for a tool this simple.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so the baseline is 4. There are no parameters whose meaning the description would need to clarify.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a concrete verb (即時檢查 / check in real time) and a concrete resource (reachability of 104, Yourator, and foreign job boards). It is unambiguous what the tool does despite the vague tool name 'sources'. It does not, however, explicitly distinguish itself from siblings like search_jobs, which is why it falls short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no explicit when-to-use guidance, no prerequisites, and no mention of alternatives. An agent can infer this is a health/probe check to run before searching, but nothing in the text states that or excludes any scenario.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 6 tool updatesv1.1.0
    • First observedget_company
    • First observedget_job
    • First observedlookup_code
    • First observedsalary_overview
    • First observedsearch_jobs
    • First observedsources

TDQS

A3.8/5.0

Scored across 6 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: search_jobs lists listings, get_job/get_company fetch single-entity details, salary_overview aggregates statistics, sources checks connectivity, and lookup_code resolves codes. Although salary_overview shares parameters with search_jobs, its statistical output (quartiles/median) versus listing output makes the boundary obvious.

Naming Consistency4/5

All names use snake_case, with a consistent get_ prefix for the two detail fetchers (get_job, get_company) and verb_noun elsewhere (search_jobs, lookup_code). Minor deviation: salary_overview and sources are noun-only rather than verb-led, but still readable and predictable.

Tool Count5/5

Six tools is tightly scoped for a job-search server: search, job detail, company detail, salary statistics, source health, and code lookup each earn their place with no redundancy.

Completeness4/5

The surface covers the full read workflow: discovery (search_jobs), drill-down (get_job, get_company), analysis (salary_overview), and supporting utilities (sources, lookup_code). Only minor gaps exist, such as no fetching of multiple jobs by ID in one call, but agents can easily work around this.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables AI agents to pull live job listings from major ATS platforms (Greenhouse, Lever, Ashby, Workable), Hacker News hiring threads, and detect hiring signals on company career pages.
    -
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables AI agents to search and explore remote job listings, salary stats, and popular roles, and supports token-authenticated actions like job alerts and apply redirects.
    MIT
  • F
    license
    A
    quality
    B
    maintenance
    This MCP server lets AI assistants search job listings on Taiwan's 104 Job Bank, read full job details, and prepare applications with human-in-the-loop confirmation before final submission.
    3
    3
    -