MCP server for the Kardow job board platform, enabling job posting, company management, location resolution, and employer search via OAuth or API key authentication
kardow-mcp has well-structured tool definitions with clear naming (verb_noun pattern) and comprehensive descriptions (avg 180 chars). All 4 tools have Zod schemas with typed parameters and descriptions. However, output schemas are not formally documented, responses are text-based content arrays without structured field definitions. Error handling is present but generic ('API error: ...'). Missing tool annotations (readOnlyHint/destructiveHint). The scrape_job_from_url tool description is instructional rather than declarative, which may confuse LLM tool selection.
Add a company to the job board from its website, or look up what we can find about a website before adding it. Pass the company's own domain (e.g. 'stripe.com'). We read their site and pull in the name, logo, description, social profiles, industry, HQ location, founded year and careers page automatically. This is far better than typing a name: a name alone produces a company with no branding. Set preview: true to see what we would find WITHOUT saving anything. Use that when the user should confirm first. If the company already exists on this board, this updates it rather than creating a duplicate. Do NOT pass a LinkedIn, Facebook, Indeed or applicant-tracking (Greenhouse/Lever/Workday) URL. Those are not company websites and will be rejected.
Search for employer accounts on the job board by name or email. Use this before create_job when the user wants to post a job on behalf of a specific employer — get their email from the results, then pass it to create_job as posted_by_email. Requires the API key to have members:read scope.
List the companies on this job board, with their job counts. Use this before create_company to check whether a company already exists, and to find the exact name a board already uses.
Fetch the text content of a job posting page. Use the returned text to extract structured job details, then call create_job to post it to the board.
Output schemas not formally documented. Tools return text-based content arrays; LLMs cannot infer structured fields for downstream chaining. E.g., find_employer returns user objects but no schema declares 'id', 'email', 'name' fields.
Missing tool annotations. No readOnlyHint on read tools (scrape_job_from_url, find_employer, list_companies) or destructiveHint on create_company. Agents cannot distinguish safe from risky operations.
scrape_job_from_url description is instructional ('extract: title, company_name...') rather than declarative. It tells the LLM what to do after calling the tool instead of what the tool does. This violates the tool-description pattern.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 67 | <=2025-11-25 | v2 |
Error responses are generic text ('API error: {...}'). No recovery guidance or error classification (retryable vs user-fixable). LLMs cannot determine next steps on failure.
create_company accepts 'website' as string but description warns against LinkedIn/Indeed/ATS URLs without formal validation. No enum or regex constraint. LLMs may pass invalid URLs.