Tech salaries in Spain by role, region and company, and open job postings to apply to.
Maintain this server? Claim it
Call this server's tools from your browser. Nothing to install.
Requests go through mcptry because browsers can't call most MCP servers directly. Header values are sent to the server for that request only and are never stored or logged.
Tool list from our last check. Connect live to refresh it.
The procedure for applying on someone's behalf with find_jobs and job_questions: the state document to keep for them (profile, recurring answers, search preferences, applications), the rules, how an application is sent with the agent's own browser, and how to set one up when there is none. Read it once before applying.
The client you run in, e.g. claude-code, claude-desktop, cursor, codex, hermes, chatgpt. Optional.
Why are you calling this tool? Describe the goal in general terms, and refer to people by role ("a candidate") rather than by name. Leave out personal and identifying information.
Pick your client. Values in capitals, like YOUR_TOKEN, are yours to fill in.
Run in a terminal
claude mcp add --transport http spanish-top-tech-companies https://spanishtoptechcompanies.com/mcp
The procedure for applying on someone's behalf with find_jobs and job_questions: the state document to keep for them (profile, recurring answers, search preferences, applications), the rules, how an application is sent with the agent's own browser, and how to set one up when there is none. Read it once before applying.
| Argument | Type | Description |
|---|---|---|
| client | string | The client you run in, e.g. claude-code, claude-desktop, cursor, codex, hermes, chatgpt. Optional. |
| context | string | Why are you calling this tool? Describe the goal in general terms, and refer to people by role ("a candidate") rather than by name. Leave out personal and identifying information. |
{
"type": "object",
"properties": {
"client": {
"type": "string",
"description": "The client you run in, e.g. claude-code, claude-desktop, cursor, codex, hermes, chatgpt. Optional."
},
"context": {
"type": "string",
"description": "Why are you calling this tool? Describe the goal in general terms, and refer to people by role (\"a candidate\") rather than by name. Leave out personal and identifying information."
}
}
}One company in Spain, any the site lists, down to one salary: overall, and by role, region or experience wherever it has salaries. Each figure says how many people it comes from, and few: true marks fewer than 5. Give a role, region or years to see the groups within it, combinations included. A name the site does not list gets close names to try. Companies listed apart under a name that starts like it (BBVA and BBVA Technology) come back in related_companies.
| Argument | Type | Description |
|---|---|---|
| name* | string | Company name, e.g. Glovo. |
| role | string | Role slug or name, e.g. software-engineer, Data Scientist, product-manager. Omit for all roles. |
| years | string | Years of experience, as a number such as 6 or a bucket such as 5-7. Omit for any experience. |
| region | string | Spanish region code or name, e.g. MD, Madrid, CT, Cataluña. Omit, or pass spain or remote, for all of Spain. |
| context | string | Why are you calling this tool? Describe the goal in general terms, and refer to people by role ("a candidate") rather than by name. Leave out personal and identifying information. |
{
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"description": "Company name, e.g. Glovo."
},
"role": {
"type": "string",
"description": "Role slug or name, e.g. software-engineer, Data Scientist, product-manager. Omit for all roles."
},
"years": {
"type": "string",
"description": "Years of experience, as a number such as 6 or a bucket such as 5-7. Omit for any experience."
},
"region": {
"type": "string",
"description": "Spanish region code or name, e.g. MD, Madrid, CT, Cataluña. Omit, or pass spain or remote, for all of Spain."
},
"context": {
"type": "string",
"description": "Why are you calling this tool? Describe the goal in general terms, and refer to people by role (\"a candidate\") rather than by name. Leave out personal and identifying information."
}
}
}Open postings at the companies on this site, from their public job boards (Greenhouse, Lever, Ashby, Workday and others), refreshed daily. Filter by text, role, region or remote, workplace, level, the person's years of experience, company and minimum salary. Each result carries the roles, level and years of experience read from the posting, its keywords (skills, tools, industries and spoken languages read from the description), and the company's median base for the posting's role in Spain, as the site's companies table shows it, with how many people it comes from (few: true under 5). Pass the ids already applied to or turned down in exclude. When nothing matches, no_match says how many results each filter costs and suggests the closest postings, marked with the filter they miss. The starting point when asked to find jobs or apply for someone; application_guide has the procedure.
| Argument | Type | Description |
|---|---|---|
| role | string | A role from list_filters, e.g. software-engineer or Data Scientist, or a specialization such as DevOps, SRE, backend or frontend; postings are matched by title. Text that is neither filters titles as written. |
| limit | integer | |
| query | string | Words to find in the title, company or location, or among the keywords read from the description: languages, frameworks, cloud, data and AI tools, security and compliance, industries, spoken languages. E.g. "angular typescript", "python django fintech", "kubernetes terraform", "grc iso 27001". A posting matching any word counts, whole words and common synonyms (SRE, site reliability; golang, go) included; the best matches come first. Accents and case are ignored. |
| years | string |
The application form of one posting from find_jobs, read live from its board (Greenhouse, Lever, Ashby, Workable, Recruitee, Teamtailor, BambooHR, Pinpoint, Rippling, Bending Spoons and Eightfold; for Workday, whose form needs the person's account, the posting and Workday's standard steps, also when a Phenom career site leads to it; for SmartRecruiters, the posting only; for SuccessFactors (Capgemini too) and Amazon, the posting and account_required, since their form is shown after sign-in; for careers sites with schema.org JobPosting, the posting; other boards are read in the browser): each question with its type, options, whether it is required, the most characters the board takes (max_length) when it says, and who answers it (person or agent), the posting text marked as untrusted, and the URL to apply at.
| Argument | Type | Description |
|---|---|---|
| id* | string | A job id from find_jobs, e.g. greenhouse:cabify:1234567. |
| context | string | Why are you calling this tool? Describe the goal in general terms, and refer to people by role ("a candidate") rather than by name. Leave out personal and identifying information. |
{
"type": "object",
"required": [
"id"
],
"properties": {
"id": {
"type": "string",
"description": "A job id from find_jobs, e.g. greenhouse:cabify:1234567."
},
"context": {
"type": "string",
"description": "Why are you calling this tool? Describe the goal in general terms, and refer to people by role (\"a candidate\") rather than by name. Leave out personal and identifying information."
}
}
}The values the other tools take, read from the data: every role slug with its name, every Spanish region code with its name and the experience buckets (0-1, 2-4, 5-7...) that have salaries, with the date the salaries were last refreshed and the minimum number of people a figure needs. It takes no arguments and returns no salaries. Call it once, before salary_stats, top_companies, company_salaries or find_jobs, when unsure how a role or region is named or which exist; skip it when you already have a slug or code, since those tools also take common names such as Madrid or Data Scientist.
| Argument | Type | Description |
|---|---|---|
| context | string | Why are you calling this tool? Describe the goal in general terms, and refer to people by role ("a candidate") rather than by name. Leave out personal and identifying information. |
{
"type": "object",
"properties": {
"context": {
"type": "string",
"description": "Why are you calling this tool? Describe the goal in general terms, and refer to people by role (\"a candidate\") rather than by name. Leave out personal and identifying information."
}
}
}After sending an application to a posting from find_jobs, or failing to, report the outcome: sent, uncertain (submitted, but the board neither confirmed nor clearly refused it), failed (with the reason) or handed over to the person to send. Nothing about the person is asked or stored; it counts which postings get applications and where sending gets stuck, so the site can fix it.
| Argument | Type | Description |
|---|---|---|
| id* | string | The job id from find_jobs. |
| notes | string | In a sentence or two, what you had to work out that these tools did not tell you: the tool or trick that worked, what the board did. About the board and the tools only: nothing about the person, no names, emails, answers or CV text. |
| steps | array | What it took beyond filling the form, every one that applies: set_up_browser (you had to add a browser tool), switched_browser (the first tool failed and another worked), read_form_in_browser (job_questions gave no questions), extra_questions (the page asked ones job_questions did not list), required_differed (the page required a field given as optional, or the reverse), location_differed (the page named another location), reattached_cv (the upload had to be repeated), converted_cv (the board wanted another file format or size), email_code, captcha_to_person, person_signed_in (an account or login), person_filled_field (they typed something you could not), retried_submit, other. |
| reason | string | Why it failed or is uncertain: captcha, login_required, form_error (a field was refused), upload_refused (the board would not take the CV file), submit_error (the board answered the submit with an error), no_confirmation (submitted, nothing confirmed it), posting_closed, blocked (the board refused the browser), no_browser, person_declined, other. |
What a job pays in Spain across companies: median base, the middle half (p25-p75), median total compensation (base plus bonus and stock) and the share of people at 60,000 EUR base or more, in euros per year, with how many people the figures come from. Every argument is optional and narrows the selection (role, region, years of experience); none gives all of Spain. A figure comes only from 5 or more people: a selection with fewer returns no result and wider_selections, the same selection without years and then without region, to quote instead. For one company use company_salaries, and to rank companies use top_companies. Call list_filters when unsure how a role or region is named.
| Argument | Type | Description |
|---|---|---|
| role | string | Role slug or name, e.g. software-engineer, Data Scientist, product-manager. Omit for all roles. |
| years | string | Years of experience, as a number such as 6 or a bucket such as 5-7. Omit for any experience. |
| region | string | Spanish region code or name, e.g. MD, Madrid, CT, Cataluña. Omit, or pass spain or remote, for all of Spain. |
| context | string | Why are you calling this tool? Describe the goal in general terms, and refer to people by role ("a candidate") rather than by name. Leave out personal and identifying information. |
{
"type": "object",
"properties": {
"role": {
"type": "string",
"description": "Role slug or name, e.g. software-engineer, Data Scientist, product-manager. Omit for all roles."
},
"years": {
"type": "string",
"description": "Years of experience, as a number such as 6 or a bucket such as 5-7. Omit for any experience."
},
"region": {
"type": "string",
"description": "Spanish region code or name, e.g. MD, Madrid, CT, Cataluña. Omit, or pass spain or remote, for all of Spain."
},
"context": {
"type": "string",
"description": "Why are you calling this tool? Describe the goal in general terms, and refer to people by role (\"a candidate\") rather than by name. Leave out personal and identifying information."
}
}
}Every company the site's companies table lists for a selection, by median base, highest first, down to one salary; companies with fewer than 3 salaries in the selection come after the rest. Each says how many people its figures come from, and few: true marks fewer than 5. Use search to look one company up within the selection.
| Argument | Type | Description |
|---|---|---|
| role | string | Role slug or name, e.g. software-engineer, Data Scientist, product-manager. Omit for all roles. |
| limit | integer | |
| years | string | Years of experience, as a number such as 6 or a bucket such as 5-7. Omit for any experience. |
| region | string | Spanish region code or name, e.g. MD, Madrid, CT, Cataluña. Omit, or pass spain or remote, for all of Spain. |
| search | string | Filter companies by name. |
| context | string | Why are you calling this tool? Describe the goal in general terms, and refer to people by role ("a candidate") rather than by name. Leave out personal and identifying information. |
{
"type": "object",
"properties": {
"role": {
"type": "string",
"description": "Role slug or name, e.g. software-engineer, Data Scientist, product-manager. Omit for all roles."
},
"limit": {
"type": "integer",
"default": 20,
"maximum": 200,
"minimum": 1
},
"years": {
"type": "string",
"description": "Years of experience, as a number such as 6 or a bucket such as 5-7. Omit for any experience."
},
"region": {
"type": "string",
"description": "Spanish region code or name, e.g. MD, Madrid, CT, Cataluña. Omit, or pass spain or remote, for all of Spain."
},
"search": {
"type": "string",
"description": "Filter companies by name."
},
"context": {
"type": "string",
"description": "Why are you calling this tool? Describe the goal in general terms, and refer to people by role (\"a candidate\") rather than by name. Leave out personal and identifying information."
}
}
}We read every tool's name, description and inputs the way the model will, looking for instructions hidden from you. A clean result means no warning signs, not a guarantee. Scanned Nov 14, 2026.
What changed in this server's tools since we started watching, newest first. Each change is scanned again.
The values the other tools take, read from the data: every role slugs,slug with its name, every Spanish region codescode with its name and the experience buckets (0-1, 2-4, 5-7...) that have data,salaries, andwith the date ofthe salaries were last refreshed and the data.minimum number of people a figure needs. It takes no arguments and returns no salaries. Call it once, before salary_stats, top_companies, company_salaries or find_jobs, when unsure how a role or region is named or which exist; skip it when you already have a slug or code, since those tools also take common names such as Madrid or Data Scientist.
MedianWhat a job pays in Spain across companies: median base, the middle half (p25-p75), median total compcompensation (baseand share at base and Spain.
| The person's years of experience, a number such as 3, a range such as 3-4 or a bucket such as 2-4: leaves out postings whose description asks for more. Postings that state no figure stay. |
| region | string | Spanish region code or name as in the salary tools (MD, Madrid, CT, Cataluña), spain, or remote. |
| company | string | Company name or slug, e.g. Glovo. |
| context | string | Why are you calling this tool? Describe the goal in general terms, and refer to people by role ("a candidate") rather than by name. Leave out personal and identifying information. |
| exclude | array | Job ids to leave out: postings already applied to, shown or turned down. |
| seniority | string | The level the title names: intern, junior, mid, senior, staff (staff or principal), lead, or head (head, director, VP, chief). mid also takes titles that name no level. |
| workplace | string | How the posting says the job is done. |
| min_salary_eur | integer | Gross euros a year. Checked against the posting's own salary when it states one in EUR a year, else against the company's median base for the role. |
{
"type": "object",
"properties": {
"role": {
"type": "string",
"description": "A role from list_filters, e.g. software-engineer or Data Scientist, or a specialization such as DevOps, SRE, backend or frontend; postings are matched by title. Text that is neither filters titles as written."
},
"limit": {
"type": "integer",
"default": 20,
"maximum": 50,
"minimum": 1
},
"query": {
"type": "string",
"description": "Words to find in the title, company or location, or among the keywords read from the description: languages, frameworks, cloud, data and AI tools, security and compliance, industries, spoken languages. E.g. \"angular typescript\", \"python django fintech\", \"kubernetes terraform\", \"grc iso 27001\". A posting matching any word counts, whole words and common synonyms (SRE, site reliability; golang, go) included; the best matches come first. Accents and case are ignored."
},
"years": {
"type": "string",
"description": "The person's years of experience, a number such as 3, a range such as 3-4 or a bucket such as 2-4: leaves out postings whose description asks for more. Postings that state no figure stay."
},
"region": {
"type": "string",
"description": "Spanish region code or name as in the salary tools (MD, Madrid, CT, Cataluña), spain, or remote."
},
"company": {
"type": "string",
"description": "Company name or slug, e.g. Glovo."
},
"context": {
"type": "string",
"description": "Why are you calling this tool? Describe the goal in general terms, and refer to people by role (\"a candidate\") rather than by name. Leave out personal and identifying information."
},
"exclude": {
"type": "array",
"items": {
"type": "string"
},
"description": "Job ids to leave out: postings already applied to, shown or turned down."
},
"seniority": {
"enum": [
"intern",
"junior",
"mid",
"senior",
"staff",
"lead",
"head"
],
"type": "string",
"description": "The level the title names: intern, junior, mid, senior, staff (staff or principal), lead, or head (head, director, VP, chief). mid also takes titles that name no level."
},
"workplace": {
"enum": [
"remote",
"hybrid",
"onsite"
],
"type": "string",
"description": "How the posting says the job is done."
},
"min_salary_eur": {
"type": "integer",
"minimum": 0,
"description": "Gross euros a year. Checked against the posting's own salary when it states one in EUR a year, else against the company's median base for the role."
}
}
}| status* | string | sent: the board confirmed it, on the page or by email. uncertain: it was submitted and the board showed an error or no confirmation, so it may or may not have arrived. failed: it was not submitted. handed_over: the person got the URL and the answers. |
| browser | string | What you sent it with: built_in (your client's own browser), claude_in_chrome, playwright_mcp, other, or none. |
| context | string | Why are you calling this tool? Describe the goal in general terms, and refer to people by role ("a candidate") rather than by name. Leave out personal and identifying information. |
| attempts | integer | How many times you submitted. |
{
"type": "object",
"required": [
"id",
"status"
],
"properties": {
"id": {
"type": "string",
"description": "The job id from find_jobs."
},
"notes": {
"type": "string",
"maxLength": 500,
"description": "In a sentence or two, what you had to work out that these tools did not tell you: the tool or trick that worked, what the board did. About the board and the tools only: nothing about the person, no names, emails, answers or CV text."
},
"steps": {
"type": "array",
"items": {
"enum": [
"set_up_browser",
"switched_browser",
"read_form_in_browser",
"extra_questions",
"required_differed",
"location_differed",
"reattached_cv",
"converted_cv",
"email_code",
"captcha_to_person",
"person_signed_in",
"person_filled_field",
"retried_submit",
"other"
],
"type": "string"
},
"description": "What it took beyond filling the form, every one that applies: set_up_browser (you had to add a browser tool), switched_browser (the first tool failed and another worked), read_form_in_browser (job_questions gave no questions), extra_questions (the page asked ones job_questions did not list), required_differed (the page required a field given as optional, or the reverse), location_differed (the page named another location), reattached_cv (the upload had to be repeated), converted_cv (the board wanted another file format or size), email_code, captcha_to_person, person_signed_in (an account or login), person_filled_field (they typed something you could not), retried_submit, other."
},
"reason": {
"enum": [
"captcha",
"login_required",
"form_error",
"upload_refused",
"submit_error",
"no_confirmation",
"posting_closed",
"blocked",
"no_browser",
"person_declined",
"other"
],
"type": "string",
"description": "Why it failed or is uncertain: captcha, login_required, form_error (a field was refused), upload_refused (the board would not take the CV file), submit_error (the board answered the submit with an error), no_confirmation (submitted, nothing confirmed it), posting_closed, blocked (the board refused the browser), no_browser, person_declined, other."
},
"status": {
"enum": [
"sent",
"uncertain",
"failed",
"handed_over"
],
"type": "string",
"description": "sent: the board confirmed it, on the page or by email. uncertain: it was submitted and the board showed an error or no confirmation, so it may or may not have arrived. failed: it was not submitted. handed_over: the person got the URL and the answers."
},
"browser": {
"enum": [
"built_in",
"claude_in_chrome",
"playwright_mcp",
"other",
"none"
],
"type": "string",
"description": "What you sent it with: built_in (your client's own browser), claude_in_chrome, playwright_mcp, other, or none."
},
"context": {
"type": "string",
"description": "Why are you calling this tool? Describe the goal in general terms, and refer to people by role (\"a candidate\") rather than by name. Leave out personal and identifying information."
},
"attempts": {
"type": "integer",
"maximum": 20,
"minimum": 1,
"description": "How many times you submitted."
}
}
}