Skip to main content
Glama
Las-so

freelance-radar-mcp

by Las-so

freelance-radar-mcp

test

An MCP server that searches official, public job/freelance APIs and, optionally, scores results against your own capability keywords. No scraping, no unofficial endpoints, no shared or embedded credentials — every call goes to a documented API, using your own key where a key is required.

Built as a small, finishable, real first rep: one legitimate authenticated-access pattern, done end to end, with tests that hit the live API rather than mocks alone.

Why this exists

Most "job board MCP" demos either scrape HTML (fragile, against most sites' terms) or hardcode a single source. This one is deliberately architected around the question "what is the strongest legitimate, authenticated, programmable interface available?" for each source, and treats a missing credential as a clean, reported skip — never a silent failure and never a workaround.

Source

Auth

Status

Remotive

none — public API

always on

Adzuna

app_id + app_key (free signup)

on when ADZUNA_APP_ID / ADZUNA_APP_KEY are set

Adding a third source (Indeed Publisher, USAJobs, Jooble, etc.) means writing one more file in src/freelance_radar_mcp/sources/ that returns the shared JobPosting shape — the server and scorer don't change.

Related MCP server: simplyapply-jobs-mcp

Tools

  • source_status() — which sources are live right now, and why. Call this first so you know exactly what you're querying.

  • search_jobs(query, category, limit) — normalized postings from every configured source, fetched in parallel.

  • score_opportunities(capability_keywords, query, category, limit) — search_jobs plus a transparent 0-100 relevance score (title matches count double). Output maps directly onto a score / capability_match style tracker column.

Install

git clone https://github.com/Las-so/freelance-radar-mcp.git
cd freelance-radar-mcp
pip install -e ".[dev]"

Run

# stdio MCP server — point your MCP client (Claude Desktop, etc.) at this command
freelance-radar-mcp

# or directly
python -m freelance_radar_mcp.server

Optional: enable Adzuna

export ADZUNA_APP_ID="your_app_id"
export ADZUNA_APP_KEY="your_app_key"

Without these, search_jobs / score_opportunities still run — Adzuna is reported in sources_skipped with the reason, Remotive results still come back.

Claude Desktop config

{
  "mcpServers": {
    "freelance-radar": {
      "command": "freelance-radar-mcp"
    }
  }
}

Behind a TLS-intercepting proxy

httpx bundles its own CA store (via certifi) and, unlike requests, does not automatically trust SSL_CERT_FILE / REQUESTS_CA_BUNDLE. Behind a proxy that injects its own root CA (sandboxed dev environments, some corporate networks, CI runners), that mismatch fails every request with CERTIFICATE_VERIFY_FAILED even though the proxy itself is fine. src/freelance_radar_mcp/http.py checks those env vars and points httpx at that CA bundle when present, so the same code runs unmodified on a bare machine and behind a proxy. If you're launching this server as a subprocess (as any MCP client does), remember the client also has to forward that env var into the subprocess's environment — most MCP clients start servers with a minimal environment for security, not your full shell env.

Test

pip install -e ".[dev]"
pytest -v

tests/test_live_remotive.py makes a real network call to the live Remotive API (no mocking) so a broken connector fails loudly instead of passing on stale mocks. Everything else is a fast unit test against fixture data.

License

MIT — see LICENSE.

Available Tools

3 tools
score_opportunitiesA

Search job sources, then score every result against your own capability keywords (0-100, title matches weighted 2x body matches). Highest score first.

Args: capability_keywords: e.g. ["MCP", "python", "automation", "shopify", "API integration"]. query: free-text search passed through to the sources. category: optional Remotive category slug. limit: max postings per source before scoring.

NameRequiredDescriptionDefault
limitNo
queryNo
categoryNo
capability_keywordsYes

TDQS

A3.5/5.0
Behavior3/5

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

With no annotations, the description carries the full burden. It does disclose meaningful behavior: the scoring formula (0-100, title matches weighted 2x), the sort order, and that limit caps postings per source before scoring. It omits whether the call hits the network, rate limits, failure behavior when a source is unreachable, and whether results are deduplicated across sources.

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?

The opening sentence front-loads the pipeline, the scoring scale, and the sort order, which is exactly what an agent needs first. The Args block is compact and each entry adds distinct information, though the labelled list is slightly heavier than prose would be.

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 four-parameter tool that queries external job sources with no annotations and no output schema, the description covers inputs well but says little about the returned result shape beyond ordering and score range. Source coverage and behavior when a source fails or returns nothing are unaddressed.

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 coverage is 0%, so the description must compensate, and it does: capability_keywords gets a concrete example list, query is described as free text passed through to sources, category is identified as an optional Remotive slug, and limit is explained as per-source pre-scoring cap rather than a total. The 2x title weighting also clarifies how keywords are applied.

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 specific compound action: search job sources, then score each result against capability keywords on a 0-100 scale, sorted descending. It is clear what the tool produces. It stops short of explicitly naming search_jobs as the plain-search alternative, so differentiation from the sibling is left to inference.

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?

Usage is implied rather than stated: an agent can infer 'use this when you want ranked results rather than raw listings,' and 'search_jobs' is the obvious alternative, but neither the condition nor the alternative is named. No prerequisites, exclusions, or source-selection guidance are given.

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

search_jobsA

Search every configured job source and return normalized postings.

Args: query: free-text search, e.g. "automation" or "shopify developer". category: optional Remotive category slug, e.g. "software-dev". limit: max postings per source (1-50).

NameRequiredDescriptionDefault
limitNo
queryNo
categoryNo

TDQS

A3.7/5.0
Behavior3/5

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

With no annotations, the description carries the full burden. It does disclose two behavioral traits: it queries all configured sources (fan-out) and normalizes results across them. However, it says nothing about per-source failure handling, rate limits, latency, or whether repeated calls are idempotent.

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?

The core purpose is front-loaded in one sentence, followed by a compact Args block that documents each parameter without padding. Slightly list-like, but every line earns its place.

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 and no annotations, the description should say more about the return value; 'normalized postings' leaves the actual fields unspecified. It also omits what happens when an individual source is unavailable, which matters for a multi-source aggregator.

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

Parameters5/5

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

Schema description coverage is 0%, and the description fully compensates: it explains query as free-text with examples, category as an optional Remotive slug with an example, and limit as max postings per source with an explicit 1-50 range not present in the schema. The 'per source' qualifier on limit is genuinely additive information.

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 verb and resource ('search ... job postings') plus scope ('every configured job source') and output shape ('normalized postings'). It is clear what the tool does, though it never explicitly contrasts itself with siblings like source_status or score_opportunities.

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 fan-out scope ('every configured job source') implies when this tool is appropriate for discovery, but there is no explicit when-to-use, when-not, or mention of the alternative sibling tools. Usage must be inferred.

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

source_statusA

Report which job sources are live and why — call this first to see what you're actually querying before trusting the results.

NameRequiredDescriptionDefault

No parameters

TDQS

A3.9/5.0
Behavior3/5

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

With no annotations, the description carries the full burden. It does imply a side-effect-free diagnostic ('Report', 'see what you're actually querying'), but never states read-only behavior, output shape, or latency/auth characteristics for a status check.

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 compact sentence, front-loaded with the purpose and finishing with the routing advice. Every clause earns its place; nothing is padded.

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 meta tool with no annotations and no output schema, the description covers what it returns ('which job sources are live and why') and when to call it. Only the result structure is left implicit.

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 of 4 applies; there is no argument syntax for the description to clarify or for the schema to document.

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?

Specific verb ('Report') plus resource ('job sources') with a stated scope: which sources are live and why. It is clearly a diagnostic/preflight tool, functionally distinct from search_jobs and score_opportunities, though those siblings are never named.

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?

'Call this first to see what you're actually querying before trusting the results' gives an explicit when-to-use and ordering relative to the search/scoring tools. It stops short of naming exclusions or alternatives, but the sequencing guidance is unusually clear.

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. 3 tool updatesv0.1.0
    • First observedscore_opportunities
    • First observedsearch_jobs
    • First observedsource_status

TDQS

A3.7/5.0

Scored across 3 tools

Disambiguation4/5

source_status is clearly a distinct diagnostic, and score_opportunities is differentiated from search_jobs by its explicit scoring/ranking behavior. The overlap between search_jobs and score_opportunities (both query sources and return postings) is real, but descriptions make the boundary legible.

Naming Consistency4/5

All names use snake_case and are readable, following a verb_noun style for the two action tools (search_jobs, score_opportunities). The noun-first source_status is a minor deviation but clearly conveys its purpose.

Tool Count4/5

Three tools is on the lean side but well matched to a focused job-radar purpose: check sources, search, and score. Nothing feels redundant or padded for the stated scope.

Completeness3/5

The core loop (verify sources, search, score) is covered, but there is no way to fetch full details for a single posting, filter by region/rate, or persist/track scored opportunities. These are noticeable gaps for a job-hunting workflow, though an agent can work around them.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables natural-language job search and aggregation from multiple recruitment websites with zero configuration, providing filtered results and standardized output for AI assistants.
    42 npm
    ISC
  • A
    license
    A
    quality
    C
    maintenance
    Enables real-time job search across thousands of companies' open roles from Greenhouse, Lever, Ashby, and SmartRecruiters, with full-text filtering and company-specific queries, no API key required.
    2
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    Enables querying job boards for a company's open roles, pulling from Greenhouse, Workday, and an opt-in LinkedIn source and normalizing the results into one shape. It discovers boards, searches one or many companies at once, and returns full postings with title-based AI/ML and junior filtering.
    7
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables real-time job discovery across multiple job boards and remote APIs, providing normalized and deduplicated job listings to AI agents via MCP.
    MIT