# Reported issues for Blind

Pod holds 17 of 18 GitHub reports that passed its relevance review. This can include external user reports, maintainer-confirmed bugs, and concrete feature gaps. Treat them as evidence to inspect, not a count of distinct defects.

Back to [Blind](/mcp/blind).

## Most discussed

### Google, Meta, Amazon and Apple self-hosted careers sites are unreachable, and there is no Recruitee adapter (Workday and SmartRecruiters are done)

> [!NOTE]
> **Status refreshed 2026-09-17 — three of the four asks in the old title have landed.**
> The title used to say *"add Workday, SmartRecruiters adapters"*. Both exist. Verified:
>
> ```
> $ python -c "from payband_mcp import ats; print([n for n,_ in ats._BOARDS])"
> ['greenhouse', 'ashby', 'lever', 'smartrecruiters', 'workday']
> ```
>
> | From the list below | State |
> | --- | --- |
> | Workday | **Done** — in `_BOARDS` (63fea18) |
> | SmartRecruiters | **Done** — in `_BOARDS` |
> |…

[Read the thread](https://github.com/dheerajjha/payband-mcp/issues/13) · 2026-09-16 · open · 6 comments

### Keka and Workday tenants cannot be found from a company name -- build the registry

> [!WARNING]
> **Correction, 2026-09-17.** This issue used to open by saying we can already read pay off
> Keka boards. That was wrong, and I have filed **#27** for it: `keka.py` is imported by
> nothing — no `_BOARDS` entry, no loader — so no tool can reach a Keka board today. The
> parser is real and its 22 tests pass; nothing calls it.
>
> **What that means for you, concretely:**
> - **Workday rows are live work.** Workday *is* in `_BOARDS`, so a Workday row you add is
>   reachable the…

[Read the thread](https://github.com/dheerajjha/payband-mcp/issues/26) · 2026-09-17 · open · 3 comments

### SmartRecruiters and Workday should pass posting location to the pay parser (claimed)

Follow-up to [#19](https://github.com/dheerajjha/payband-mcp/pull/19), which teaches `money.parse` to resolve a bare `$` using the posting location — `Toronto, ON` means CAD, not USD.

#19 threads the location through the three inline boards (Greenhouse, Ashby, Lever). The two boards that fetch pay in a second request do not:

- `src/payband_mcp/smartrecruiters.py` — `fetch_pay()` calls `money.parse(content)`. The posting carries `location.country`.
- `src/payband_mcp/workday.py` —…

[Read the thread](https://github.com/dheerajjha/payband-mcp/issues/23) · 2026-09-17 · open · 3 comments

### `read_post` silently truncates at max_comments, so a caller cannot tell a 12-comment thread from a 137-comment one (Blind path, currently dormant — see #12)

`read_post` slices to `max_comments` (default 40) and returns. The result carries `comment_count` from the schema block, but nothing indicates the returned list is shorter than what exists, so a caller cannot distinguish "this thread has 12 comments" from "this thread has 120 and you are seeing a third".

```python
post = read_post(url, max_comments=40)
len(post["comments"])   # 40
post["comment_count"]   # 137  -- but is 40 the whole story? nothing says.
```

Threads that hit this are exactly…

[Read the thread](https://github.com/dheerajjha/payband-mcp/issues/5) · 2026-09-09 · open · 3 comments

### research produces zero probes for "what is the rto policy", because `rto` is filtered as too short and `policy` as low-signal (Blind path, currently dormant — see #12)

`research` turns a question into keywords and probes them against Blind's company pages. Two filters in `_probe_terms` combine badly: words of 3 characters or fewer are dropped (`len(w) > 3`), and `_LOW_SIGNAL` drops `policy`. For the single most common question this server exists to answer, nothing survives.

```python
>>> from blind_mcp import server as s
>>> s._probe_terms("what is the rto policy", "Acme", [])
[]
>>> s._probe_terms("is wfh allowed", "Acme", [])
['allowed']
```

With no…

[Read the thread](https://github.com/dheerajjha/payband-mcp/issues/1) · 2026-09-09 · open · 3 comments

### market_rate merges hourly rates into annual bands, reports the hourly figure, and cannot express the unit at all

Live in 0.7.0. `pay_bands` fixes the currency **and** the interval before summarising; `market_rate` fixes only the currency.

```python
# server.py, in market_rate
currency = _dominant_currency(hits)
priced = [p for p in hits if p["pay"] and p["pay"]["currency"] == currency]
```

No interval filter. So an hourly contract rate and an annual salary at the same company land in one band — and because the modal-band pick can select the hourly pair, the **hourly figure is reported as the band**:…

[Read the thread](https://github.com/dheerajjha/payband-mcp/issues/24) · 2026-09-17 · closed · 2 comments

### A bare "$" is assumed to be USD, so Canadian and Australian bands are mislabelled

Four currencies write themselves as `$`. `money.py` resolves it by looking for an explicit code nearby, and falls back to USD when there is none:

```python
if match.group("syma") or match.group("symb"):
    return "USD"
```

That is right often enough to be useful and wrong silently when it is wrong. A Toronto posting that says `$120,000 - $150,000` with no code attached is recorded as USD, and since `pay_bands` groups by currency it then lands in the US band — inflating a Canadian salary by…

[Read the thread](https://github.com/dheerajjha/payband-mcp/issues/17) · 2026-09-16 · closed · 2 comments

### The disk cache never evicts anything -- 61MB after casual use, growing without bound

`http.fetch` writes every response to `~/.cache/blind-mcp/` and never removes anything. Entries expire for *reading* after `CACHE_TTL` (6h), but the files stay on disk forever, and a stale entry is overwritten only if that exact URL is requested again.

Measured after ordinary use — a few dozen research questions:

```
$ du -sh ~/.cache/blind-mcp
61M
$ ls ~/.cache/blind-mcp/www.teamblind.com/anon/*.html | wc -l
85
```

That is ~700KB per page, because Blind ships the whole RSC payload inline.…

[Read the thread](https://github.com/dheerajjha/blind-mcp/issues/8) · 2026-09-09 · closed · 2 comments

## Most recent

### classify() reports 'mid' for any unmarked title, so the mid band is a default presented as a reading

`levels.classify` reports `mid` for any title that carries no seniority marker, so the `mid` bucket in `by_level` is not a seniority reading — it is everything we could not read, wearing the name of a level people are actually hired into.

## Verified

```
Software Engineer          -> mid
Developer                  -> mid
Backend Engineer           -> mid
Forward Deployed Engineer  -> mid
Solutions Architect        -> mid
Engineer, Level 62         -> mid
Nurse                      -> mid…

[Read the thread](https://github.com/dheerajjha/payband-mcp/issues/30) · 2026-09-18 · open · 1 comment

### An employer we have already probed and rejected is reported as a lookup failure, so callers are sent slug-hunting for a board that does not exist

Ask this tool about Amazon and it sends you to go read a Greenhouse slug out of Amazon's careers page. There isn't one, there never was, and we already know that — it is written down in `selfhosted.py`, four lines from the code that gives the advice.

## What happens today

`fetch_postings` raises `BoardNotFound` with a genuinely good message (`ats.py:375`):

> No public Greenhouse, Ashby, Lever or SmartRecruiters board found for 'amazon' (tried slugs [...]). Two common reasons: the board token…

[Read the thread](https://github.com/dheerajjha/payband-mcp/issues/29) · 2026-09-18 · open · 0 comments

### no_range_count merges 'published nothing where a band is required' with 'published nothing where none is'

`no_range_count` answers two different questions with one number, and they do not mean the same thing.

An employer that posts a Denver role with no band and an employer that posts a Bengaluru role with no band are not doing the same thing. Colorado requires the range; India requires nothing. The first is a finding. The second is the expected state of the world. Today both land in the same bucket:

```python
# server.py, inside pay_bands
silent = [p for p in base_pay if not p["pay"] and…

[Read the thread](https://github.com/dheerajjha/payband-mcp/issues/28) · 2026-09-18 · open · 0 comments

### The Keka adapter is wired to nothing, so no tool can reach a Keka board (blocks the Keka half of #26)

`keka.py` is imported by nothing, so no tool can reach a Keka board and the adapter is unreachable code.

Found during a maintainer sweep on `main` @ `7bde2c2`, while re-verifying #26 before re-advertising it.

## The claim that is wrong

#26 opens with "**We can now read pay off Keka boards (#25)**", and I repeated that to @Rayan-and-beyond on #19 as a reason his location fix matters less for that source. Both statements are false in the way that matters to a user: the *parser* works, and…

[Read the thread](https://github.com/dheerajjha/payband-mcp/issues/27) · 2026-09-17 · open · 0 comments

### Blind now 403s every non-browser User-Agent site-wide; we will not spoof a browser to get around it

Around 2026-09-16 Blind began returning **403 to every automated request**. Verified from a clean shell:

| User-Agent | `/company/Roku/posts` |
| --- | --- |
| `blind-mcp/0.1.0 (+github…)` | **403** |
| `curl/8.4.0` | **403** |
| *(empty)* | **403** |
| `Mozilla/5.0 … Chrome/128` | 200 |

Every path is affected, including `/` and `/robots.txt` itself. `robots.txt` — read with a browser UA — is unchanged and still permits `/company/`. So this is a WAF/bot-protection layer sitting in front of…

[Read the thread](https://github.com/dheerajjha/blind-mcp/issues/12) · 2026-09-16 · open · 0 comments

### The server reports an empty version to every MCP client, because `__version__` is never passed to `MCPServer`

`src/blind_mcp/__init__.py` defines `__version__ = "0.1.0"`, but `server.py` constructs `MCPServer("blind")` without it. Every MCP client is therefore told the server has no version:

```
$ blind-mcp   # initialize handshake
serverInfo: {'name': 'blind', 'version': ''}
```

Clients display this in their server list, and it is the first thing anyone debugging a stale install will check. An empty string is worse than useless — it looks like the handshake is broken rather than the metadata being…

[Read the thread](https://github.com/dheerajjha/blind-mcp/issues/7) · 2026-09-09 · closed · 2 comments

### Every multi-word company name fails to resolve, because `_resolve` tries capitalisations but never hyphens

`_resolve` finds a company's Blind URL by trying four capitalisations of the name. None of them touch whitespace, so every multi-word employer fails — and takes six seconds of throttled requests to do it.

```python
>>> from blind_mcp.server import _resolve
>>> _resolve("Goldman Sachs")
ValueError: No Blind company page found for 'Goldman Sachs'
  (tried ['Goldman Sachs', 'Goldman sachs', 'GOLDMAN SACHS'])
```

Blind uses hyphens, and the slug is case-insensitive:

| URL | result |
| --- | ---…

[Read the thread](https://github.com/dheerajjha/blind-mcp/issues/6) · 2026-09-09 · closed · 0 comments

### Ranking ignores thread age, so a 2021 parental-leave thread outranks newer ones and the model reports stale policy as current (Blind path, currently dormant — see #12)

Ranking in `research` scores a thread on keyword overlap plus a specificity bonus. Nothing looks at the date. On policy questions — which are most of what this server gets asked — that reliably surfaces answers that were true years ago.

Real example. Asked for Intuit's parental leave policy, `research` returns:

| thread | published |
| --- | --- |
| Maternity leave/benefits at Intuit | **2021-07-04** |
| Best company for paternity leave? | **2022-02-15** |

Both are genuinely the best keyword…

[Read the thread](https://github.com/dheerajjha/payband-mcp/issues/4) · 2026-09-09 · open · 2 comments

### `find` reports 272 matches but returns only the first 30, and nothing tells the caller the rest exist

`find` fetches exactly one page and returns at most `limit` cards from it, but reports `total_matches` from the page header. The two disagree, and nothing says so.

```python
>>> find("Intuit", "leave")
{'total_matches': 272, 'posts': [ ... 30 items ... ]}
```

A caller reading that reasonably concludes it has seen the matches for `leave`. It has seen 11% of them, specifically the 30 Blind chose to show first. For a narrow keyword (`maternity` → 7) this never bites. For anything broader it…

[Read the thread](https://github.com/dheerajjha/blind-mcp/issues/3) · 2026-09-09 · closed · 0 comments

The remaining reports are on [the project's issue tracker](https://github.com/dheerajjha/blind-mcp/issues).
