Skip to main content
Glama
moutasem-isentemiz

workatastartup-mcp

workatastartup-mcp

CI

An MCP server that reads Work at a Startup (Y Combinator) job postings through your own logged-in session.

Work at a Startup keeps its job pages behind a login, so tools that only fetch public URLs get a title and nothing else. This server signs the request with your session cookie, so an AI assistant can pull the full job description the same way you'd see it in the browser.

What it does

It exposes two tools:

  • get_job(jobId) — takes the numeric id from a /jobs/<id> URL and returns the job as structured data: title, company, location, whether it's remote, employment type, role family, minimum experience, salary and equity ranges, visa policy, skills, when the posting went up, whether your account's location is eligible for the role, and the full description. It also hands back the company's slug and URL, so a job can be followed straight to get_company.

  • get_company(slug) — takes the slug from a /companies/<slug> URL (e.g. siphox-health) and returns the company's details — name, batch, tagline, website, location, team size, industry, and founders — along with every role it currently has open (title, id, url, role family, employment type, location, remote flag, experience, salary and equity ranges, visa policy, and skills).

Related MCP server: recruiting-jobs-mcp

Requirements

  • Node.js 18 or newer

  • A Work at a Startup account you're logged into

Install

npm install -g workatastartup-mcp

Or run it straight from npm without installing:

npx workatastartup-mcp

The server reuses your existing session instead of storing your password. You give it your cookie once:

  1. Log in to https://www.workatastartup.com in your browser.

  2. Open the developer tools (F12), go to the Network tab, and reload the page.

  3. Click the first request, find the Cookie request header, and copy its whole value.

  4. Put that value in a WAAS_COOKIE environment variable.

The cookie expires after a while. When the server starts returning "session expired", repeat the steps above for a fresh one.

Connecting it to an MCP client

Add the server to your client's MCP config. For a Claude-style config it looks like this:

{
  "mcpServers": {
    "workatastartup": {
      "command": "npx",
      "args": ["workatastartup-mcp"],
      "env": {
        "WAAS_COOKIE": "paste-your-cookie-here"
      }
    }
  }
}

Once it's connected, ask your assistant to fetch a posting by id, for example: "Get Work at a Startup job 100105." — or ask for a company's open roles: "What is siphox-health hiring for on Work at a Startup?"

How it works

The job pages are an Inertia.js app: instead of server-rendering the content, they ship the whole page as JSON inside a data-page attribute and let the browser draw it. The server reads that JSON straight from the attribute, so you get clean structured fields rather than scraped text — and it needs nothing heavier than a single authenticated HTTP request per job, no headless browser.

The same job is serialised differently depending on which page you land on: camelCase on a job page (minExperience), snake_case with pretty_* display variants inside a company's payload (pretty_min_experience). The parser accepts either spelling and prefers the display variant when both are there, since that's the string the site itself would show — Remote (US only) rather than a bare office city.

Batch mode from the command line

Run with one or more job ids and the same binary works as a plain CLI instead of the MCP server — handy for scripting, a saved queue of ids, or a quick check without wiring up a client. Each job streams to stdout as it's fetched, one JSON record per line, so you can pipe it straight into jq:

WAAS_COOKIE=... npx workatastartup-mcp --json 100105 100106 | jq .title

Without --json each record is pretty-printed. A bad id doesn't stop the run — it prints an { "jobId": ..., "error": ... } record and the command exits non-zero if any id failed. Run it with --help for the full usage.

Draining a staged queue

If you collect postings as you browse, put them in a file and let --from chew through it:

WAAS_COOKIE=... npx workatastartup-mcp --json --from queue.txt > jobs.jsonl

One entry per line, in whatever shape you copied it — a bare id, a /jobs/<id> path, or the whole URL out of the address bar. Blank lines and # comments are skipped, so the file can carry notes:

# worth a closer look
100105
https://www.workatastartup.com/jobs/100106?utm_source=share  # remote, hardware

A job listed twice is fetched once, the ids are fetched in the order you staged them, and a line that isn't an id is reported on stderr and skipped rather than ending the run. --from - reads the queue from stdin, so grep, jq or a browser export can pipe straight in. Ids on the command line work the same way and are fetched first.

Development

npm test

The tests run the parsers against saved pages in test/fixtures — trimmed copies of what the site serves, payload and all — so the whole extraction path is covered without a session cookie or a network call. If Work at a Startup changes its markup, save a fresh page into test/fixtures and the tests will show what moved.

GitHub Actions runs the same suite on every push and pull request, across Node 18 through 24 — see .github/workflows/ci.yml.

Limitations

  • Only reads public-to-you postings — anything your account can't see, the server can't see either.

  • Field extraction is best-effort against the current page markup; if Work at a Startup restructures a page, the selectors in src/job-client.js may need a small update.

  • Through the MCP tools it's one posting per call; use the batch CLI above to fetch several ids at once.

  • The CLI fetches one job at a time, on purpose — it's your own session doing the reading, so a queue of a few hundred takes a few minutes.

License

MIT — see LICENSE.

Available Tools

1 tool
get_companyA

Fetch a Work at a Startup (workatastartup.com) company by its slug and return the company's details along with the roles it currently has open. Needs a WAAS_COOKIE holding your logged-in session.

ParametersJSON Schema
NameRequiredDescriptionDefault
slugYesCompany slug from a /companies/<slug> URL, e.g. "siphox-health".

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations exist, so description carries full burden. It discloses authentication requirement (cookie), which is key behavioral info. No mention of side effects or rate limits, but fetch operation is implied read-only.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, no wasted words. Front-loaded with action and output. Efficient and easy to parse.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Describes return content (company details and open roles) despite no output schema. No mention of error handling, but adequate for a simple single-param tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema has 100% description coverage for the single parameter 'slug'. Description does not add extra meaning beyond the schema's example; baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description clearly states it fetches a company by slug and returns details and open roles. Verb 'Fetch' and resource 'company' are specific. No sibling tools to distinguish, but the description is precise.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Specifies prerequisite: needs a WAAS_COOKIE with logged-in session. No alternatives or when-not-to-use given, but clarity on context is sufficient.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

TDQS

A4/5.0
Disambiguation5/5

With only one tool, there is zero ambiguity. An agent will always select get_company.

Naming Consistency5/5

The single tool name 'get_company' follows a clear verb_noun pattern. Consistent and descriptive.

Tool Count2/5

A single tool for what implies a broader domain (company and role retrieval) is too thin. Ideally there would be at least listing or search capabilities.

Completeness2/5

Only a read operation exists. Missing essential operations like list, search, or any mutation endpoints, leaving obvious gaps for the domain.

Maintenance

ActivityMaintained
ResponsivenessSyncing

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/moutasem-isentemiz/workatastartup-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server