Glassdoor MCP Server
Allows searching Glassdoor job listings by keyword and location, and reading full job postings with salary details, employer ratings, and requirements.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Glassdoor MCP ServerFind senior software engineer jobs in Austin, TX with salary details"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Glassdoor MCP Server
A hosted Model Context Protocol (MCP) server that gives Claude, Cursor, Windsurf and any other MCP client two read-only Glassdoor tools. Search job listings by keyword and location, then read one posting in full with the employer rating, the salary figure and its provenance, both as structured JSON, with no Glassdoor partner account and nothing to host.
It reads public Glassdoor job pages that a signed-out visitor can see, on the US site and 22 regional ones.
1,000 free credits every month, no card required, which is 100 Glassdoor calls at the 10-credit rate.
https://mcp.hasdata.com/api/mcp?apis=glassdoor
Contents
Related MCP server: iCIMS Careers API
What you need
An MCP client and a HasData API key from the dashboard, free to create with no card, and the free tier covers about 100 calls a month at the 10-credit rate. This is a remote server, so the simplest path is a URL and an x-api-key header, with no container to run. A client that only speaks stdio reaches it through a thin launcher, published as @hasdata/glassdoor-mcp on npm and hasdata-glassdoor-mcp on PyPI, shown below.
Quick start
The server URL is the same for every client. We run it hands-on in Claude Code and Claude Desktop. The other blocks follow each client's own documented format for a remote server.
Field | Value |
URL |
|
Transport | HTTP, streamable |
Auth header |
|
Clients with OAuth support can add the same URL as a connector and sign in without putting a key in a config file.
claude mcp add --transport http glassdoor "https://mcp.hasdata.com/api/mcp?apis=glassdoor" \
--header "x-api-key: HASDATA_API_KEY"Settings, then Connectors, then Add custom connector, then paste https://mcp.hasdata.com/api/mcp?apis=glassdoor and sign in.
For the config-file route, Claude Desktop loads only local (stdio) servers, so it reaches a remote server through a stdio launcher. The @hasdata/glassdoor-mcp package is that launcher, and it reads the key from the environment. Add this to claude_desktop_config.json:
{
"mcpServers": {
"glassdoor": {
"command": "npx",
"args": ["-y", "@hasdata/glassdoor-mcp"],
"env": { "HASDATA_API_KEY": "YOUR_KEY" }
}
}
}For Python instead of Node, swap the launcher for the PyPI package, which uvx runs without a manual install:
{
"mcpServers": {
"glassdoor": {
"command": "uvx",
"args": ["hasdata-glassdoor-mcp"],
"env": { "HASDATA_API_KEY": "YOUR_KEY" }
}
}
}~/.cursor/mcp.json for every project, or .cursor/mcp.json for one:
{
"mcpServers": {
"glassdoor": {
"url": "https://mcp.hasdata.com/api/mcp?apis=glassdoor",
"headers": { "x-api-key": "HASDATA_API_KEY" }
}
}
}~/.codeium/windsurf/mcp_config.json. Windsurf calls the field serverUrl, not url:
{
"mcpServers": {
"glassdoor": {
"serverUrl": "https://mcp.hasdata.com/api/mcp?apis=glassdoor",
"headers": { "x-api-key": "HASDATA_API_KEY" }
}
}
}.vscode/mcp.json in the workspace:
{
"servers": {
"glassdoor": {
"type": "http",
"url": "https://mcp.hasdata.com/api/mcp?apis=glassdoor",
"headers": { "x-api-key": "HASDATA_API_KEY" }
}
}
}Example prompts
Each of these lands on one tool, or on two in sequence when the second needs the URL the first returns.
Find data engineer roles in Austin, TX and show me only the ones where the employer stated the salary.
What is the median posted salary for this role in Austin, and how many postings did that come from?
Read this Glassdoor posting in full and list the required qualifications.
Which companies hiring for this role have an employer rating above 4?
Show me postings for this role added in the last week, sorted by recency.
Compare posted salaries for this role on the UK and the German Glassdoor sites.
A prompt that names a role goes to the listing tool, and reading the full description takes a second call per posting. The listing already carries the salary, the employer rating and the skills, so a comparison across many roles needs one call rather than one per posting.
Tools
Two tools, 10 credits per successful call.
Get Glassdoor job listings
hasdata_glassdoor_listing_getJobListings
A page of postings for a role in a place, 30 to a page.
Parameter | Type | Required | Notes |
| string | yes | The role to search for, such as |
| string | yes | Where to search, such as |
| string |
| |
| string | One of 22 regional Glassdoor sites | |
| string | Cursor for the next page, taken from the previous response |
Returns searchInformation with totalResults and the Glassdoor URL behind the query, a jobs array, and pagination.
Each posting carries title, id, url, location, ageInDays, sponsored, a skills array, a description snippet, a salary object and an employer object with its own rating and logoUrl.
The salary object is the reason this tool is worth more than a job board feed. It reports min, median, max, currency, period and, decisively, source, which is either EMPLOYER_PROVIDED or ESTIMATED. The first is a figure the employer published, the second is Glassdoor's own model. In the sample below, 19 of 30 postings were employer-provided and 10 estimated.
{
"title": "Data Engineer",
"id": 1010220057561,
"url": "https://www.glassdoor.com/job-listing/data-engineer-esc-region-xiii-JV_IC1139761_KO0,13_KE14,29.htm?jl=1010220057561",
"location": "Austin, TX",
"ageInDays": 36,
"sponsored": false,
"skills": ["Azure", "Customer service", "System design"],
"salary": {
"currency": "USD",
"period": "ANNUAL",
"min": 82572,
"median": 82572,
"max": 82572,
"source": "EMPLOYER_PROVIDED"
},
"employer": {
"id": 477452,
"name": "Education Service Center Region XIII",
"shortName": "ESC Region XIII",
"rating": 4.2,
"sponsored": false
}
}Get Glassdoor job details
hasdata_glassdoor_job_getJobDetails
One posting in full, by its Glassdoor URL.
Parameter | Type | Required | Notes |
| string | yes | The posting URL, as the listing tool returns it |
Returns a job object. On top of the title, salary and employer the listing already gave you, it adds the full description as plain text, the same text as descriptionHtml, a requirements object holding educationRequirements and an experienceRequirements array, an address object with coordinates, datePosted, and an expired flag.
{
"title": "Data Engineer",
"employer": {
"name": "ESC Region XIII",
"url": "https://www.glassdoor.com/Overview/Working-at-ESC-Region-XIII-EI_IE477452.11,26.htm"
},
"address": {
"country": "United States",
"region": "Texas",
"city": "Austin, TX",
"latitude": 30.26694,
"longitude": -97.74278
},
"requirements": {
"educationRequirements": "Bachelor's degree",
"experienceRequirements": ["Azure", "Customer service", "System design", "Windows", "SQL", "AWS"]
},
"salary": {
"payCurrency": "USD",
"period": "ANNUAL",
"min": 82572,
"median": 82572,
"max": 82572,
"source": "EMPLOYER_PROVIDED"
},
"datePosted": "2026-09-03T00:00:00",
"ageInDays": 36,
"expired": false
}Errors and failure paths
Plan for these rather than assuming a happy path.
salary.source decides whether the figure is a fact or a model output. EMPLOYER_PROVIDED came from the posting. ESTIMATED is Glassdoor's own estimate for the role and market, and mixing the two into one median produces a number that describes neither. Filter on source before you aggregate, and say which set a published figure came from.
A single stated salary arrives as min, median and max all equal. Three of the 30 postings in the sample looked like that. A range of zero is a point figure, not a missing range.
salary can be absent, and period can be HOURLY rather than ANNUAL. One posting in the sample carried no salary at all. Converting hourly to annual is your assumption to make, not something the response does.
The listing description is a truncated snippet. Eighteen of the 30 samples ended mid-sentence with an ellipsis. The full text is only on the detail tool, so a prompt that reads descriptions costs one call per posting.
Pagination is token-based, and otherPages holds tokens rather than page URLs. pagination.otherPages maps a page number to an opaque base64 token, and that token is what goes into nextPageToken. Keep the other parameters unchanged while paging.
www.glassdoor.com is the default and is not a value you can pass. The domain enum lists the 22 regional sites, so the US site is what you get when you leave domain off. There is nothing to send for it.
expired is on the detail tool only. A listing page can still show a posting the employer has closed, and only the detail call reports it. Check the flag before you act on an old ageInDays.
A salary figure and an employer rating are Glassdoor's numbers. They come from Glassdoor's own data and models, so attribute them rather than presenting them as market truth.
Results that carry data also carry a requestMetadata.id worth quoting in support.
Pricing, free tier and limits
Each Glassdoor tool costs 10 credits per successful call. Response size does not change the price, so a 30-posting page costs the same as a single detail call, which makes the listing tool the cheap way to cover a market and the detail tool the expensive way.
The free tier is 1,000 credits every month with no card, which is 100 Glassdoor calls at the base rate. It renews with the billing cycle, so a low-volume agent runs on the free tier indefinitely.
Paid plans start at $49 a month for 200,000 credits, which is 20,000 calls. The unit price falls with volume, from $2.45 per 1,000 calls on the entry plan to $1.00 on Business, $0.84 on Growth and $0.74 on the largest high-volume plans.
Your plan also sets concurrency. The free tier allows 1 request at a time, Startup 15, Business 30, Growth 50, and the high-volume plans run from 200 to 1,500. Retry on the 429 with a backoff in anything unattended, because an agent that walks a page of postings will reach the ceiling before you do.
A request that comes back non-200 is not billed. A successful call that finds nothing is still a call.
A note on cost per answer. Thirty postings arrive for 10 credits, and reading all thirty in full costs 300 more. Most comp and hiring questions are answerable from the listing alone, so reach for the detail tool per posting rather than per page.
Tool selection
Start from what the prompt gives you. A role and a place go to the listing tool, and a Glassdoor URL goes straight to the detail tool.
Then ask what the answer needs. Salary, employer rating, skills, location and age all arrive with the listing, which covers comp benchmarking, hiring-trend monitoring and sourcing shortlists in one call. The detail tool exists for the full description and the stated qualifications, which is what a matching or resume-tailoring pipeline needs and what a market summary does not.
How it compares
Glassdoor has no public jobs API, so the honest comparison is against a job board feed and against Glassdoor's own site.
A job board feed | Glassdoor on the site | This server | |
Eligibility | A partner agreement per board | A browser and a login prompt | An API key |
Employer rating | Not included | Shown | On every posting |
Salary provenance | Rarely stated | Shown |
|
Skills tags | Board-dependent | Shown | An array per posting |
Regional sites | Separate integrations | Separate sites | A parameter |
Structured output | Feed-dependent | None | JSON |
The row that decides it is salary provenance. Comp work falls apart when an employer figure and a modelled estimate land in the same column, and this is the field that keeps them apart.
FAQ
Is there an official Glassdoor MCP server?
Glassdoor does not publish one, and it does not publish a public jobs API either. This one is maintained by HasData and reads public Glassdoor pages.
What is a Glassdoor MCP server?
An MCP server exposes tools an AI client can call. This one turns Glassdoor job searches and postings into JSON an agent can reason over, without a browser or a scraping library in your stack.
Do I need a Glassdoor account?
No. The only credential is your HasData key.
Are the salaries real or estimated?
Both, and the response says which. salary.source is EMPLOYER_PROVIDED for a figure the employer published and ESTIMATED for Glassdoor's own model. Read that field before you average anything.
Does it return company reviews?
No. These two tools cover job listings and postings. The employer object carries the aggregate rating Glassdoor shows next to a company name, and review text is not part of the response.
Which countries are covered?
The US site by default, plus 22 regional ones from www.glassdoor.co.uk through www.glassdoor.co.in, www.glassdoor.com.au and the language-split Belgian, Canadian and Swiss sites. Pass domain to switch.
How do I page through results?
Take the token for the page you want from pagination.otherPages and send it as nextPageToken, leaving keyword, location and sort unchanged.
Can I use this together with other HasData APIs?
Yes. One key covers everything, and one endpoint serves them all through the apis parameter. Point a client at ?apis=glassdoor,indeed to get both tool sets in one connection, or at mcp.hasdata.com/api/mcp for the full catalogue.
Is HasData affiliated with Glassdoor?
No. HasData is an independent service and is not affiliated with, endorsed by, or sponsored by Glassdoor. Glassdoor is a trademark of its respective owner. The tools work with publicly available data only, and you are responsible for using the results in line with Glassdoor's terms and the law that applies to you.
Compliance and personal data
Job postings are business records, and these tools return no candidate or reviewer data. Two things still need care. Employer ratings and salary estimates are Glassdoor's own aggregates, so republishing them without attribution misrepresents whose numbers they are. And a posting at a very small employer can name a person as the contact, which is the one place personal data appears.
HasData links
Glassdoor Scraper API, the REST endpoints behind these tools
Other HasData MCP servers: Indeed, Google Search, Google Maps, Google Trends, Google Flights, DuckDuckGo, YouTube, TikTok, Instagram, Amazon, Walmart, Shopify, Yelp, Zillow, Redfin, Airbnb, Booking.com.
Development
The launcher is a thin stdio bridge to the remote server, so there is nothing to build.
npm install
HASDATA_API_KEY=your_key_here npm testThe tests in test/ assert the tool contract, the part that can break without a commit here. They check that ?apis=glassdoor returns the expected tool count, that no name changed, that every tool still declares its required parameters and carries a description, that sort still offers both orders, and that the key in use is actually accepted. That last check calls a tool for real and costs 10 credits, which is the price of a canary that can fail for the right reason.
One test asserts that a live posting still carries salary.source. The README leans on that field to keep employer figures apart from estimates, and a response that quietly dropped it would leave the advice standing with nothing behind it.
The contract suite also runs weekly on a schedule, because the upstream tool list can change without anyone touching this repository.
Contributing
A tool table, a response sample or a documented behaviour that does not match reality is worth an issue. There is a template for exactly that. Pull requests are welcome for the same, and for anything in the launcher.
License
MIT, see LICENSE.
Available Tools
2 toolshasdata_glassdoor_job_getJobDetailsglassdoor_job: GET /AInspect
Get GlassDoor Job Details
Fetches a Glassdoor job posting by its vacancy URL. Returns job title, company name and rating, location, salary estimate, employment type, posted date, full job description, qualifications/benefits, and apply link. Use for ATS ingestion, job aggregators, comp benchmarking, enrichment of company profiles, and feeding descriptions into LLM matching or resume-tailoring pipelines.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | The URL of the job vacancy to retrieve details for. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden of explaining behavior. It does list the returned fields and suggests practical use cases, but it does not mention potential limitations, error behavior, authentication, or rate limits. This is adequate for a simple fetch operation but not fully transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is reasonably concise and well-structured: a clear action sentence, a list of returned fields, and a list of use cases. The use-case list is somewhat broad but not excessive, and every sentence contributes useful context.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter tool with no output schema, the description gives enough context to invoke it correctly: what URL to provide, what data will be returned, and common scenarios where it is useful. It does not overpromise or omit critical invocation details.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The only parameter, 'url', is fully described in the schema as 'The URL of the job vacancy to retrieve details for.' The tool description largely repeats this and adds no new parameter-level details, so the description adds minimal value beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States the specific action ('Fetches a Glassdoor job posting by its vacancy URL'), the resource (Glassdoor job posting), and the scope (details by URL). This clearly distinguishes it from the sibling listing tool and other job detail tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains when to use the tool ('by its vacancy URL') and lists relevant use cases such as ATS ingestion, job aggregation, and LLM matching. It does not explicitly name the alternative listing tool or say 'use this when you already have a URL', but the condition is strongly implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
hasdata_glassdoor_listing_getJobListingsglassdoor_listing: GET /AInspect
Get GlassDoor Job Listings
Searches Glassdoor job listings by keyword and location with sort (recent/relevant), domain targeting, and nextPageToken pagination. Returns an array of jobs with title, company, location, salary estimate, posted date, job URL, and jobId, plus the next page token. Use to build job feeds, monitor hiring trends for roles/companies/regions, power candidate sourcing tools, and collect URLs for downstream full-detail scraping via the Glassdoor Job endpoint.
| Name | Required | Description | Default |
|---|---|---|---|
| sort | No | The sorting option for the search results. | |
| domain | No | The domain of the Glassdoor site (optional). | |
| keyword | Yes | The keyword used to search for job listings. | |
| location | Yes | The location to search for job listings. | |
| nextPageToken | No | Token for fetching the next page of jobs. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description carries the burden. It discloses the return structure (array of jobs with specific fields and next page token) and pagination behavior. It does not mention authentication or rate limits, but for a read-only search tool this is acceptable; the description is not misleading.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, front-loaded with the core action and scoping. The return fields and use cases are listed efficiently with no filler. Each sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates by explaining the return array and pagination token. It covers purpose, usage, and routing to the details endpoint. It doesn't describe how to chain nextPageToken, but that's a minor gap given the clarity of the rest.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description merely echoes the parameters (sort, domain, nextPageToken) without adding new semantics or usage details beyond what the schema already states.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly identifies the resource (Glassdoor job listings) and action (get/search). It distinguishes from the sibling details endpoint by mentioning 'downstream full-detail scraping via the Glassdoor Job endpoint', and from other platforms (Indeed, etc.) by naming Glassdoor explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
States explicit use cases ('build job feeds, monitor hiring trends...') and points to the alternative for full details ('collect URLs for downstream full-detail scraping via the Glassdoor Job endpoint'). This gives clear when-to-use and when-not-to-use guidance.
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.
2 tool updates
v0.1.0- First observed
hasdata_glassdoor_job_getJobDetails - First observed
hasdata_glassdoor_listing_getJobListings
TDQS
Scored across 2 tools
The two tools have completely distinct purposes: one searches and returns job listings, the other fetches full details for a specific job by URL. There is no overlap or ambiguity between them.
Both tool names follow the same pattern: hasdata_glassdoor_<resource>_<verb>. The resource (job/listing) and action (getJobDetails/getJobListings) are clearly and consistently structured, despite using camelCase for the verb portion.
Two tools is on the low end, but for a narrowly scoped Glassdoor job data server, this pair covers the essential search-and-detail workflow. It feels appropriately minimal rather than incomplete.
The server covers the core job data lifecycle from discovery (listings with pagination) to retrieval (full details). For a read-only job data source, there are no obvious missing operations—the two endpoints form a complete workflow.
Maintenance
Related MCP Connectors
Indeed job listings by keyword and location, and full postings, as structured JSON.
Live job postings from 30+ ATS feeds and job boards, one schema. Live results need a Bearer key.
Scrape job listings from companies using Greenhouse ATS via a fast API.
Scrape job listings from Greenhouse, Workable, Reed, RemoteOK and other boards. Pay per row.
Related MCP Servers
AlicenseAqualityAmaintenanceDirect access to 40+ scraping and search tools. Extract structured data from Google (Search, Maps, Trends), Amazon, Airbnb, Social Media, and any web page directly into your AI agent.8425MIT- FlicenseNot gradedqualityCmaintenanceEnables users to retrieve live job postings from any iCIMS career site, providing structured data including title, requisition ID, employer, locations, employment type, dates, salary, and apply links.-
- AlicenseAqualityAmaintenanceEnables MCP clients to perform live Google searches and retrieve structured SERP data including organic results, AI Overviews, People Also Ask, AI Mode answers, news, shopping, and short-video results via eight read-only tools.2104787MIT
- AlicenseAqualityAmaintenanceEnables MCP clients to search Indeed job listings by keyword and location and retrieve full job postings as structured JSON, without requiring an Indeed developer account or partner approval.225023MIT