{
  "markdown": "<img src=\"assets/icon-128.png\" alt=\"\" width=\"96\" align=\"right\">\n\n# mcp-ashby\n\n[![npm](https://img.shields.io/npm/v/mcp-ashby.svg)](https://www.npmjs.com/package/mcp-ashby)\n[![CI](https://github.com/smeet666/mcp-ashby/actions/workflows/ci.yml/badge.svg)](https://github.com/smeet666/mcp-ashby/actions/workflows/ci.yml)\n[![license](https://img.shields.io/npm/l/mcp-ashby.svg)](./LICENSE)\n[![MCP Registry](https://img.shields.io/badge/MCP_Registry-listed-6E56CF)](https://registry.modelcontextprotocol.io/v0/servers?search=io.github.smeet666/mcp-ashby)\n[![Glama](https://glama.ai/mcp/servers/smeet666/mcp-ashby/badges/score.svg)](https://glama.ai/mcp/servers/smeet666/mcp-ashby)\n[![M8ven](https://m8ven.ai/badge/mcp/smeet666-mcp-ashby-bavazc?variant=verified)](https://m8ven.ai/mcp/smeet666-mcp-ashby-bavazc)\n[![LobeHub](https://lobehub.com/badge/mcp/smeet666-mcp-ashby)](https://lobehub.com/mcp/smeet666-mcp-ashby)\n[![Install in Cursor](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/en/install-mcp?name=ashby&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIm1jcC1hc2hieSJdfQ%3D%3D)\n[![Install in VS Code](https://img.shields.io/badge/VS_Code-Install-0098FF?style=flat&logo=visualstudiocode&logoColor=white)](https://insiders.vscode.dev/redirect/mcp/install?name=ashby&config=%7B%22name%22%3A%22ashby%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22mcp-ashby%22%5D%7D)\n\n<!-- m8ven-verify: 73fc264cac412f1cc3ce6c59a1a1d662 -->\n\n[Ashby](https://www.ashbyhq.com) is recruiting software, and every company using\nit gets a public job board that comes with it. Each board carries that company's\nopen positions with their title, their department and team, the employment type,\nthe locations and whether the work is remote, the full advert, and, where the\ncompany chose to publish it, the pay: a salary range, an equity share, a\ncommission or a bonus, each with the period it is quoted over. Ashby holds one\nboard per company and publishes no index across them.\n\nThis server connects a chat client to those boards. You name the companies you\nare interested in, and it turns each name into the token that addresses its\nboard, searches their postings, filters them by department, team, location,\ncountry, employment type, remoteness, recency or pay, reads one posting in full,\nlists the words each board actually uses, and puts the pay of several postings\nside by side. It needs no API key and no account.\n\n_[Version française](#mcp-ashby-français)_\n\n---\n\n## Install\n\n**One-click install**\n\n[![Install in Cursor](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/en/install-mcp?name=ashby&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIm1jcC1hc2hieSJdfQ%3D%3D)\n[![Install in VS Code](https://img.shields.io/badge/VS_Code-Install-0098FF?style=flat&logo=visualstudiocode&logoColor=white)](https://insiders.vscode.dev/redirect/mcp/install?name=ashby&config=%7B%22name%22%3A%22ashby%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22mcp-ashby%22%5D%7D)\n\n**Claude Code**\n\n```bash\nclaude mcp add ashby -- npx -y mcp-ashby\n```\n\n**Claude Desktop, Cursor, and any client using the standard config format**\n\n```json\n{\n  \"mcpServers\": {\n    \"ashby\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"mcp-ashby\"]\n    }\n  }\n}\n```\n\nNode 24 or later is required, and no environment variable has to be set.\n\n### With Docker\n\n```json\n{\n  \"mcpServers\": {\n    \"ashby\": {\n      \"command\": \"docker\",\n      \"args\": [\"run\", \"-i\", \"--rm\", \"ghcr.io/smeet666/mcp-ashby:2.0.1\"]\n    }\n  }\n}\n```\n\n`-i` keeps stdin open, which is where the protocol travels, and `-t` is left out\nbecause a TTY rewrites the stream. The container needs outbound HTTPS to\n`api.ashbyhq.com`, and nothing else: no volume, no port, no credential.\n\n### Bundle, without npm\n\nDownload `mcp-ashby-2.0.1.mcpb` from\n[the latest release](https://github.com/smeet666/mcp-ashby/releases/latest) and\nopen it. A client that supports MCP bundles installs it on its own, with no npm\nand no configuration file to edit. The bundle carries its dependencies, so\nnothing is fetched at install time.\n\n## What you can ask\n\n- \"Is Ramp hiring on Ashby?\"\n- \"Find me remote design roles at Ramp and Linear.\"\n- \"Read me that posting in full.\"\n- \"What departments does that board file its jobs under?\"\n- \"Put the salaries of those engineering postings side by side.\"\n\nEvery question starts from a company, since Ashby offers no search across boards.\n`search_jobs` resolves the names you give it, so no preparation is needed:\n\n```\nresolve_board([\"Ramp\"])          ->  ramp, publishing\nsearch_jobs([\"Ramp\"], query: \"designer\", is_remote: true)\nget_job(\"ramp\", \"b0c8…\")\n```\n\n## Tools\n\n| Tool                   | What it does                                                       |\n| ---------------------- | ------------------------------------------------------------------ |\n| `resolve_board`        | Turns a company name into the Ashby board token.                   |\n| `search_jobs`          | Searches the postings of the companies you name.                   |\n| `get_job`              | Reads one posting in full, advert included.                        |\n| `list_filter_values`   | Lists the words one board uses, with how many postings carry each. |\n| `compare_compensation` | Puts one pay component of several postings side by side.           |\n\nEvery board keeps its own departments and teams, so a filter written from another\nboard's vocabulary narrows to nothing. `list_filter_values` publishes the words a\nboard actually uses.\n\n### `resolve_board`\n\nTurns a company name into the token that addresses its Ashby board.\n\n| Argument | Type   | Required | What it does                                              |\n| -------- | ------ | -------- | --------------------------------------------------------- |\n| `name`   | string | yes      | A company name, or an Ashby board token you already know. |\n\n**In return:** `found`, the boards that answered, and `tried`, the forms actually\nsent in order. Four forms are tried per name, so nothing found is never proof\nthat a company is absent from Ashby.\n\n### `search_jobs`\n\nSearches the postings of the companies named. Ashby serves a whole board at once,\nand every restriction below is applied to what was read.\n\n| Argument            | Type                                                                   | Required | What it does                                           |\n| ------------------- | ---------------------------------------------------------------------- | -------- | ------------------------------------------------------ |\n| `companies`         | array of 1 to 10 strings                                               | yes      | Company names or board tokens.                         |\n| `query`             | string                                                                 | no       | Words to look for.                                     |\n| `search_in`         | `title` or `title_and_description`, default `title`                    | no       | Where `query` is looked for.                           |\n| `department`        | one string or a list of up to 10                                       | no       | Departments as the board spells them.                  |\n| `team`              | one string or a list of up to 10                                       | no       | Teams as the board spells them.                        |\n| `employment_type`   | one string or a list of up to 6                                        | no       | Employment types.                                      |\n| `workplace_type`    | one string or a list of up to 4                                        | no       | Workplace types.                                       |\n| `is_remote`         | boolean                                                                | no       | Keep the postings marked remote.                       |\n| `country`           | one country or a list of up to 10                                      | no       | Countries as the board spells them.                    |\n| `location_contains` | string                                                                 | no       | Part of a location line.                               |\n| `published_after`   | an ISO 8601 date                                                       | no       | How recent a posting has to be.                        |\n| `has_compensation`  | boolean                                                                | no       | Keep the postings whose company publishes a pay range. |\n| `salary_min`        | number, 0 or more                                                      | no       | A floor for the salary component.                      |\n| `currency`          | three-letter code                                                      | no       | The currency the floor is written in.                  |\n| `salary_interval`   | string, default `1 YEAR`                                               | no       | The period the floor belongs to.                       |\n| `sort`              | `published_desc`, `published_asc` or `title`, default `published_desc` | no       | How the rows are ordered.                              |\n| `limit`             | integer, 1 to 100, default `20`                                        | no       | Postings to serve.                                     |\n| `offset`            | integer, 0 to 10000, default `0`                                       | no       | Postings to skip.                                      |\n\n**In return:** `jobs`, each carrying `board` and `id`, which `get_job` takes\ntogether, plus `title`, `department`, `team`, `employment_type`, `location`,\n`country`, `secondary_location_count`, `workplace_type`, `is_remote`,\n`published_at` with the offset Ashby publishes, `compensation_summary`, `job_url`\nand `apply_url`. **The rows carry no advert text, at any limit.**\n`total_on_board` counts the postings the boards read hold, `total_matched` those\nthe criteria kept, and `returned` those in this answer: three different numbers.\n`per_company` gives one outcome per company with its `status`, `filters_applied`\nechoes what was applied, and `undeclared` counts the postings that declare\nnothing on a field being filtered, so a restriction never silently swallows them.\n\n### `get_job`\n\nReads one posting in full.\n\n| Argument               | Type                                       | Required | What it does                             |\n| ---------------------- | ------------------------------------------ | -------- | ---------------------------------------- |\n| `board`                | string                                     | yes      | A company name, or an Ashby board token. |\n| `job_id`               | string                                     | yes      | The identifier a search row carries.     |\n| `description`          | `plain`, `html` or `none`, default `plain` | no       | How to serve the advert.                 |\n| `include_compensation` | boolean, default `true`                    | no       | Carry the pay the company published.     |\n\nThe advert runs to thousands of characters, and `html` is the company's own\nmarkup, unrewritten.\n\n**In return:** the posting a search row carries, with its description, its\nlocations and the pay components the company published.\n\n### `list_filter_values`\n\nLists the words one board actually uses, with how many postings carry each.\n\n| Argument | Type                                                                                                            | Required | What it does                      |\n| -------- | --------------------------------------------------------------------------------------------------------------- | -------- | --------------------------------- |\n| `board`  | string                                                                                                          | yes      | A company name, or a board token. |\n| `facet`  | `departments`, `teams`, `locations`, `countries`, `employment_types`, `workplace_types` or `all`, default `all` | no       | Which vocabulary to read.         |\n\n**In return:** `facets`, each value with the number of postings carrying it, and\n`undeclared`, the postings declaring nothing on that facet. `sibling_spellings`\nnames the wordings that differ only in case or spacing, which a filter would\notherwise treat as two different things.\n\n### `compare_compensation`\n\nPuts one pay component of several postings side by side.\n\n| Argument     | Type                                                                                       | Required | What it does                      |\n| ------------ | ------------------------------------------------------------------------------------------ | -------- | --------------------------------- |\n| `board`      | string                                                                                     | yes      | A company name, or a board token. |\n| `job_ids`    | array of up to 50 strings                                                                  | no       | The postings to compare.          |\n| `department` | one string or a list of up to 10                                                           | no       | Compare a department instead.     |\n| `team`       | one string or a list of up to 10                                                           | no       | Compare a team instead.           |\n| `query`      | string                                                                                     | no       | Words to look for in the titles.  |\n| `component`  | `Salary`, `EquityCashValue`, `EquityPercentage`, `Commission` or `Bonus`, default `Salary` | no       | Which component to compare.       |\n| `interval`   | string, default `1 YEAR`                                                                   | no       | The period compared.              |\n| `limit`      | integer, 1 to 100, default `25`                                                            | no       | Postings to compare.              |\n\n**One component at a time:** a share of capital and a salary do not add up.\nPostings quoted over another period are listed apart, unconverted.\n\n**In return:** `rows`, one per posting, with the `component` and the `interval`\nthey were compared on, `currencies_present` naming every currency in the answer,\nand `not_published` listing the postings whose company published nothing, which\nis never the same as zero.\n\n## What a pay figure means\n\nA company publishes what it chooses. A posting without a range comes back with\nnone, never with a zero. A range is reported in the currency and over the period\nAshby carries it in, and it is never converted or annualised: comparing two\npostings quoted over different periods is left to whoever knows what the\ncomparison is for.\n\n## Configuration\n\nNothing has to be configured. The server reads no environment variable, and the\n`mcpServers` block above is complete as written.\n\nThe pacing, the timeout and the cache are settings of the client layer, which\n[As a library](#as-a-library) shows how to pass. The interval between two\nrequests can be widened there and never narrowed.\n\n## Errors\n\nEvery failure carries one of six codes, a message, and where it helps the values\nthat would have been accepted.\n\n| Code            | What happened                                           | What to do                                                                        |\n| --------------- | ------------------------------------------------------- | --------------------------------------------------------------------------------- |\n| `not_found`     | Ashby answered, and holds no such board or posting.     | Check the token with `resolve_board`.                                             |\n| `invalid_input` | The arguments were refused before any request went out. | Read the message, which names the argument and what it takes.                     |\n| `rate_limited`  | Ashby asked this client to slow down.                   | Wait, then call again with the same arguments. The posting is still on the board. |\n| `parse_failure` | Ashby answered in a shape this client cannot read.      | Report it at [the issue tracker](https://github.com/smeet666/mcp-ashby/issues).   |\n| `network_error` | The request did not complete.                           | Try again shortly.                                                                |\n| `timeout`       | The request passed its deadline.                        | Ask for fewer companies, or a smaller `limit`.                                    |\n\n## As a library\n\nThe layer reading Ashby is published on its own, with its pacing, its cache and\nits errors, and with no protocol attached.\n\n```ts\nimport { Client } from \"mcp-ashby/client\";\n\nconst client = new Client({ minIntervalMs: 2000 });\nconst resolved = await client.resolveBoard(\"Ramp\");\nconsole.log(resolved.found);\n```\n\n`ClientOptions` takes `minIntervalMs`, `timeoutMs`, `cacheTtlMs` and `fetchImpl`.\nAn interval below the published floor is ignored, so the floor holds here as\nwell.\n\n## Pacing and attribution\n\nRequests go out one at a time with at least a second between them, and that floor\nholds however the client is configured. Ashby serves a whole board in one\nresponse, which can weigh megabytes, so a single question about one company costs\none request and this server holds the answer briefly rather than asking again.\nThe `User-Agent` carries the project and an address where a person can be\nreached, and imitates no browser.\n\nEvery posting carries the address of its Ashby page and its apply URL. Credit the\ncompany and link that page when you show a posting.\n\nThis MCP server is an unofficial project, with no affiliation to Ashby or to the\ncompanies whose boards it reads.\n\n## Privacy\n\nThis server collects nothing about you and sends nothing to its author. It runs\non your machine, contacts `api.ashbyhq.com` and nothing else, holds its answers\nin memory while it runs, and writes nothing to disk.\n[PRIVACY.md](PRIVACY.md) states what a request carries and which settings change\nany of it.\n\n## Development\n\n```bash\nnpm install\nnpm run build:fixtures\nnpm test\nnpm run check\n```\n\nTests run against generated fixtures and make no network request. The live suite,\n`npm run test:live`, makes one request per route and runs nightly against the\nservice itself.\n\n## Contributing\n\nBugs, questions and ideas belong in\n[the issue tracker](https://github.com/smeet666/mcp-ashby/issues). Pull requests\nare welcome; opening an issue first helps agree on the shape of the change. See\n[CONTRIBUTING.md](CONTRIBUTING.md).\n\n## License\n\nMIT, see [LICENSE](LICENSE). The postings belong to the companies that published\nthem.\n\n---\n\n<a name=\"mcp-ashby-français\"></a>\n\n# mcp-ashby (français)\n\n_[English version](#mcp-ashby)_\n\n[Ashby](https://www.ashbyhq.com) est un logiciel de recrutement, et chaque\nentreprise qui l'utilise reçoit avec lui un site d'offres public. Chaque site\nporte les postes ouverts de cette entreprise avec leur intitulé, leur département\net leur équipe, le type de contrat, les lieux et le caractère distant du travail,\nl'annonce complète, et, quand l'entreprise a choisi de le publier, la\nrémunération : une fourchette de salaire, une part de capital, une commission ou\nune prime, chacune avec la période sur laquelle elle est exprimée. Ashby héberge\nun site par entreprise et ne publie aucun index les traversant.\n\nCe serveur relie un client de conversation à ces sites. Vous nommez les\nentreprises qui vous intéressent, et il traduit chaque nom en le jeton qui\nadresse son site, cherche dans leurs offres, les filtre par département, équipe,\nlieu, pays, type de contrat, télétravail, fraîcheur ou rémunération, lit une\noffre en entier, liste les mots que chaque site emploie réellement, et met les\nrémunérations de plusieurs offres côte à côte. Aucune clé d'API, aucun compte.\n\n## Installation\n\n**Installation en un clic**\n\n[![Install in Cursor](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/en/install-mcp?name=ashby&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIm1jcC1hc2hieSJdfQ%3D%3D)\n[![Install in VS Code](https://img.shields.io/badge/VS_Code-Install-0098FF?style=flat&logo=visualstudiocode&logoColor=white)](https://insiders.vscode.dev/redirect/mcp/install?name=ashby&config=%7B%22name%22%3A%22ashby%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22mcp-ashby%22%5D%7D)\n\n**Claude Code**\n\n```bash\nclaude mcp add ashby -- npx -y mcp-ashby\n```\n\n**Claude Desktop, Cursor, et tout client au format de configuration standard**\n\n```json\n{\n  \"mcpServers\": {\n    \"ashby\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"mcp-ashby\"]\n    }\n  }\n}\n```\n\nNode 24 ou plus récent est nécessaire, et aucune variable d'environnement n'est à\nrenseigner.\n\n### Avec Docker\n\n```json\n{\n  \"mcpServers\": {\n    \"ashby\": {\n      \"command\": \"docker\",\n      \"args\": [\"run\", \"-i\", \"--rm\", \"ghcr.io/smeet666/mcp-ashby:2.0.1\"]\n    }\n  }\n}\n```\n\n`-i` garde l'entrée standard ouverte, qui est le canal du protocole, et `-t` est\nomis parce qu'un TTY réécrit le flux. Le conteneur a besoin d'un accès HTTPS\nsortant vers `api.ashbyhq.com`, et de rien d'autre : aucun volume, aucun port,\naucun identifiant.\n\n### Bundle, sans npm\n\nTéléchargez `mcp-ashby-2.0.1.mcpb` depuis\n[la dernière publication](https://github.com/smeet666/mcp-ashby/releases/latest)\net ouvrez-le. Un client qui gère les bundles MCP l'installe seul, sans npm et\nsans fichier de configuration à modifier. Le bundle emporte ses dépendances, donc\nrien n'est téléchargé à l'installation.\n\n## Ce qu'on peut demander\n\n- « Est-ce que Ramp recrute sur Ashby ? »\n- « Trouve-moi des postes de design en télétravail chez Ramp et Linear. »\n- « Lis-moi cette offre en entier. »\n- « Sous quels départements ce site classe-t-il ses offres ? »\n- « Mets côte à côte les salaires de ces offres d'ingénierie. »\n\nChaque question part d'une entreprise, puisque Ashby n'offre aucune recherche\ntraversant les sites. `search_jobs` résout lui-même les noms qu'on lui donne,\ndonc rien n'est à préparer :\n\n```\nresolve_board([\"Ramp\"])          ->  ramp, publie\nsearch_jobs([\"Ramp\"], query: \"designer\", is_remote: true)\nget_job(\"ramp\", \"b0c8…\")\n```\n\n## Les outils\n\n| Outil                  | Ce qu'il fait                                                       |\n| ---------------------- | ------------------------------------------------------------------- |\n| `resolve_board`        | Traduit un nom d'entreprise en jeton de site Ashby.                 |\n| `search_jobs`          | Cherche dans les offres des entreprises nommées.                    |\n| `get_job`              | Lit une offre en entier, annonce comprise.                          |\n| `list_filter_values`   | Liste les mots qu'un site emploie, et combien d'offres les portent. |\n| `compare_compensation` | Met une composante de rémunération de plusieurs offres côte à côte. |\n\nChaque site garde ses propres départements et équipes, donc un filtre écrit dans\nle vocabulaire d'un autre site ne retient rien. `list_filter_values` publie les\nmots qu'un site emploie réellement.\n\n### `resolve_board`\n\nTraduit un nom d'entreprise en le jeton qui adresse son site Ashby.\n\n| Argument | Type   | Requis | Ce qu'il fait                                      |\n| -------- | ------ | ------ | -------------------------------------------------- |\n| `name`   | chaîne | oui    | Un nom d'entreprise, ou un jeton Ashby déjà connu. |\n\n**En retour :** `found`, les sites qui ont répondu, et `tried`, les formes\nréellement envoyées dans l'ordre. Quatre formes sont essayées par nom, donc ne\nrien trouver ne prouve jamais qu'une entreprise est absente d'Ashby.\n\n### `search_jobs`\n\nCherche dans les offres des entreprises nommées. Ashby sert un site entier d'un\ncoup, et chaque restriction ci-dessous s'applique à ce qui a été lu.\n\n| Argument            | Type                                                                  | Requis | Ce qu'il fait                                                     |\n| ------------------- | --------------------------------------------------------------------- | ------ | ----------------------------------------------------------------- |\n| `companies`         | tableau de 1 à 10 chaînes                                             | oui    | Noms d'entreprises ou jetons.                                     |\n| `query`             | chaîne                                                                | non    | Les mots à chercher.                                              |\n| `search_in`         | `title` ou `title_and_description`, défaut `title`                    | non    | Où `query` est cherché.                                           |\n| `department`        | une chaîne ou une liste jusqu'à 10                                    | non    | Départements comme le site les écrit.                             |\n| `team`              | une chaîne ou une liste jusqu'à 10                                    | non    | Équipes comme le site les écrit.                                  |\n| `employment_type`   | une chaîne ou une liste jusqu'à 6                                     | non    | Types de contrat.                                                 |\n| `workplace_type`    | une chaîne ou une liste jusqu'à 4                                     | non    | Modes de travail.                                                 |\n| `is_remote`         | booléen                                                               | non    | Ne garder que les offres en télétravail.                          |\n| `country`           | un pays ou une liste jusqu'à 10                                       | non    | Pays comme le site les écrit.                                     |\n| `location_contains` | chaîne                                                                | non    | Une partie d'une ligne de lieu.                                   |\n| `published_after`   | une date ISO 8601                                                     | non    | L'ancienneté maximale d'une offre.                                |\n| `has_compensation`  | booléen                                                               | non    | Ne garder que les offres dont l'entreprise publie une fourchette. |\n| `salary_min`        | nombre, 0 ou plus                                                     | non    | Un plancher pour la composante salaire.                           |\n| `currency`          | code à trois lettres                                                  | non    | La devise du plancher.                                            |\n| `salary_interval`   | chaîne, défaut `1 YEAR`                                               | non    | La période à laquelle le plancher se rapporte.                    |\n| `sort`              | `published_desc`, `published_asc` ou `title`, défaut `published_desc` | non    | L'ordre des lignes.                                               |\n| `limit`             | entier, 1 à 100, défaut `20`                                          | non    | Offres à servir.                                                  |\n| `offset`            | entier, 0 à 10000, défaut `0`                                         | non    | Offres à enjamber.                                                |\n\n**En retour :** `jobs`, chacune portant `board` et `id`, que `get_job` reprend\nensemble, plus `title`, `department`, `team`, `employment_type`, `location`,\n`country`, `secondary_location_count`, `workplace_type`, `is_remote`,\n`published_at` avec le décalage horaire qu'Ashby publie, `compensation_summary`,\n`job_url` et `apply_url`. **Les lignes ne portent pas l'annonce, quelle que soit\nla limite.** `total_on_board` compte les offres que contiennent les sites lus,\n`total_matched` celles que les critères ont retenues, et `returned` celles de\ncette réponse : trois nombres différents. `per_company` donne une issue par\nentreprise avec son `status`, `filters_applied` redonne ce qui a été appliqué, et\n`undeclared` compte les offres qui ne déclarent rien sur un champ filtré, pour\nqu'une restriction ne les avale jamais en silence.\n\n### `get_job`\n\nLit une offre en entier.\n\n| Argument               | Type                                      | Requis | Ce qu'il fait                           |\n| ---------------------- | ----------------------------------------- | ------ | --------------------------------------- |\n| `board`                | chaîne                                    | oui    | Un nom d'entreprise, ou un jeton Ashby. |\n| `job_id`               | chaîne                                    | oui    | L'identifiant que porte une ligne.      |\n| `description`          | `plain`, `html` ou `none`, défaut `plain` | non    | Comment servir l'annonce.               |\n| `include_compensation` | booléen, défaut `true`                    | non    | Porter la rémunération publiée.         |\n\nL'annonce fait des milliers de caractères, et `html` est le balisage de\nl'entreprise, non réécrit.\n\n**En retour :** l'offre que porte une ligne de recherche, avec sa description,\nses lieux et les composantes de rémunération que l'entreprise a publiées.\n\n### `list_filter_values`\n\nListe les mots qu'un site emploie réellement, et combien d'offres portent chacun.\n\n| Argument | Type                                                                                                           | Requis | Ce qu'il fait                     |\n| -------- | -------------------------------------------------------------------------------------------------------------- | ------ | --------------------------------- |\n| `board`  | chaîne                                                                                                         | oui    | Un nom d'entreprise, ou un jeton. |\n| `facet`  | `departments`, `teams`, `locations`, `countries`, `employment_types`, `workplace_types` ou `all`, défaut `all` | non    | Le vocabulaire à lire.            |\n\n**En retour :** `facets`, chaque valeur avec le nombre d'offres qui la portent,\net `undeclared`, les offres qui ne déclarent rien sur cette facette.\n`sibling_spellings` nomme les formulations qui ne diffèrent que par la casse ou\nles espaces, qu'un filtre traiterait sinon comme deux choses distinctes.\n\n### `compare_compensation`\n\nMet une composante de rémunération de plusieurs offres côte à côte.\n\n| Argument     | Type                                                                                      | Requis | Ce qu'il fait                           |\n| ------------ | ----------------------------------------------------------------------------------------- | ------ | --------------------------------------- |\n| `board`      | chaîne                                                                                    | oui    | Un nom d'entreprise, ou un jeton.       |\n| `job_ids`    | tableau jusqu'à 50 chaînes                                                                | non    | Les offres à comparer.                  |\n| `department` | une chaîne ou une liste jusqu'à 10                                                        | non    | Comparer un département.                |\n| `team`       | une chaîne ou une liste jusqu'à 10                                                        | non    | Comparer une équipe.                    |\n| `query`      | chaîne                                                                                    | non    | Les mots à chercher dans les intitulés. |\n| `component`  | `Salary`, `EquityCashValue`, `EquityPercentage`, `Commission` ou `Bonus`, défaut `Salary` | non    | La composante comparée.                 |\n| `interval`   | chaîne, défaut `1 YEAR`                                                                   | non    | La période comparée.                    |\n| `limit`      | entier, 1 à 100, défaut `25`                                                              | non    | Offres à comparer.                      |\n\n**Une composante à la fois :** une part de capital et un salaire ne s'additionnent\npas. Les offres exprimées sur une autre période sont listées à part, sans\nconversion.\n\n**En retour :** `rows`, une par offre, avec le `component` et l'`interval` sur\nlesquels elles ont été comparées, `currencies_present` qui nomme chaque devise\nprésente dans la réponse, et `not_published` qui liste les offres dont\nl'entreprise n'a rien publié, ce qui ne vaut jamais zéro.\n\n## Ce que dit un chiffre de rémunération\n\nUne entreprise publie ce qu'elle veut. Une offre sans fourchette revient sans\nrien, jamais avec un zéro. Une fourchette est rendue dans la devise et sur la\npériode où Ashby la porte, et elle n'est jamais convertie ni annualisée :\ncomparer deux offres exprimées sur des périodes différentes est laissé à qui sait\nà quoi la comparaison doit servir.\n\n## Configuration\n\nIl n'y a rien à configurer. Le serveur ne lit aucune variable d'environnement, et\nle bloc `mcpServers` ci-dessus est complet tel quel.\n\nLe rythme, le délai et le cache sont des réglages de la couche cliente, que\n[Comme bibliothèque](#comme-bibliothèque) montre comment passer. L'écart entre\ndeux requêtes peut y être élargi et jamais resserré.\n\n## Erreurs\n\nChaque échec porte un des six codes, un message, et quand cela aide les valeurs\nqui auraient été acceptées.\n\n| Code            | Ce qui s'est passé                                       | Que faire                                                                             |\n| --------------- | -------------------------------------------------------- | ------------------------------------------------------------------------------------- |\n| `not_found`     | Ashby a répondu, et n'a ni ce site ni cette offre.       | Vérifiez le jeton avec `resolve_board`.                                               |\n| `invalid_input` | Les arguments ont été refusés avant toute requête.       | Lisez le message, qui nomme l'argument et ce qu'il prend.                             |\n| `rate_limited`  | Ashby demande à ce client de ralentir.                   | Attendez, puis rappelez avec les mêmes arguments. L'offre est toujours en ligne.      |\n| `parse_failure` | Ashby a répondu dans une forme que ce client ne lit pas. | Signalez-le sur [le suivi d'incidents](https://github.com/smeet666/mcp-ashby/issues). |\n| `network_error` | La requête n'a pas abouti.                               | Réessayez sous peu.                                                                   |\n| `timeout`       | La requête a dépassé son délai.                          | Demandez moins d'entreprises, ou un `limit` plus petit.                               |\n\n## Comme bibliothèque\n\nLa couche qui lit Ashby est publiée seule, avec son rythme, son cache et ses\nerreurs, sans protocole attaché.\n\n```ts\nimport { Client } from \"mcp-ashby/client\";\n\nconst client = new Client({ minIntervalMs: 2000 });\nconst resolved = await client.resolveBoard(\"Ramp\");\nconsole.log(resolved.found);\n```\n\n`ClientOptions` prend `minIntervalMs`, `timeoutMs`, `cacheTtlMs` et `fetchImpl`.\nUn écart sous le plancher publié est ignoré, donc le plancher tient également\nici.\n\n## Rythme et attribution\n\nLes requêtes partent une à une avec au moins une seconde entre elles, et ce\nplancher tient quelle que soit la configuration du client. Ashby sert un site\nentier en une réponse, qui peut peser plusieurs mégaoctets, donc une question sur\nune entreprise coûte une requête et ce serveur garde brièvement la réponse plutôt\nque de redemander. Le `User-Agent` porte le projet et une adresse où joindre une\npersonne, et n'imite aucun navigateur.\n\nChaque offre porte l'adresse de sa page Ashby et son adresse de candidature.\nCréditez l'entreprise et renvoyez vers cette page quand vous montrez une offre.\n\nCe MCP est un projet non officiel, sans affiliation à Ashby ni aux entreprises\ndont il lit les sites.\n\n## Confidentialité\n\nCe serveur ne collecte rien sur vous et n'envoie rien à son auteur. Il tourne sur\nvotre machine, ne joint que `api.ashbyhq.com`, garde ses réponses en mémoire le\ntemps qu'il tourne, et n'écrit rien sur le disque. [PRIVACY.md](PRIVACY.md) dit\nce qu'une requête emporte et quels réglages changent cela.\n\n## Développement\n\n```bash\nnpm install\nnpm run build:fixtures\nnpm test\nnpm run check\n```\n\nLes tests s'exécutent sur des fixtures engendrées et n'émettent aucune requête.\nLa suite en direct, `npm run test:live`, émet une requête par route et tourne\nchaque nuit contre le service lui-même.\n\n## Contribuer\n\nLes anomalies, les questions et les idées ont leur place dans\n[le suivi d'incidents](https://github.com/smeet666/mcp-ashby/issues). Les\npropositions de modification sont bienvenues ; ouvrir un ticket d'abord aide à\ns'accorder sur la forme du changement. Voir [CONTRIBUTING.md](CONTRIBUTING.md).\n\n## Licence\n\nMIT, voir [LICENSE](LICENSE). Les offres appartiennent aux entreprises qui les\nont publiées.\n",
  "bytes": 36909,
  "sha": "e480aaa808d1ee29943c54331399fcdb4e7f7158ba69ac202e667d1870fe2cc0",
  "repo_slug": "smeet666/mcp-ashby",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_smeet666_mcp_ashby_07c51f41/readme"
}