A live browser-based MCP server for checking H-1B visa sponsorship signals.
Project description
H1B MCP
Live H-1B sponsorship checks for Codex and other MCP-compatible agents.
h1b-mcp opens H1BGrader in a real browser, searches for companies, job
titles, and locations, extracts profile tables, and returns normalized
sponsorship signals with structured evidence.
This is an independent community project. It is not affiliated with, authorized by, endorsed by, or sponsored by H1BGrader.
Features
- Live H1BGrader company, job-title, and location lookup through SeleniumBase UC mode.
- Structured H-1B sponsor signal:
Strong signal,Mixed signal,Weak signal, orNo sponsor. - Parsed annual LCA approvals and denial counts.
- Parsed annual LCA approval and denial rates.
- Parsed annual USCIS H-1B approvals and denial counts.
- Parsed annual USCIS approval and denial rates.
- Parsed annual H-1B salary maximum, median, average, and minimum.
- Parsed H1BGrader grade, confidence, annual grades, and grade insight cards.
- Parsed latest H-1B job title counts and salary ranges.
- Parsed job-title and location aggregate profiles with top employers, LCA trends, approval rates, and salary history.
- Local caches so repeated checks can reuse parsed H1BGrader data.
- Typed Pydantic response models that are easy for agents to consume.
- Browser-block aware behavior that raises a clear tool error instead of inventing a sponsor conclusion.
Included Tools
All tools return typed structured content. MCP clients can inspect the full
input and output schemas through tools/list.
Company Tools
| Tool | Use |
|---|---|
check_h1b_sponsorship |
Classify company-level H-1B sponsorship evidence. |
check_company_job_sponsorship |
Check whether a company has sponsored evidence for a specific job title. |
get_company_role_sponsorship_context |
Combine company-specific and market-wide H-1B context for a role. |
get_company_profile |
Return the full parsed company profile for broader agent reasoning. |
get_company_job_titles |
Return sponsored job titles for a company. |
get_company_lca_trends |
Return annual company LCA approval and denial trends. |
get_company_uscis_trends |
Return annual company USCIS approval and denial trends. |
get_company_salaries |
Return annual H-1B salary history for a company. |
get_company_grade |
Return H1BGrader grade details for a company. |
Job Title Tools
| Tool | Use |
|---|---|
check_h1b_job_title_sponsorship |
Classify market-level H-1B sponsorship evidence for a job title. |
get_h1b_job_title_profile |
Return the full parsed job-title profile for broader agent reasoning. |
get_h1b_job_title_employers |
Return top H-1B sponsoring employers for a job title. |
get_h1b_job_title_lca_trends |
Return annual job-title LCA approval and denial trends. |
get_h1b_job_title_salary |
Return annual H-1B salary history for a job title. |
Location Tools
| Tool | Use |
|---|---|
check_h1b_location_sponsorship |
Classify city-level H-1B sponsorship evidence. |
get_h1b_location_profile |
Return the full parsed city profile for broader agent reasoning. |
get_h1b_location_employers |
Return top H-1B sponsoring employers for a city. |
get_h1b_location_lca_trends |
Return annual city LCA approval and denial trends. |
get_h1b_location_salary |
Return annual H-1B salary history for a city. |
Quick Start
Run the published package with uvx:
uvx h1b-mcp@latest
Lookups use SeleniumBase UC mode. The first lookup may download or prepare a compatible ChromeDriver automatically.
Codex Setup
Add the server to your Codex MCP config:
[mcp_servers.h1b]
command = "uvx"
args = ["h1b-mcp@latest"]
env = { UV_HTTP_TIMEOUT = "300" }
tool_timeout_sec = 300
Or add it from the CLI:
codex mcp add h1b --env UV_HTTP_TIMEOUT=300 -- uvx h1b-mcp@latest
Restart Codex and check /mcp to confirm the server is available.
Local Development Setup
Install dependencies:
uv sync
Run the server locally:
uv run h1b-mcp
Use a local checkout from Codex before publishing:
[mcp_servers.h1b]
command = "uv"
args = ["run", "--project", "/path/to/h1b-mcp", "h1b-mcp"]
tool_timeout_sec = 300
Usage
Ask your MCP client to check a company:
Check whether Databricks sponsors H-1B visas.
The MCP tool call is:
check_h1b_sponsorship(company_name="Databricks")
Example response shape:
{
"company_query": "Databricks",
"matched_company": "Databricks Inc",
"signal": "Strong signal",
"url": "https://h1bgrader.com/h1b-sponsors/databricks-inc-nokpn1vn04",
"evidence": [
"Latest LCA table reports 174 filings in fiscal year 2026, including 173 certified and 0 denied.",
"Latest non-empty USCIS table row reports 337 approvals and 0 denials in fiscal year 2025.",
"H1BGrader grade tab shows latest grade A with high confidence.",
"Job title table includes 56 sponsored title rows."
]
}
How It Works
View request flow diagram
flowchart TD
A[MCP client calls any H1B tool] --> B[FastMCP tool handler]
B --> C[tools.common run_tool or run_profile_tool]
C --> D[H1BGraderService]
D --> E{Profile type}
E --> F[get_company_profile]
E --> G[get_job_title_profile]
E --> H[get_location_profile]
F --> I{Fresh cache entry?}
G --> I
H --> I
I -->|Yes| J[Load typed profile from entity cache]
I -->|No| K[H1BGraderClient fetch_profile with lookup spec]
K --> L[Launch SeleniumBase UC homepage session]
L --> M[Open company, job-title, or city search tab]
M --> N[Type query into shared typeahead]
N --> O[Click selected dropdown result]
O --> P[Open profile tabs required by lookup spec]
P --> Q[Parse page source into typed profile model]
Q --> R[Write profile to matching cache]
J --> S[Focused response builder]
R --> S
S --> T{Requested slice}
T --> U[Sponsorship signal]
T --> V[Role context]
T --> W[Full profile]
T --> X[Employers or job titles]
T --> Y[LCA or USCIS trends]
T --> Z[Salaries or grade]
U --> AA[Return structured Pydantic output]
V --> AA
W --> AA
X --> AA
Y --> AA
Z --> AA
K --> AB{Cloudflare or lookup failure?}
AB -->|Browser block or lookup failure| AC[Raise MCP tool error with clear message]
- A FastMCP tool receives a company, job-title, or location request.
- The shared tool runner creates an
H1BGraderServiceand logs progress through the MCP context. - The service selects the matching profile cache and checks for a fresh parsed profile.
- On cache hit, the typed cached profile goes straight to the response builder.
- On cache miss, the SeleniumBase UC client opens H1BGrader and runs the lookup spec for the requested entity type.
- The lookup spec selects the correct search tab, typeahead input, expected URL pattern, tabs to open, and parser.
- Parsers extract the available LCA, USCIS, salary, grade, job-title, or employer data into typed profile models.
- The service stores the parsed profile in the matching local cache for later tool calls.
- The requested tool builds a focused Pydantic response from the same cached profile data.
- Browser blocks, missing suggestions, and unexpected lookup failures are surfaced as MCP tool errors with clear messages.
Signals
| Signal | Meaning |
|---|---|
Strong signal |
The profile contains recent, structured approval or filing evidence. |
Mixed signal |
The profile contains both sponsor and denial/no-sponsor indicators. |
Weak signal |
The profile has limited sponsorship evidence. |
No sponsor |
H1BGrader indicates the company is not a sponsor or no useful profile data was found. |
Browser Blocks
H1BGrader may still present human verification, rate limits, or other bot
protection. When that happens, h1b-mcp raises an MCP tool error with a clear
message instead of making a claim from memory.
The browser profile and caches are stored at:
~/.h1b-mcp/browser-profile
~/.h1b-mcp/cache/company-profiles
~/.h1b-mcp/cache/job-title-profiles
~/.h1b-mcp/cache/location-profiles
Current Scope
This project exposes company, job-title, and location tools backed by locally cached parsed H1BGrader profiles. It does not ship a bundled employer database or bulk scrape H1BGrader. H-1B source data is released periodically, so cached profile data is usually useful for repeated analysis rather than minute-by-minute freshness.
Troubleshooting
| Problem | What to try |
|---|---|
| First lookup is slow | Wait for SeleniumBase to prepare ChromeDriver and the browser profile. |
| Tool times out | Increase your MCP client tool_timeout_sec to 300. |
| Tool reports a browser block or lookup error | Retry later or verify manually on H1BGrader. The server intentionally avoids guessing. |
| Local server cannot start | Run uv sync, then retry uv run h1b-mcp. |
Development
Run the normal checks:
uv run ruff check .
uv run pyright
uv run pytest
uv build
Run tests only:
uv run pytest -q
Project Structure
.
├── .github/workflows/
│ └── publish.yml # Build, release, and PyPI publish workflow
├── src/h1b_mcp/
│ ├── h1bgrader/ # SeleniumBase browser client and lookup specs
│ ├── matchers/ # Local matching helpers, such as job-title matching
│ ├── models/ # Pydantic profile, response, and error models
│ ├── parsers/ # H1BGrader table, grade, summary, and aggregate parsers
│ ├── responses/ # Tool response builders for cached profiles
│ ├── tools/ # FastMCP tool registration by entity type
│ ├── cache.py # Generic disk cache for parsed profiles
│ ├── service.py # Cache/fetch orchestration layer
│ ├── server.py # FastMCP server entrypoint
│ └── settings.py # Runtime paths, timeouts, and cache settings
├── tests/ # Parser, cache, response, and MCP server tests
├── pyproject.toml # Package metadata, dependencies, and tool config
└── uv.lock # Locked dependency graph
Versioning
Version bumps use bumpver:
uv run bumpver update --patch --no-fetch
uv lock
Use --minor, --major, or --set-version 1.2.3 instead of --patch when
needed. bumpver is configured not to create commits, tags, or pushes.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file h1b_mcp-1.0.0.tar.gz.
File metadata
- Download URL: h1b_mcp-1.0.0.tar.gz
- Upload date:
- Size: 27.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e5433a5b045194a058135374c16319279323b7d2806d6fa902bd279d6245ff0e
|
|
| MD5 |
1b2844cf0d06a14d2bcc18e3b37619e6
|
|
| BLAKE2b-256 |
9de9e72327644bc5f952bd1c8bad2d7c5c8cc3d74fcd9aaed43435e3f253fb98
|
Provenance
The following attestation bundles were made for h1b_mcp-1.0.0.tar.gz:
Publisher:
publish.yml on Blacksuan19/h1b-mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
h1b_mcp-1.0.0.tar.gz -
Subject digest:
e5433a5b045194a058135374c16319279323b7d2806d6fa902bd279d6245ff0e - Sigstore transparency entry: 2075665493
- Sigstore integration time:
-
Permalink:
Blacksuan19/h1b-mcp@fd279b081ed1ff6207d9cf55f607e7a33169df0c -
Branch / Tag:
refs/tags/1.0.0 - Owner: https://github.com/Blacksuan19
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@fd279b081ed1ff6207d9cf55f607e7a33169df0c -
Trigger Event:
push
-
Statement type:
File details
Details for the file h1b_mcp-1.0.0-py3-none-any.whl.
File metadata
- Download URL: h1b_mcp-1.0.0-py3-none-any.whl
- Upload date:
- Size: 39.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
31490d8beb1ce4fbf323e442f8467f9ce9709fb38ef8fa90dfc2a0d452d17712
|
|
| MD5 |
20bcde74f684298887599e5d36745ab7
|
|
| BLAKE2b-256 |
7751f2b0c71a4d31f0f1856afdf3255cd7ced039967f1d0dd14b3b55e1dd551f
|
Provenance
The following attestation bundles were made for h1b_mcp-1.0.0-py3-none-any.whl:
Publisher:
publish.yml on Blacksuan19/h1b-mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
h1b_mcp-1.0.0-py3-none-any.whl -
Subject digest:
31490d8beb1ce4fbf323e442f8467f9ce9709fb38ef8fa90dfc2a0d452d17712 - Sigstore transparency entry: 2075665949
- Sigstore integration time:
-
Permalink:
Blacksuan19/h1b-mcp@fd279b081ed1ff6207d9cf55f607e7a33169df0c -
Branch / Tag:
refs/tags/1.0.0 - Owner: https://github.com/Blacksuan19
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@fd279b081ed1ff6207d9cf55f607e7a33169df0c -
Trigger Event:
push
-
Statement type: