Skip to main content
Glama
Boljo

Fantastic.jobs MCP Server

by Boljo

Fantastic.jobs MCP Server

A small local MCP server that lets Claude search fresh job postings through the Fantastic.jobs API. Ask Claude something like "find data engineer jobs in Chicago from the last week" and it calls the API for you.

How it works

Claude Desktop  ──stdio──▶  job_server.py  ──▶  client_call.py  ──HTTPS──▶  data.fantastic.jobs

File

Role

client_call.py

Talks to the API. callout() sends the request and returns the raw JSON.

job_server.py

The MCP server. Wraps callout() in a search_jobs tool and trims the response to a few fields.

main.py

Manual test script for poking at the API from the terminal. Not used by Claude.

.env

Holds your API key. Git-ignored.

Claude Desktop launches job_server.py as a background process and talks to it over stdin/stdout. You never start it yourself.

Related MCP server: JobSpy Cowork MCP Server

Requirements

  • Python 3.14+

  • uv

  • A Fantastic.jobs API key (from your subscriptions page)

  • Claude Desktop (or Claude Code)

Setup

git clone <this-repo>
cd linkedin
uv sync
echo 'linkedin_api=YOUR_KEY_HERE' > .env

Test it in the terminal

Call the tool function directly, no MCP involved:

uv run python -c "from job_server import search_jobs; print(search_jobs('Data Engineer', time_frame='7d'))"

A list of jobs means the API call, key, and field trimming all work. An empty list [] just means no matches for that search.

To test through the real MCP protocol, use the Inspector (needs Node.js):

uv run mcp dev job_server.py

Connect to Claude Desktop

Open Settings → Developer → Edit Config and add an entry under mcpServers. Use full paths: Claude Desktop is launched from the Dock and can't see your shell's PATH.

{
  "mcpServers": {
    "fantastic-jobs": {
      "command": "/Users/YOU/.local/bin/uv",
      "args": ["--directory", "/absolute/path/to/linkedin", "run", "job_server.py"]
    }
  }
}

Find your uv path with which uv. Then fully quit Claude Desktop (Cmd+Q) and reopen it. search_jobs should appear in the tools list.

For Claude Code instead:

claude mcp add fantastic-jobs -- uv --directory /absolute/path/to/linkedin run job_server.py

The tool

search_jobs(title, location="", time_frame="24h", limit=10)

Parameter

Notes

title

Required. Keyword match. Use quotes for an exact phrase, and OR to combine: "Data Engineer" OR "Analytics Engineer"

location

Full names only, no abbreviations: Chicago, Illinois, United States. Same OR syntax. Results are global if omitted.

time_frame

1h, 24h, or 7d

limit

Max results per call. Each result costs API credits.

Each job comes back trimmed to: title, organization, url, date_posted, locations_derived, ai_core_responsibilities. Edit FIELDS in job_server.py to change this. The full API response has 50+ fields including AI-extracted skills, salary, and company data.

Gotchas

  • Never print() inside job_server.py. stdout is the channel Claude talks over; a stray print corrupts it. Use print(..., file=sys.stderr) for debugging.

  • Restart Claude Desktop after any code or config change. The server process is spawned at launch and reads the key once at import.

  • .zshrc doesn't reach Claude Desktop. That's why the key lives in .env, which load_dotenv() picks up regardless of how the server was started.

  • 401 Unauthorized means the key didn't arrive. Check .env exists, has the right name (linkedin_api), and that no stale env block in the Claude config is overriding it.

  • Server shows as failed in Claude Desktop: Settings → Developer has per-server logs. It's almost always the uv path, the project path, or a missing key.

Security

.env is in .gitignore. Confirm before your first commit with git check-ignore -v .env. If a key ever leaks, rotate it from your Fantastic.jobs subscriptions page.

Available Tools

1 tool
search_jobsB

Search recent job postings from company career pages. title and location accept OR syntax, e.g. '"Software Engineer" OR "Data Scientist"'. location needs full names like 'New York, United States' (no abbreviations).

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
titleYes
locationNo
time_frameNo24h
description_formatNotext

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.2/5.0
Behavior2/5

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

No annotations are provided, so the description carries the full burden of behavioral disclosure. It establishes the source ('company career pages') and recency, but it does not mention any limitations, pagination behavior, staleness, or processing quirks. An agent is left to infer most behavioral expectations from the tool name and output schema.

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?

The description is two sentences with no waste. The purpose is front-loaded, and the parameter usage notes are compact and directly actionable.

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?

With five parameters, no annotations, and zero schema descriptions, the description is not complete enough for deliberate parameter selection. The output schema exists, so return values are covered, but key parameters like time_frame and description_format remain unexplained.

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 compensate for all five parameters. It adds useful semantics for title and location, including OR syntax and full-name requirements, but it provides no guidance for limit, time_frame, or description_format beyond their default values.

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 states a specific verb and resource: 'Search recent job postings from company career pages.' It is clear about what the tool does, though there are no siblings to differentiate against, so it cannot earn the full 5 for sibling distinction.

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?

There is no alternative tool mentioned, but the description gives clear context: use this tool when searching recent job postings from company career pages. The OR-syntax and location-format notes also provide practical guidance for effective invocation.

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. 1 tool updatev0.1.0
    • First observedsearch_jobs

TDQS

B3.3/5.0

Scored across 1 tool

Disambiguation5/5

With only one tool, there is no possibility of confusion or misselection. The tool's purpose is clearly described and unambiguous.

Naming Consistency5/5

The single tool name 'search_jobs' follows the consistent verb_noun snake_case convention. There are no other names to conflict with this pattern.

Tool Count2/5

The server has only one tool, which feels extremely thin for a job search domain. Even a minimal implementation would typically include at least a way to retrieve job details or paginate results.

Completeness2/5

The server only offers a search operation, leaving no way to fetch a specific job, browse companies, or access additional details beyond search results. The surface is too narrow to support a complete job search workflow.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables job search and scraping across multiple job boards (LinkedIn, Indeed, Glassdoor, etc.) with advanced filtering, directly from Claude Desktop or other MCP clients.
    6
    MIT
  • F
    license
    Not graded
    quality
    B
    maintenance
    Enables searching real job listings from multiple job boards (Indeed, LinkedIn, Glassdoor, Google Jobs, etc.) through a single MCP tool, designed for use as a custom connector in Claude Cowork.
    -
  • F
    license
    B
    quality
    C
    maintenance
    Enables searching justjoin.it for job listings and tracking applications locally with status updates, all via natural language in Claude.
    4
    -
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables searching and evaluating job postings from LinkedIn and freehire.me directly through Claude Desktop. Provides tools to search jobs, fetch full posting details, and assess candidate fit using eligibility scans and a scoring rubric.
    MIT