Documentation Index
Fetch the complete documentation index at: https://docs.nico-jobagent.com/llms.txt
Use this file to discover all available pages before exploring further.
MCP Server
Nico exposes a Model Context Protocol (MCP) server that allows AI assistants like Claude to interact with your job applications directly.
What can the MCP server do?
The MCP server provides 7 tools:
| Tool | Type | Description |
|---|
list_job_applications | Read | List your job applications with filtering |
search_job_applications | Read | Search your saved applications by URL or company name |
get_job_application | Read | Get full details of a specific application |
parse_job_application_url | Read | Extract structured data from a job posting URL |
search_job_postings | Read | Search Nico’s global job postings index |
create_proposed_job_application | Write | Add a new proposed job to your board |
add_note_to_job_application | Write | Add a note to an existing application |
Connecting Claude Desktop
To use Nico with Claude Desktop, add this to your Claude Desktop configuration:
{
"mcpServers": {
"nico-jobagent": {
"url": "https://mcp.nico-jobagent.com/mcp",
"authorization_token": "YOUR_OAUTH_TOKEN"
}
}
}
The MCP server requires OAuth authentication with the mcp scope. See OAuth for how to obtain a token.
list_job_applications
List job applications with optional filtering and pagination.
Parameters:
| Parameter | Type | Required | Description |
|---|
status | string | No | Filter by status group: draft, applied, interviewing, offer, finished, active |
page | integer | No | Page number (default: 1) |
per_page | integer | No | Items per page (default: 25) |
Example response:
{
"job_applications": [
{
"id": 42,
"title": "Senior Product Manager",
"status": "applied",
"company": {
"id": 7,
"name": "Acme Corp"
},
"url": "https://acme.com/careers/pm-senior",
"location": "Berlin, Germany",
"work_mode": "hybrid",
"created_at": "2025-03-15T10:30:00Z"
}
],
"meta": {
"current_page": 1,
"total_pages": 3,
"total_count": 52
}
}
search_job_applications
Search for job applications by URL (exact match) or company name (case-insensitive).
Parameters:
| Parameter | Type | Required | Description |
|---|
url | string | No* | Search by exact job posting URL |
company_name | string | No* | Search by company name (case-insensitive) |
status | string | No | Filter results by status group |
*At least one of url or company_name is required.
Example response (search by URL):
{
"exists": true,
"count": 1,
"job_applications": [
{
"id": 42,
"title": "Senior Product Manager",
"status": "applied",
"company": {
"name": "Acme Corp"
}
}
]
}
get_job_application
Get the full details of a specific job application, including interviews, notes, and status history.
Parameters:
| Parameter | Type | Required | Description |
|---|
id | integer | Yes | The job application ID |
Example response:
{
"id": 42,
"title": "Senior Product Manager",
"status": "applied",
"kanban_category": "applied",
"company": {
"id": 7,
"name": "Acme Corp",
"url": "https://acme.com"
},
"url": "https://acme.com/careers/pm-senior",
"location": "Berlin, Germany",
"work_mode": "hybrid",
"salary_min": 80000,
"salary_max": 100000,
"currency": "EUR",
"period": "annual",
"employment_type": "full-time",
"interviews": [],
"notes": [],
"created_at": "2025-03-15T10:30:00Z"
}
parse_job_application_url
Extract structured job data from a job posting URL. Nico automatically detects the job board and parses the posting.
Parameters:
| Parameter | Type | Required | Description |
|---|
url | string | Yes | URL of the job posting to parse |
Example response:
{
"title": "Senior Product Manager",
"company": "Acme Corp",
"location": "Berlin, Germany",
"work_mode": "hybrid",
"salary_min": 80000,
"salary_max": 100000,
"currency": "EUR",
"period": "annual",
"employment_type": "full-time"
}
Use parse_job_application_url before create_proposed_job_application to extract job details automatically — then pass the parsed data to the create tool.
search_job_postings
Search Nico’s global job postings index — the same data behind the in-app job search at /jobs. Returns the most recent matching postings, newest-first.
This searches Nico’s shared posting index, not the user’s own job applications. To check “have I already saved this?”, use search_job_applications instead.
Parameters:
| Parameter | Type | Required | Description |
|---|
country_code | string | Yes | ISO 3166-1 alpha-2 country code, e.g. US or NL. Always required. |
title | string[] | No | Title phrases ORed together. Each phrase is a case-insensitive substring match. Example: ["backend engineer", "staff engineer"] |
region | string | No | State/province name (case-insensitive). Required when city is set and country_code is US or CA. |
city | string | No | City name for radius search. Looked up exactly against Nico’s geocoded locations index — no external geocoding is performed. Returns an error if the city is unknown or ambiguous. |
radius_km | integer | No | Search radius in km around the resolved city (default 25). Only used when city is set. |
work_mode | string[] | No | One or more of remote, onsite. Hybrid postings surface under either filter. |
employers | string[] | No | Filter to postings at these employers. Pass employer names — lookup is case-insensitive. Each name must resolve to exactly one employer; unknown or ambiguous names return an error. Example: ["Anthropic", "Stripe"] |
limit | integer | No | Max results (default 20, max 100) |
City radius search:
Pass city together with country_code (plus region for US/CA) to filter postings within radius_km of that city. Cities are resolved by exact, case-insensitive match against Nico’s existing geocoded-locations index — there is no live geocoding fallback, so unknown or ambiguous names return an error rather than a best-guess match.
{
"city": "Amsterdam",
"country_code": "NL",
"radius_km": 50
}
{
"city": "Springfield",
"region": "Illinois",
"country_code": "US",
"radius_km": 50
}
Errors:
The tool returns a single-key error object when the request can’t proceed:
{ "error": "country_code is required" }
Other error messages you may see:
country_code is required — country_code is mandatory on every call.
region (state/province) is required for city search in US (or CA) — region must be set when city is given and the country is US or CA.
Location not found: <city> — the city wasn’t found in Nico’s geocoded locations index.
Ambiguous location: multiple matches for <city> — please refine — more than one row matched; narrow with region.
Unknown employer: <name> — a name in employers didn’t match any employer.
Ambiguous employer: multiple matches for <name> — please refine — a name in employers matched more than one employer; refine the spelling.
Job search is not enabled for this account — the calling account doesn’t have job search enabled.
Example response:
{
"job_postings": [
{
"id": "019e1e37-ff01-7870-a56a-7b316b2d2373",
"title": "Senior Backend Engineer",
"company_name": "Acme Co",
"company_id": "019e1e37-aa01-7870-a56a-7b316b2d2374",
"location": "San Francisco, CA / Hybrid",
"work_mode": "hybrid",
"employment_type": "full-time",
"salary_min": 150000,
"salary_max": 200000,
"salary_currency": "USD",
"salary_period": "annual",
"posted_at": "2026-05-12T08:00:00Z",
"url": "https://acme.test/jobs/be-eng"
}
],
"count": 1
}
After finding a relevant posting, pass its url to parse_job_application_url to extract richer structured fields, then create_proposed_job_application to add it to the user’s board.
create_proposed_job_application
Create a new job application in proposed status. The job owner must approve it before it moves forward.
Parameters:
| Parameter | Type | Required | Description |
|---|
title | string | Yes | Job title |
company_name | string | Yes | Company name (creates company if it doesn’t exist) |
url | string | No | Job posting URL |
location | string | No | Job location |
work_mode | string | No | One of: remote, remote-optional, hybrid, on-site |
salary_min | number | No | Minimum salary |
salary_max | number | No | Maximum salary |
currency | string | No | Salary currency (e.g., USD, EUR) |
period | string | No | Pay period (e.g., annual, monthly) |
employment_type | string | No | One of: full-time, part-time, contract, internship, temporary |
Idempotency: If a job application with the same URL already exists, the existing application is returned instead of creating a duplicate.
Example response:
{
"id": 43,
"title": "Senior Product Manager",
"status": "proposed",
"company": {
"name": "Acme Corp"
},
"created": true
}
add_note_to_job_application
Add a note to an existing job application.
Parameters:
| Parameter | Type | Required | Description |
|---|
job_application_id | integer | Yes | The job application ID |
content | string | Yes | The note text |
Example response:
{
"id": 156,
"content": "Strong match for the candidate's background in product analytics.",
"created_at": "2025-03-15T14:20:00Z",
"author": "Job Search Bot"
}