{
  "markdown": "<a name=\"top\"></a>\n\n<div align=\"center\">\n\n<a href=\"https://landed.jobs\"><img src=\"https://static.b100x.ai/email/landed-wordmark.png\" alt=\"Landed\" width=\"200\"></a>\n\n<img src=\"https://static.b100x.ai/github-repos/images/landed-mcp/banner.svg\" alt=\"Landed MCP Server\" width=\"100%\">\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-black.svg)](LICENSE)\n[![Model Context Protocol](https://img.shields.io/badge/MCP-Streamable_HTTP-6E56CF.svg)](https://modelcontextprotocol.io)\n[![smithery badge](https://smithery.ai/badge/landedjobs/landed)](https://smithery.ai/servers/landedjobs/landed)\n[![Works with Claude](https://img.shields.io/badge/Works_with-Claude-D97757.svg)](#claude-desktop)\n[![Works with Cursor](https://img.shields.io/badge/Works_with-Cursor-000000.svg)](#cursor)\n\n**Search AI-native jobs, prepare applications, and study for interviews — from any MCP client.**\nA public [Model Context Protocol](https://modelcontextprotocol.io) server giving Claude, Cursor, VS Code, and any MCP-capable agent live access to [Landed](https://landed.jobs)'s ranked, fit-scored job corpus.\n\n*Maintained by [Landed](https://landed.jobs) — daily AI-native job matches, agent help with every application, and mock-interview prep.*\n\n</div>\n\n---\n\n## What is this?\n\n**Landed MCP** connects your AI assistant to a curated, continuously-updated corpus of AI-native roles\n(AI Engineer, ML Engineer, RAG Engineer, AI PM, GTM Engineer, and more). Instead of copy-pasting job\nboards into a chat, your agent can:\n\n- 🔎 **Search jobs** — ranked and fit-scored against a structured brief (role, skills, seniority,\n  remote, compensation, industries…), or from a plain-English description.\n- 📝 **Prepare applications** — pull a job's real application form, grouped into standard / screening /\n  EEO fields, so the agent can auto-fill and draft answers before you apply.\n- 🎓 **Study for interviews** — fetch free, curated interview-prep, portfolio, and roadmap resources.\n\nIt speaks **Streamable HTTP** and works with any MCP client. Use the **hosted** server in seconds, or\n**self-host** this repo against your own Landed API.\n\n> **Free to start.** Anonymous callers get a shared free budget — no signup, no key. Add an API token\n> for unlimited, personalized results.\n\n---\n\n## Quick start (hosted)\n\nThe hosted server lives at:\n\n```\nhttps://mcp.landed.jobs/mcp\n```\n\nPick your client below. Everything works **anonymously** out of the box — just omit the `Authorization`\nheader. Add `Authorization: Bearer lnd_live_…` (mint one at\n[Landed → Settings → API tokens](https://landed.jobs)) for unlimited, brief-personalized search.\n\n### Claude Code\n\nThe one-liner (CLI):\n\n```bash\n# Anonymous (free tier)\nclaude mcp add --transport http landed-jobs https://mcp.landed.jobs/mcp\n\n# Authenticated (unlimited, personalized)\nclaude mcp add --transport http landed-jobs https://mcp.landed.jobs/mcp \\\n  --header \"Authorization: Bearer lnd_live_your_token_here\"\n```\n\nThen in a session: `/mcp` to confirm it's connected, and try the `find_jobs` prompt.\n\n### Claude Desktop\n\nOpen **Settings → Developer → Edit Config** (this opens `claude_desktop_config.json`), then add:\n\n```jsonc\n{\n  \"mcpServers\": {\n    \"landed-jobs\": {\n      \"command\": \"npx\",\n      \"args\": [\n        \"-y\", \"mcp-remote\", \"https://mcp.landed.jobs/mcp\",\n        \"--header\", \"Authorization: Bearer lnd_live_your_token_here\"\n      ]\n    }\n  }\n}\n```\n\nRestart Claude Desktop. Drop the `--header` line for the free anonymous tier.\n\n> Claude Desktop bridges remote HTTP servers through [`mcp-remote`](https://www.npmjs.com/package/mcp-remote).\n> If your build has native **Custom Connectors** (Settings → Connectors → *Add custom connector*), you can\n> instead paste `https://mcp.landed.jobs/mcp` directly.\n\n### Cursor\n\nCreate `.cursor/mcp.json` in your project (or `~/.cursor/mcp.json` globally):\n\n```jsonc\n{\n  \"mcpServers\": {\n    \"landed-jobs\": {\n      \"url\": \"https://mcp.landed.jobs/mcp\",\n      \"headers\": { \"Authorization\": \"Bearer lnd_live_your_token_here\" }\n    }\n  }\n}\n```\n\nThen enable **landed-jobs** under **Settings → MCP**. Omit `headers` for the free tier.\n\n### VS Code (GitHub Copilot / Agent Mode)\n\nCreate `.vscode/mcp.json`:\n\n```jsonc\n{\n  \"servers\": {\n    \"landed-jobs\": {\n      \"type\": \"http\",\n      \"url\": \"https://mcp.landed.jobs/mcp\",\n      \"headers\": { \"Authorization\": \"Bearer lnd_live_your_token_here\" }\n    }\n  }\n}\n```\n\nOpen the Chat view → **Agent** mode → the tools appear under the 🔧 picker.\n\n### Windsurf\n\nEdit `~/.codeium/windsurf/mcp_config.json`:\n\n```jsonc\n{\n  \"mcpServers\": {\n    \"landed-jobs\": {\n      \"serverUrl\": \"https://mcp.landed.jobs/mcp\",\n      \"headers\": { \"Authorization\": \"Bearer lnd_live_your_token_here\" }\n    }\n  }\n}\n```\n\n### Cline (VS Code extension)\n\nOpen **Cline → MCP Servers → Configure**, or edit `cline_mcp_settings.json`:\n\n```jsonc\n{\n  \"mcpServers\": {\n    \"landed-jobs\": {\n      \"type\": \"streamableHttp\",\n      \"url\": \"https://mcp.landed.jobs/mcp\",\n      \"headers\": { \"Authorization\": \"Bearer lnd_live_your_token_here\" }\n    }\n  }\n}\n```\n\n### Any other MCP client\n\nPoint it at `https://mcp.landed.jobs/mcp` using the **Streamable HTTP** transport. Pass\n`Authorization: Bearer <token>` if you have one. Quick sanity check from a terminal:\n\n```bash\ncurl -s -X POST https://mcp.landed.jobs/mcp \\\n  -H 'content-type: application/json' \\\n  -H 'accept: application/json, text/event-stream' \\\n  -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools/list\"}'\n```\n\n### Registries\n\nLanded is listed on the [Official MCP Registry](https://registry.modelcontextprotocol.io) as\n`io.github.landedjobs/landed`, and on [Smithery](https://smithery.ai/servers/landedjobs/landed) as\n`landedjobs/landed`. Clients that read either registry can discover and install it without any\nmanual configuration.\n\n---\n\n## Tools\n\n| Tool | What it does | Anonymous cost |\n|------|--------------|:---:|\n| `search_jobs` | Ranked, fit-scored jobs. Supports physical city/country labels plus canonical remote-eligibility country/region codes; free text is parsed server-side. | 1 unit / job returned |\n| `get_job_form` | Application form for a `jobId`, grouped `standard` / `screening` / `eeo` for answer prep. | **free** |\n| `get_learning_content` | Curated interview-prep, portfolio, and roadmap resources. | **free** |\n\n## Prompts (guided workflows)\n\nMCP **prompts** are reusable, user-invocable skills that teach the agent how to chain the tools and\npresent results as a clean shortlist — never raw JSON. In most clients they show up as slash-commands.\n\n| Prompt | Args | What it guides |\n|--------|------|----------------|\n| `find_jobs` | `describe?` | Search, then present a ranked, fit-scored shortlist + next steps. |\n| `prepare_application` | `jobId` | Fetch the form; auto-fill standard, draft screening, leave EEO to the user. |\n| `prep_for_role` | `role?` | Pull learning resources for a role and suggest a study order. |\n\nThe server also ships always-on `instructions` (tool overview, presentation rules, freemium behavior)\nthat compliant clients load automatically.\n\n### Location parameters\n\nLocation eligibility is structured rather than keyword-matched:\n\n- `locations`: physical cities/countries, with country included for ambiguous cities, e.g. `[\"Bengaluru, India\"]`\n- `countryCodes`: ISO alpha-2 remote/base eligibility, e.g. `[\"IN\"]`\n- `regionCodes`: `apac`, `emea`, or `americas`\n- `workAuthorizationCountryCodes`: ISO alpha-2 work-authorization countries\n- `remote`: work mode (`remote`, `hybrid`, or `onsite`)\n\nThe hosted API resolves human city labels to stable place identities. Callers must not invent place\nIDs. The legacy `regions` field remains accepted for compatibility.\n\n---\n\n## Auth & pricing\n\n| Tier | How | What you get |\n|------|-----|--------------|\n| **Anonymous** | No header | A free budget of job-units **that resets every day at 00:00 UTC**. Metered by a hybrid of your IP and an issued `X-Landed-Anon` token (echoed on every response — resend it to keep your budget across sessions). |\n| **Authenticated** | `Authorization: Bearer lnd_live_…` | Unlimited search, personalized to your saved brief + profile. Mint a token at [Landed → Settings → API tokens](https://landed.jobs). |\n\nEvery result carries a `freemium` block so your agent can see how much budget is left and how to lift\nthe cap.\n\n---\n\n## Architecture\n\nThis repository is a **thin, self-hostable proxy**. It speaks MCP and forwards to the hosted Landed\nAPI — it holds **no database, no ranking engine, and no job data**.\n\n```\n   MCP client                 landed-mcp (this repo)              Landed API\n ┌─────────────┐   HTTP    ┌────────────────────────┐  HTTPS   ┌────────────────────────┐\n │ Claude /    │ ───────▶  │ • MCP protocol + tools │ ──────▶  │ • search engine        │\n │ Cursor /    │  /mcp     │ • forwards caller creds│          │ • job corpus + forms   │\n │ VS Code …   │ ◀───────  │ • local learning list  │ ◀──────  │ • auth · freemium meter│\n └─────────────┘           └────────────────────────┘          └────────────────────────┘\n```\n\nThe proxy resolves nothing itself: it forwards the caller's API token (or an anonymous id) to the\nLanded API, which validates it, runs the search, meters usage, and returns results plus a `freemium`\nblock the proxy relays verbatim. The `get_learning_content` catalog is static and lives in this repo\n([`src/mcp/catalog/learning.ts`](src/mcp/catalog/learning.ts)) — that tool works with no backend at all.\n\n---\n\n## Self-host\n\nRun your own proxy against the Landed API (or your own deployment of it).\n\n### Prerequisites\n\n- **Node.js ≥ 20**\n- **pnpm** (`npm i -g pnpm`)\n- A **Landed API base URL** and its **shared internal secret**\n\n### Run\n\n```bash\ngit clone git@github.com:landedjobs/landed-mcp.git\ncd landed-mcp\npnpm install\ncp .env.example .env       # then fill in the values below\npnpm dev                   # hot-reload dev server\n# → [mcp] listening on :8090 — POST /mcp → https://api.landed.jobs/api/v1\n```\n\nFor production: `pnpm start`.\n\n### Environment variables\n\n| Variable | Required | Default | Description |\n|----------|:---:|---------|-------------|\n| `LANDED_API_BASE` | ✓ | `http://localhost:8000/api/v1` | Hosted Landed API base, **including** the `/api/v1` prefix. |\n| `LANDED_INTERNAL_SECRET` | ✓ | — | Shared secret authenticating this proxy to the API (must match the server's `INTERNAL_SERVICE_SECRET`). |\n| `PORT` | | `8090` | HTTP port to listen on. |\n| `CORS_ORIGINS` | | `*` | Comma-separated allowlist of origins, or `*`. |\n| `RATE_LIMIT_PER_MIN` | | `60` | Per-IP first-line request cap. The API's freemium meter is the real economic cap. |\n\n### Endpoints\n\n| Method | Path | Purpose |\n|--------|------|---------|\n| `POST` | `/mcp` | MCP Streamable HTTP endpoint (stateless). |\n| `GET` | `/healthz` | Liveness probe (`{ \"ok\": true }`). |\n\n---\n\n## Development\n\n```bash\npnpm dev           # watch + reload\npnpm check-types   # tsc --noEmit\npnpm test          # deterministic input-contract tests\npnpm start         # run once\n```\n\nThe repository includes official MCP Registry metadata in [`server.json`](server.json). It describes\nthe public Streamable HTTP endpoint but does not imply that the server has been submitted to or\naccepted by any external registry.\n\n**Project layout**\n\n```\nsrc/\n├── index.ts                 # bootstrap: start the HTTP server\n├── config/                  # env → typed config\n├── http/                    # express shell + per-IP rate limiter\n├── services/api-client.ts   # typed fetch client → Landed API\n├── types.ts                 # the API response contract (owned here)\n└── mcp/\n    ├── server.ts            # instructions + tool/prompt registration\n    ├── prompts.ts           # find_jobs / prepare_application / prep_for_role\n    ├── catalog/learning.ts  # static, public learning resources\n    └── tools/               # search_jobs · get_job_form · get_learning_content\n```\n\nStack: TypeScript · Express · [`@modelcontextprotocol/sdk`](https://github.com/modelcontextprotocol/typescript-sdk) · Zod. No database, no build step (runs on `tsx`).\n\n---\n\n## Contributing\n\nIssues and PRs welcome — bug fixes, new client setup guides, and learning-catalog additions especially.\nPlease run `pnpm check-types` and `pnpm test` before opening a PR. For private vulnerability reports,\nfollow [SECURITY.md](SECURITY.md).\n\n## License\n\n[MIT](LICENSE) © Landed\n",
  "bytes": 12311,
  "sha": "a75d2183434f8a6a6b02b316e2506d312b5416e8cb8e07d32695d7010e10e787",
  "repo_slug": "landedjobs/landed-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_landedjobs_landed_e344f6ff/readme"
}