Skip to main content
Glama
WonderCV

ClawHire MCP

by WonderCV
README.md
# ClawHire MCP

Employer-facing MCP for China's first agent-native hiring marketplace.

ClawHire lets hiring managers post jobs, search candidates, and receive applications — all through natural language conversation with Claude or any MCP-compatible AI assistant. Backed by [WonderCV](https://www.wondercv.com)'s resume database and existing HR infrastructure.

## What This Is

ClawHire is one half of a two-sided marketplace:

```
Candidates                              Employers
    │                                       │
resume-agent-mcp                    clawhire-mcp (this repo)
    │                                       │
    └──────── WonderCV Backend ─────────────┘
                    │
              PostgreSQL (existing WonderCV DB)
```

- **[resume-agent-mcp](https://github.com/WonderCV/resume-agent-mcp)** — Candidate-facing. Resume analysis, profile publishing, job applications.
- **clawhire-mcp** (this repo) — Employer-facing. Job posting, candidate search, application management.

Both share WonderCV's existing Django backend, company database, and profession taxonomy. This is NOT a standalone product — it's an MCP layer on top of WonderCV's existing hiring infrastructure.

## Why It Exists

The thesis: China is in an AI-agent boom. Companies hiring for white-collar roles increasingly want people who can work with AI agents. But no hiring platform treats **AI-agent fluency** as a first-class hiring signal.

ClawHire does. Candidates who use MCP tools are automatically tagged with AI fluency badges. Employers can filter for agent-fluent talent. This signal is impossible to replicate on traditional job boards.

## Three Categories of Candidates

Not all candidates are equal. The system handles three distinct pools:

| Category | How They Enter | AI Fluency | Employer Can... |
|----------|---------------|-----------|-----------------|
| **1. MCP Native** | Install resume-agent-mcp, publish profile | Auto-badged `verified_mcp_user` | Search, view profile, receive applications |
| **2. GUI Opt-In** | Click button on wondercv.com or WeChat | No badge (not demonstrated) | Same as above |
| **3. Database** | They don't — existing WonderCV users | None | View anonymized/coarsened data, send outreach invite only |

**Category conversions:**
- 3 → 2: Candidate responds to outreach email or opts in via GUI
- 2 → 1: Candidate links MCP session to their WonderCV account (automatic upgrade)
- Conversions are one-way (upward only)

**Company blocklist:** Candidates can block specific companies (e.g. current employer) from seeing their profile. Enforced at query time.

## Architecture

### Existing WonderCV Models We Reuse (DO NOT DUPLICATE)

| Model | Table | What It Has |
|-------|-------|------------|
| `Companies` | `api/companies/` | Company names (cn/en), scale, industry, Tianyancha verification |
| `HrAccounts` | `api/account/` | HR manager accounts, WeChat auth, phone login, quotas |
| `Jobs` | `api/jobs/` | Job postings with profession taxonomy, salary, experience (in **days**) |
| `JobApplications` | `api/data_operations/` | Application tracking with state machine |
| `JobOrders` | `api/job_orders/` | Payment/promotion with Alipay + WeChat Pay |

### New Models We Add (only 2)

| Model | Purpose |
|-------|---------|
| `CandidateProfile` | Opt-in marketplace profile (Cat 1 + 2). Links to WonderCV user. Contains visibility, AI fluency data, company blocklist, preferences. |
| `McpEmployerSession` | Bridges MCP session → HrAccount. Tracks daily usage quotas. |

### Data Unit Conventions

These MUST match existing WonderCV conventions:

| Field | Unit | Notes |
|-------|------|-------|
| `salary_min/max` | CNY/month (integer) | NOT thousands |
| `experience_min/max` | **Days** (in DB) | MCP accepts years, converts with `× 365` |
| `status` (Jobs) | Integer 0-4 | 0=draft, 1=publish, 2=expired, 3=offline, 4=remove |
| IDs | `token` (CharField) | NOT UUIDs — WonderCV uses string tokens |

## Available Tools (7)

| Tool | Purpose | Quota |
|------|---------|-------|
| `register_company` | Create employer account, get session_id | — |
| `post_job` | Publish job to marketplace | jobs_posted |
| `list_jobs` | View own posted jobs with stats | — |
| `search_candidates` | Search marketplace + database pools | searches |
| `view_candidate` | View candidate profile (visibility-enforced) | candidate_views |
| `list_applications` | View inbound applications | — |
| `request_outreach` | Send invite to Category 3 database candidate | outreach_sent |

### Quota Tiers (daily limits)

| Tier | Views | Searches | Outreach | Jobs |
|------|-------|----------|----------|------|
| Alpha (current) | 50 | 30 | 10 | 5 |
| Free | 20 | 10 | 5 | 2 |
| Paid | 200 | 100 | 20 | 20 |

All alpha users get the Alpha tier for free.

## Quick Start

### Install & Build

```bash
git clone https://github.com/WonderCV/clawhire-mcp.git
cd clawhire-mcp
npm install
npm run build
```

### Configure

```bash
cp .env.example .env
```

Edit `.env`:

```env
CLAWHIRE_API_BASE_URL=https://api.wondercv.cn/cv/v1/mcp/hiring
CLAWHIRE_API_KEY=your_api_key_here    # Leave as-is for mock mode
LOG_LEVEL=info
```

**Mock mode:** If `CLAWHIRE_API_KEY` is missing or `your_api_key_here`, the server returns realistic mock data for all endpoints. Useful for development without the backend.

### Add to Claude

In your MCP config (e.g. `~/.claude.json` or Claude Desktop settings):

```json
{
  "mcpServers": {
    "clawhire": {
      "command": "node",
      "args": ["/absolute/path/to/clawhire-mcp/dist/server.js"],
      "env": {
        "CLAWHIRE_API_KEY": "your_api_key_here"
      }
    }
  }
}
```

### Try It

After connecting, tell Claude:

- "Register my company — we're TechCorp in Shanghai, email hr@techcorp.com"
- "Post a job for Senior Product Manager, remote OK, 30-50k/month"
- "Search for AI-fluent product managers in Shanghai with 3+ years experience"
- "Show me candidate details for [candidate_id]"
- "Send an outreach invite to [candidate_ref] for the PM role"

## Development

```bash
npm run dev          # Watch mode (auto-recompile on changes)
npm run build        # Single build
npm run typecheck    # Type check without emitting
npm start            # Run compiled server
```

### Project Structure

```
src/
├── server.ts           # MCP server entry, tool registration, JSON schema conversion
├── types.ts            # All TypeScript types (aligned with WonderCV models)
├── session.ts          # In-memory session management + quota tracking
├── backend-api.ts      # WonderCV backend API client (with mock fallback)
└── tools/
    ├── index.ts                # Tool registry
    ├── register_company.ts     # Creates HrAccount + Company
    ├── post_job.ts             # Wraps Jobs model (years→days conversion)
    ├── list_jobs.ts            # Paginated job list with stats
    ├── search_candidates.ts    # Marketplace + database pools, AI fluency filter
    ├── view_candidate.ts       # Visibility-enforced profile view + anonymization
    ├── list_applications.ts    # Application list with match scores
    └── request_outreach.ts     # Database candidate invitation (rate-limited)
```

### Adding a New Tool

1. Create `src/tools/your_tool.ts` implementing the `Tool<Input>` interface
2. Define input schema with Zod
3. Implement `execute(input)` returning `ToolResult`
4. Export from `src/tools/index.ts` and add to `allTools` array
5. The server auto-registers it via the tool registry

### Backend API Pattern

All tools follow the same pattern:

```typescript
// 1. Validate session
const session = getSession(input.session_id);
if (!session) return errorResult('INVALID_SESSION', '...');

// 2. Check quota (for metered tools)
const remaining = getRemainingQuota(session, 'searches');
if (remaining <= 0) return errorResult('QUOTA_EXCEEDED', '...');

// 3. Call backend
const result = await backendApi.searchCandidates(input);

// 4. Consume quota AFTER success (not before)
checkAndIncrementUsage(session, 'searches');

// 5. Format and return
return { content: [{ type: 'text', text: JSON.stringify(formatted) }], isError: false };
```

## Known Issues (v0.1.0)

See [KnownIssues.md](./KnownIssues.md) for full details.

| Issue | Severity | Impact |
|-------|----------|--------|
| In-memory session storage | High (for prod) | Server restart = re-register |
| Quota race condition | Medium | Concurrent requests can exceed limits |
| Brittle JSON schema conversion | Medium | Works for flat inputs, fragile for complex |
| No test coverage | Low | Needs tests before v0.2 |

**Alpha verdict:** Ship to alpha (<50 employers), not to GA.

## Roadmap

### v0.1 (current) — Alpha Foundation
- [x] 7 employer tools (register, post, search, view, applications, outreach, list)
- [x] Three-category candidate model
- [x] AI fluency badges
- [x] Anonymization for privacy
- [x] Daily quota system

### v0.2 — Marketplace Core
- [ ] Persistent session storage (Redis or backend rehydration)
- [ ] Backend authoritative quota metering
- [ ] Replace zodToJsonSchema with `zod-to-json-schema` library
- [ ] Candidate-side tools in resume-agent-mcp (publish, apply, browse jobs)
- [ ] LLM-based match scoring
- [ ] Test suite

### v0.3 — Growth
- [ ] Company verification automation (Tianyancha API)
- [ ] Application status management (shortlist, reject)
- [ ] Paid tier billing (via existing JobOrders + Alipay/WeChat Pay)
- [ ] Global aggregate stats

## Related

- [resume-agent-mcp](https://github.com/WonderCV/resume-agent-mcp) — Candidate-side MCP
- [WonderCV](https://www.wondercv.com) — Resume platform
- [Full product plan](./docs/plans/) — Architecture decisions and detailed specs

## License

MIT

TDQS

A4/5.0

Scored across 7 tools

Disambiguation5/5

Each tool has a distinct purpose with clear boundaries: list_applications for viewing applications, list_jobs for job listings, post_job for posting jobs, register_company for account setup, request_outreach for candidate invitations, search_candidates for candidate searches, and view_candidate for detailed profiles. No overlap exists; an agent can easily differentiate them based on their specific actions and targets.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern in snake_case: list_applications, list_jobs, post_job, register_company, request_outreach, search_candidates, view_candidate. This uniformity makes the set predictable and easy to understand, with no deviations in naming conventions.

Tool Count5/5

With 7 tools, this server is well-scoped for its recruitment domain. Each tool serves a unique function in the hiring workflow, from company registration to candidate management, without being overly sparse or bloated. The count aligns perfectly with the typical range of 3-15 tools for a focused purpose.

Completeness4/5

The tool set covers most core recruitment operations: company setup, job posting, candidate search, outreach, and application viewing. However, there are minor gaps noted in list_applications, such as missing tools for processing applications (e.g., approve/deny), which are planned for v2 but currently absent. Otherwise, the surface is largely complete for the domain.