Skip to main content
Glama
sauravss98
by sauravss98

sponsor-check

Can this UK employer sponsor my visa? Ask Claude, get an answer from the official Home Office register in seconds.

Live demo: sponsor-check.onrender.com (free hosting, so the first visit after a quiet spell can take up to a minute to wake up)

sponsor-check is an MCP server, command-line tool and web app that checks employers against the Register of licensed sponsors: workers, which UK Visas and Immigration republishes almost every working day. It also checks a salary against the published Skilled Worker thresholds and going rates.

$ sponsor-check check "Synthesia"
YES: Synthesia / Skilled Worker (register 2026-09-28)
  Synthesia Limited  (London)  score 100
      - Skilled Worker  [A]

$ sponsor-check salary 45000 2136
YES: £45,000 for occupation code 2136 (IT quality and testing professionals)
  required: £41,700
  rule: Standard rate: the higher of the £41,700 general salary threshold and the £41,200
        going rate for occupation code 2136 (IT quality and testing professionals).

Why

Checking the register by hand means downloading a ~10 MB CSV and Ctrl+F-ing it for every application. That breaks in predictable ways:

  • Trading names vs legal names. Job ads use the brand; the register uses the legal entity, often as LEGAL NAME LTD T/A Brand. sponsor-check indexes both halves.

  • Inconsistent data entry. CAKE GLORY LTD LTD, F-Secure (UK) Limited, 2i Limited vs 2I LIMITED. Names are normalised (case, punctuation, legal suffixes, accents, &) before matching.

  • One row per route. The same employer appears once per visa route. Results are grouped per organisation, with each route and its A/B rating.

  • Downgraded licences. B-rated and provisional licences are flagged, because they change what you should ask the employer.

Related MCP server: SponsorFinder MCP Server

Use it from Claude

Claude Code

claude mcp add sponsor-check -- sponsor-check-mcp

Claude Desktop (claude_desktop_config.json)

{
  "mcpServers": {
    "sponsor-check": { "command": "sponsor-check-mcp" }
  }
}

Then ask things like "Can Octopus Energy sponsor a Skilled Worker visa?" or paste a job ad and ask whether the employer is on the register.

Tool

What it does

check_sponsor(company, route="Skilled Worker")

Verdict: licensed, licensed_other_routes, possible_match or not_found, with evidence and caveats

search_sponsors(query, limit=5)

Ranked fuzzy matches with routes and ratings

check_salary(salary, soc_code, new_entrant=False)

Verdict: meets, below, occupation_ineligible, going_rate_unavailable or unknown_occupation, with the rule that applied and the lower rates the job could qualify for

register_info()

Register and thresholds dates, sizes and GOV.UK source URLs

All tools are read-only.

Command line

pip install git+https://github.com/sauravss98/sponsor-check
sponsor-check update                                   # download today's register
sponsor-check check "Octopus Energy"                   # exit code 0 only if licensed
sponsor-check check "Mode Agence" --route "Creative Worker"
sponsor-check search "octopus" -n 10 --json
sponsor-check salary 45000 2136                        # exit code 0 only if the salary meets it
sponsor-check salary 62000 1111 --new-entrant --json

The register is cached in ~/.cache/sponsor-check (override with SPONSOR_CHECK_HOME) and refreshed automatically when it is more than 24 hours old. If GOV.UK is unreachable, the last good copy is used.

How it works

GOV.UK Content API ──► find today's CSV URL ──► download (atomic swap)
                                                     │
                                                     ▼
                         parse ► group rows by organisation ► SQLite
                                        │
                           aliases: full name, legal part, trading part(s)
                                        │
query ► normalise ► exact alias lookup ─┴─► RapidFuzz WRatio over aliases ► verdict
  • The CSV link changes with every publication, so it is discovered through the GOV.UK Content API, with an HTML fallback.

  • Exact alias hits score 100. Fuzzy hits are capped at 99 so a guess is never reported as a confirmed licence; names that start with the query get a boost.

  • Verdict bands: 100 = licensed, 90 to 99 = possible_match, below that = not_found (closest names still shown).

Salary thresholds

The salary requirement is the higher of a flat general threshold and the occupation's going rate, and both move with the Immigration Rules. No figure is hardcoded: they are scraped from the published GOV.UK guidance into src/sponsor_check/data/thresholds.json, which records the source URL and publication date of every table it used. Every answer repeats that date, names the rule that produced it, and lists the lower rates the job could qualify for, such as the new entrant, PhD, immigration salary list and temporary shortage list rates.

Refresh the data after a rules change with python scripts/refresh_thresholds.py, then commit the diff. The script fails loudly rather than writing a half-empty file if a page changes shape.

Web app

Try it at sponsor-check.onrender.com. A React frontend in web/ talks to a small FastAPI wrapper (src/sponsor_check/api.py) over the same register.py/salary.py logic the CLI and MCP server use, so all three surfaces always agree.

pip install -e ".[dev]"
sponsor-check-api          # http://127.0.0.1:8000

cd web
npm install
npm run dev                # http://localhost:5173, proxies /api to the server above

See web/README.md for more.

Deploying

The Dockerfile builds everything into one container: FastAPI serves /api and the built frontend from the same origin, so no CORS setup is needed. The register is downloaded at build time, so a cold start serves straight away, and the running server refreshes it in the background once it is more than 24 hours old.

docker build -t sponsor-check .
docker run -p 8000:8000 sponsor-check     # http://localhost:8000

render.yaml deploys it to Render's free tier: in the Render dashboard choose New > Blueprint and pick this repository. Free services sleep when idle, so the first visit after a quiet spell takes a little while to wake up.

Development

pip install -e ".[dev]"
pytest

Tests run against a fixture of real rows taken from the published register, plus clearly fictional Example ... rows for the B-rated case. They are offline: the salary tests read the committed thresholds file, and scripts/refresh_thresholds.py is the only thing that talks to GOV.UK at build time.

Roadmap

  • Salary check against Skilled Worker thresholds by occupation code

  • Web app: FastAPI + React frontend, live at sponsor-check.onrender.com

  • check_job tool: extract employer and salary from a pasted job ad, run both checks

  • Companies House lookup to resolve brand names to legal entities

  • Publish to PyPI and the MCP registry

Disclaimer

Not legal or immigration advice. A licence means an employer can sponsor, not that it will sponsor a particular role. Always confirm with the employer.

Register data and salary thresholds: UK Visas and Immigration, published on GOV.UK under the Open Government Licence v3.0. Code: MIT.

Available Tools

4 tools
check_salaryA
Read-only

Check a salary against the Skilled Worker salary requirement for an occupation.

The requirement is the higher of a general threshold and the occupation's published going rate, so both the salary and the occupation code are needed.

Args: salary: Gross annual salary offered, in pounds. soc_code: 4-digit SOC 2020 occupation code for the job, e.g. "2136". Ask the user or the employer for it; do not guess a code from the job title. new_entrant: True if the applicant qualifies for the new entrant rate, e.g. under 26, a recent UK student or graduate, in professional training, or in an eligible postdoctoral role.

Returns a verdict (meets, below, occupation_ineligible, going_rate_unavailable, unknown_occupation), the required salary and the rule that produced it, the other discount options the job could qualify under, and the date the thresholds were published.

ParametersJSON Schema
NameRequiredDescriptionDefault
salaryYes
soc_codeYes
new_entrantNo

TDQS

A4.8/5.0
Behavior5/5

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

Annotations already mark this as read-only and not open-world, but the description adds substantial behavioral context: the full set of possible verdicts, the required salary and rule that produced it, other applicable discount options, and the threshold publication date. There is no contradiction with the annotations.

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 purpose is front-loaded, then Args and Returns are cleanly separated. The length is justified by the domain complexity and the absence of an output schema; every sentence adds useful meaning without filler.

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

Completeness5/5

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

Given no output schema, zero schema descriptions, and minimal annotations, the description supplies everything an agent needs to invoke the tool correctly: required inputs, new_entrant semantics, return structure, and relevant domain context. No material gap remains.

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?

With 0% schema description coverage, the description carries the full burden and succeeds: salary is defined as gross annual salary in pounds, soc_code is specified as a 4-digit SOC 2020 code with an example and explicit warning not to guess from job title, and new_entrant is explained with eligibility conditions.

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?

The description names a specific verb and resource: checking a salary against the Skilled Worker salary requirement for an occupation. It clearly distinguishes this from sibling tools like check_sponsor and search_sponsors, which concern sponsor/register information rather than salary thresholds.

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?

It explains that both salary and occupation code are required and gives clear conditions for the new_entrant flag, including under 26, recent UK student/graduate, professional training, and eligible postdoctoral roles. It also instructs the agent to ask the user or employer for the SOC code rather than guessing, though it does not explicitly name when-not-to-use cases or alternatives.

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

check_sponsorA
Read-only

Check whether a UK employer is licensed to sponsor visas on a given route.

Args: company: Employer name as it appears in a job ad (legal or trading name). route: Visa route, e.g. "Skilled Worker" (default), "Global Business Mobility: Senior or Specialist Worker", "Scale-up", "Creative Worker".

Returns a verdict (licensed, licensed_other_routes, possible_match, not_found), the matching register entries with their routes and A/B ratings, and caveats.

ParametersJSON Schema
NameRequiredDescriptionDefault
routeNoSkilled Worker
companyYes

TDQS

A4.2/5.0
Behavior4/5

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

Annotations already cover the read-only, closed-world safety profile, and the description adds real behavioral value: the four possible verdicts (licensed, licensed_other_routes, possible_match, not_found), the fact that register entries carry routes and A/B ratings, and that caveats are returned. It omits timing/rate-limit behavior but is otherwise informative.

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?

Front-loaded purpose sentence followed by clearly labeled Args and Returns blocks, with no filler. The route example list is the longest element but is directly actionable, so little is wasted.

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

Completeness5/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 fully compensates by enumerating the verdict values and the returned register data plus caveats. An agent has enough to select and call the tool and to interpret the response correctly.

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 carries the full burden and mostly does: it clarifies company should be the name as it appears in a job ad (legal or trading name) and gives concrete route values plus the default. It does not state matching/fuzzy-matching tolerance or name-normalization expectations, which matters for a lookup tool.

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+scope: checking whether a UK employer is licensed to sponsor visas on a given route. The verdict taxonomy in the Returns block makes it clearly a point-lookup tool, distinct from the sibling search_sponsors bulk-search 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?

Usage is implied rather than stated: an agent can infer this is the single-employer verification call and search_sponsors is the discovery call, but neither the alternative nor the conditions selecting it are named. No when-not guidance or prerequisites are given.

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

register_infoB
Read-only

Dates and sources of the loaded data: the sponsor register and the salary thresholds.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

B3.2/5.0
Behavior3/5

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

Annotations declare readOnlyHint=true and openWorldHint=false, covering the safety profile. The description adds domain context—that the data concerns dates/sources for the sponsor register and salary thresholds—but does not describe return format, permissions, or other behavioral traits beyond the annotations.

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 description is a single compact sentence with no filler. It front-loads the returned data categories, though the missing verb makes the structure slightly less scannable.

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 zero-parameter, read-only metadata tool with annotations and no output schema, the description conveys the essential return content (dates and sources). It could specify the return shape more explicitly, but it is largely complete for invocation.

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 and schema coverage is 100% (empty object). With no parameters to document, the description does not need to add parameter semantics; baseline 4 applies.

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

Purpose3/5

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

The description names the information returned (dates and sources of loaded data) and the data domains (sponsor register, salary thresholds), but it does not use a verb to say what action the tool performs. It is more specific than a tautology but remains a noun phrase that leaves the operation implicit.

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?

No when-to-use guidance is provided, and the sibling tools (check_sponsor, search_sponsors, check_salary) are never mentioned as alternatives or complements. The agent must infer that this is for metadata inspection rather than lookups.

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

search_sponsorsB
Read-only

Fuzzy-search the register and return the closest organisations, best first.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
queryYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3/5.0
Behavior3/5

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

Annotations already declare readOnlyHint=true and openWorldHint=false, so safety is covered. The description adds genuinely useful behaviors beyond that: results are approximate ('fuzzy') and ordered by closeness ('best first'). It says nothing about how many are returned by default or what happens on no match.

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?

A single front-loaded sentence with the action and result ordering stated first and no filler. Efficient, though very terse for the amount of undocumented surface area.

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?

An output schema exists so return values need no explanation, and the readOnly annotation covers safety. However, with two undocumented parameters and no guidance on query format or limit behavior, the definition is only minimally complete 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?

Schema coverage is 0%, so the description must carry the load. It implies the 'query' is matched fuzzily against the register but never states what the query string represents (name, registration number, etc.), nor does it mention the 'limit' parameter or the default of 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?

Specific verb+resource: 'Fuzzy-search the register' returns 'the closest organisations, best first.' An agent can distinguish this approximate-match search from the 'check_*' siblings. It stops short of naming a sibling explicitly, but the verb and scope are unambiguous.

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?

The word 'fuzzy' hints that this is for approximate matching, but there is no explicit when-to-use, when-not-to-use, or reference to the alternatives (check_sponsor, register_info). The agent is left to infer that an exact-lookup sibling should be preferred when a precise identifier is known.

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. 4 tool updatesv0.1.0
    • First observedcheck_salary
    • First observedcheck_sponsor
    • First observedregister_info
    • First observedsearch_sponsors

TDQS

A3.6/5.0

Scored across 4 tools

Disambiguation4/5

check_sponsor and search_sponsors both query the register and could be momentarily confused, but check_sponsor returns a verdict while search_sponsors returns ranked candidates, and the descriptions make this distinction clear. check_salary and register_info are clearly distinct.

Naming Consistency4/5

check_sponsor, check_salary, and search_sponsors follow a verb_noun pattern, but register_info breaks it with a noun-only name and there's a minor plural inconsistency (sponsor vs sponsors). Still largely predictable and readable.

Tool Count4/5

Four tools is a tight, well-scoped set for a focused sponsor/salary checking domain, with little redundancy. It sits slightly at the thin end but each tool earns its place.

Completeness4/5

The surface covers the key workflows: verifying a sponsor, fuzzy-discovering registered sponsors, validating salary against SOC codes, and checking data provenance. Minor gaps like route enumeration or bulk checking exist but core agent workflows are supported.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables searching and analyzing H-1B visa sponsoring companies using U.S. Department of Labor data. Supports filtering by job role, location, and salary with natural language queries to find direct employers and export results.
    17
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables querying the Dutch IND public register of recognised sponsors for work/residence permits. Offers tools to search sponsors by name or KvK number and check register status.
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    An MCP server that lets AI assistants search the UK Register of Licensed Visa Sponsors (125,000+ companies), enabling queries about company sponsorship, location, visa routes, and ratings.
    1
    MIT