# hiresignal [Health: Active]

**Category:** 💻 Developer Tools  
**Repository:** https://github.com/iusmuchandra/hiresignal-mcp  
**GitHub Stars:** 0  
**Views:** 0  
**Installs:** 0  
**Upvotes:** 0  
**Directory Page:** https://allmcps.com/mcp/hiresignal

## Description
Real-time job market intelligence: live job search, hiring velocity, salary & skill trends.

## Claude Desktop Quick Installation
Install path detected from listing signals. Uses `npx` (confidence: high):

```json
"mcpServers": {
  "hiresignal": {
    "command": "npx",
    "args": ["-y","mcp-remote","https://your-hiresignal.up.railway.app/sse","--header","Authorization: Bearer YOUR_HIRESIGNAL_API_KEY"]
  }
}
```

## Documentation & README

# HireSignal — Hiring-Intent Signals for B2B Sales

**Turn live job postings into buying signals your AI agent can call.**

![HireSignal live demo — three tool calls against the hosted server](https://raw.githubusercontent.com/iusmuchandra/hiresignal-mcp/HEAD/marketing/demo.gif)

*Live demo against the hosted instance — run it yourself with `node scripts/demo.mjs`.*

When a company posts for a VP Sales, RevOps Manager, or Data Security Analyst, it's telling you it has a pain and an approved budget — typically **60–90 days before** it starts researching vendors. HireSignal is an MCP server that surfaces those hiring signals so your sales/GTM agent can find in-market accounts, score them, and time outreach.

Plug it into Claude, Cursor, Cline, or Windsurf and ask:

- "Which fintechs posted a RevOps or Sales Ops role in the last 7 days?" *(→ in-market for CRM/sales tooling)*
- "Is Stripe scaling or freezing its data team right now?" *(→ account expansion = budget unlocking)*
- "Compare hiring momentum across these 5 target accounts."
- "Which companies started hiring for Snowflake this month?" *(→ buying signal for adjacent data tooling)*

Also works for recruiting intel, comp benchmarking, and market research — but it's built sales-first.

The server speaks the **Model Context Protocol** over **SSE** so it can be hosted remotely (Railway, Fly, anywhere with HTTPS).

## Try it instantly (hosted demo)

A live instance is running with a shared, rate-limited demo key. Point any MCP client at:

```
URL:    https://hiresignal-mcp-production-d4d9.up.railway.app/sse
Header: Authorization: Bearer hs_demo_0b25932234553fd38b571f12c1439bfd
```

> The demo key is heavily rate-limited and shares a small monthly data quota — expect `QUOTA_EXHAUSTED` during busy periods. For a dedicated key with higher limits, get in touch.

## Tools

| Tool | What it does |
| --- | --- |
| `search_jobs` | Find live postings matching a role/skill in a location and recency window. |
| `company_hiring_velocity` | Total roles + 7d / 30d adds + department mix + growing/stable/shrinking signal for one company. |
| `skill_demand_pulse` | Week-over-week demand trend for a skill, with avg disclosed salary and top hiring companies. |
| `market_salary_estimate` | p25 / median / p75 for a job title + location + seniority, plus remote premium. |
| `industry_hiring_heatmap` | Per-department open-role counts and % change for an industry vertical. |
| `competitor_talent_intel` | Compare up to 5 companies side by side on open roles, top titles, and growth signal. |
| `job_alert_check` | Poll for new postings since N hours ago. Designed for cron / agent loops. |
| `get_server_status` | Health snapshot: version, uptime, configured providers, **corpus stats**, cache size. |

## First-party corpus (the data moat)

For a curated set of high-value accounts, HireSignal doesn't resell aggregated data — it
scrapes each company's **own ATS** (Greenhouse / Ashby / Lever / Workday) directly and stores a
**time-series** of every posting in a local SQLite file. That makes `company_hiring_velocity`
a real signal (roles **added and closed** over time, with the company's actual posted dates),
returns `data_source: "first_party_ats"`, costs nothing per query, and — because the value is
the *accumulating history* — is the one thing a competitor can't backfill.

```bash
npm run build && npm run ingest     # ~50 companies, ~12k open roles, ~$0
```

The server can keep this fresh itself (set `INGEST_INTERVAL_HOURS` + a persistent
`HIRESIGNAL_CORPUS_PATH`). Companies outside the corpus transparently fall back to the
aggregator. Full design, schema, and how to add companies: **[CORPUS.md](https://github.com/iusmuchandra/hiresignal-mcp/blob/HEAD/CORPUS.md)**.

## Configuration

Set these environment variables on the server (Railway → Variables, or `.env` locally):

```bash
SERPAPI_KEY=...               # https://serpapi.com — used by search_jobs, job_alert_check
JSEARCH_RAPIDAPI_KEY=...      # https://rapidapi.com/letscrape-6bRBa3QguO5/api/jsearch
HIRESIGNAL_API_KEYS=k1,k2     # comma-separated allowlist of client keys
PORT=3000                     # default

# First-party corpus (optional but recommended — see CORPUS.md)
HIRESIGNAL_CORPUS_PATH=./data/corpus.db   # SQLite corpus location (use a volume in prod)
INGEST_INTERVAL_HOURS=6                    # if set, server self-ingests on boot + interval
```

A data source must be available: either an **ingested corpus** (`npm run ingest`) or a provider
key. `get_server_status` reports `"ok"` when the corpus is active *or* a key is set, and
`"degraded"` when there is neither.

`HIRESIGNAL_API_KEYS` accepts one or more comma-separated keys (or use `HIRESIGNAL_API_KEY` for a single key). If neither is set the server runs in **open mode** — it logs a startup warning and accepts unauthenticated calls, which is convenient for local dev but **must not** be used in any deployment exposed to the network.

## Run locally

```bash
npm install
cp .env.example .env   # fill in keys
npm run dev            # tsx watch
# → http://localhost:3000/sse
# → http://localhost:3000/health
```

Production build:

```bash
npm run build
npm start
```

## Deploy to Railway

```bash
npm install -g @railway/cli
railway login
railway init
railway up
# then set SERPAPI_KEY and JSEARCH_RAPIDAPI_KEY in the Railway dashboard
```

`railway.json` wires up Nixpacks, the `npm ci && npm run build` step, and `/health` for health checks.

## Connecting from MCP clients

### Claude Desktop

Claude Desktop's stable config supports stdio MCP servers natively and remote (SSE) servers via the [`mcp-remote`](https://www.npmjs.com/package/mcp-remote) bridge. Edit `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows):

```jsonc
{
  "mcpServers": {
    "hiresignal": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "https://your-hiresignal.up.railway.app/sse",
        "--header",
        "Authorization: Bearer YOUR_HIRESIGNAL_API_KEY"
      ]
    }
  }
}
```

Restart Claude Desktop. The 8 HireSignal tools will appear in the tools menu.

### Cursor

Open Cursor → Settings → MCP → "Add new MCP server":

```jsonc
{
  "mcpServers": {
    "hiresignal": {
      "url": "https://your-hiresignal.up.railway.app/sse",
      "headers": {
        "Authorization": "Bearer YOUR_HIRESIGNAL_API_KEY"
      }
    }
  }
}
```

### Cline / Windsurf

Both support remote SSE MCP servers. Point them at `https://your-hiresignal.up.railway.app/sse` with the same `Authorization: Bearer …` header.

### Local stdio fallback

Most clients only need the SSE URL above. If a client requires stdio, point it at the `mcp-remote` bridge as in the Claude Desktop example.

## How auth and limits work

- **API key**: the server reads it from `Authorization: Bearer …`, `x-api-key`, or `?api_key=…` (prefer the header — query params end up in proxy/access logs). The presented key is SHA-256 digested and compared in constant time against the digests of every key in `HIRESIGNAL_API_KEYS`. Unknown or missing keys get a `401` with `{"code": "AUTH_FAILED"}`. Only the first 16 hex chars of the digest are logged, never the key itself. The `/messages` POST endpoint re-checks the key on every call and rejects it if the session was opened under a different key, so a leaked `sessionId` is not enough to take over a session.
- **Rate limit**: 30 tool calls per API key per minute (token bucket, in-memory). On overflow, tools return `{ "code": "RATE_LIMITED", "retry_after_seconds": N }`.
- **Cache**: job search results are cached for 15 minutes per `(query, location, date_posted)` tuple to protect upstream quota. `job_alert_check` always bypasses the cache.
- **Quota errors**: when an upstream returns 429 or signals quota exhaustion, the tool returns `{ "code": "QUOTA_EXHAUSTED", "retry_after_seconds": N, "hint": "hiresignal.io/pricing" }`.

## Testing

```bash
npm test         # vitest run with mocked upstream APIs
npm run typecheck
```

## License

MIT.

