MCP

swissdevjobs-cli: Search and Apply to Salary-Transparent European Tech Jobs from the Terminal and AI Agents

For job seekers who want to search and apply to roughly 4,700 salary-transparent European tech jobs from the terminal or an AI agent — but real applications require prior identity configuration (name, email, résumé), and apply_to_job has an irreversible confirmation gate.

Official source · swissdevjobs-cli

Install

uv tool install git+https://github.com/Stupidoodle/swissdevjobs-cli

Who It's For

  • Job seekers looking for salary-transparent tech roles (about 4,700 of them) in Switzerland, Germany, the UK, the US, Canada, the Netherlands, or France, who want to search, filter, and apply from the terminal or an AI agent.
  • Users who want to plug their job search into an MCP client (such as Claude Code): it is simultaneously a Python CLI, an MCP server, and a Claude Code plugin.
  • Not a fit for: users who need to install from PyPI (it is not published on PyPI and can only be installed from the GitHub repository); users without a Python 3.9+ environment. Also note that the search tools require no identity configuration, but actually applying to jobs requires providing your name, email, and résumé file path — this is an explicit official prerequisite.

First Attempt in 3 Minutes

The recommended main path is to start with the read-only search tools to get familiar with the data, with no applications involved:

  1. Prerequisites: install uv, Python 3.9+.

  2. Install the CLI:

    uv tool install git+https://github.com/Stupidoodle/swissdevjobs-cli
    

    This installs two equivalent commands, sdj and swissdevjobs.

  3. Low-risk first call: use the MCP read-only tools search_jobs directly (filter by salary, tech stack, city, country, remote, seniority, visa) or top_technologies (see which technologies are currently hot in the market). These read-only tools carry a readOnlyHint, so clients may run them without interrupting you; but this only means they won't perform write operations — it does not mean zero risk, nor does it imply anything about their network access or data-reading boundaries.

  4. Success signal: a list of jobs matching your filters, or a technology ranking, is returned.

Before making real applications you need to configure your identity separately: sdj config --init writes ~/.config/swissdevjobs-cli/.env (chmod 600), containing SDJ_NAME, SDJ_EMAIL, and SDJ_CV. You can use sdj config to view the resolved configuration and its sources. These fields are only required for the apply action; searching and browsing don't need them.

Other official integration methods (secondary):

  • Claude Code plugin: /plugin marketplace add Stupidoodle/swissdevjobs-cli then /plugin install swissdevjobs@swissdevjobs; once installed, the MCP server starts, requiring uv to be on PATH.
  • Other MCP clients: configure the server key swissdevjobs in .mcp.json or claude_desktop_config.json, with the command swissdevjobs-mcp, providing SDJ_NAME, SDJ_EMAIL, and SDJ_CV via environment variables.
  • Run without pre-installing: uvx --from git+https://github.com/Stupidoodle/swissdevjobs-cli swissdevjobs-mcp.

The MCP entry point is implemented as JSON-RPC 2.0 over stdio.

Use Cases

  1. Search jobs by criteria: call search_jobs, filtering by salary, tech stack, city, country, remote, seniority, or visa requirements. What to expect: a list of salary-transparent jobs matching the criteria. Read-only, no side effects.
  2. Read a job in depth: call get_job on a candidate job to get the full description, requirements, and screening questions, and decide whether to apply. Read-only, no side effects.
  3. Record real applications: if you have already applied to a job via email or some ATS, call mark_applied to record it locally, then use list_applications to view your local records. Note that these two tools are not read-only: mark_applied writes local state, while list_applications only reads locally recorded content; nothing is sent to any remote endpoint.
  4. Apply via the site's form (with caution): apply_to_job submits through the website's own form, and once submitted it cannot be withdrawn. It has a confirmation gate: the first call refuses to submit; you must call again with confirm: true for the submission to actually go through. Make sure your identity is configured (name, email, résumé path) before applying.

Boundaries

  • Read/write nature: search_jobs, list_boards, get_job, and top_technologies are read-only; apply_to_job (remote write, requires a second call with confirm: true, irreversible) and mark_applied (local state write) are write operations.
  • Side effects and confirmation points: the only remote side effect is apply_to_job submitting an application, with the confirmation point at the second call carrying confirm: true; local side effects are the records written by mark_applied and the local .env file written by sdj config --init.
  • Credential requirements: applying requires SDJ_NAME, SDJ_EMAIL, and SDJ_CV (the résumé must be a PDF at an absolute path); this is explicitly required by the official documentation for the apply action.
  • Official limitations: not published on PyPI; apply_to_job is gated by default and cannot submit directly; the two installed commands sdj and swissdevjobs are equivalent.
  • Not yet confirmed: the exact compatibility scope across MCP clients, authentication details, and any rate-limiting or anti-scraping restrictions beyond the confirmation gate are not stated in the official evidence; consult the repository documentation before use.