AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
MCP verified MIT Self-run

Career Copilot

mcp-naji-najari-career-copilot · by Naji-Najari

AI hiring copilot built on Google ADK v2. Recruiter mode scores fit + drafts outreach. Candidate mode detects agency postings + generates full interview prep.

— No reviews yet
0 installs
55 views
0.0% view→install

Install

$ agentstack add mcp-naji-najari-career-copilot

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • ✓ Prompt-injection patterns
  • ✓ Secret / credential exfiltration
  • ✓ Dangerous shell & filesystem operations
  • ✓ Untrusted network calls
  • ✓ Known-malicious package signatures

What it can access

  • ✓ Network access No
  • ✓ Filesystem access No
  • ✓ Shell / process execution No
  • ● Environment & secrets Used
  • ✓ Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/mcp-naji-najari-career-copilot)

Reliability & compatibility

✓ Security review passed
0 installs to date
— no reviews yet
○ 5mo ago

Declared compatibility

Claude CodeClaude DesktopCursorWindsurf

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Career Copilot? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Career Copilot

A multi-agent CV × JD pipeline on Google ADK v2.

Live demo · Project write-up


Career Copilot reads a CV against a job description and produces a different output depending on who is asking. Recruiters get a fit verdict and a LinkedIn outreach draft that quotes a real achievement from the CV. Candidates get a company brief researched live through Tavily MCP and a tailored interview-prep bundle.

The point of the project is the orchestration. Google ADK v2 shipped its graph workflow API recently, in the same spirit as LangGraph. This is an end-to-end test of it on a real use case.

Why a graph

A single big-prompt agent works until you need any of: deterministic branching, parallel work, typed contracts at every step, or per-step tracing. Once you do, a graph stops being optional.

  • Explicit topology: nodes, edges, parallel branches, conditional routing, and sync points are first-class.
  • Testable units: each node can be tested, swapped, or traced in isolation.
  • Typed state: contracts at every boundary instead of free-form prompt parsing.
  • Predictable cost: you know upfront which steps run, in what order, and which model serves each.

How it works

flowchart LR
    IN(["CV + JD+ mode"]):::io

    IN --> CV[CV Parser]:::agent
    IN --> JD[JD Parser]:::agent
    CV --> MR(["Mode Router"]):::router
    JD --> MR

    MR -- recruiter --> FA[Fit Analyzer]:::agent
    FA --> VR(["Verdict Router"]):::router
    VR -- fit / borderline --> OW["Outreach Writermedium"]:::agent
    VR -- no_fit --> GE[Gap Explainer]:::agent

    MR -- candidate --> CFORK((·)):::fork
    CFORK --> RA["Research Agent+ Tavily MCP"]:::agent
    CFORK --> CO[CV Optimizer]:::agent
    RA --> IP[Interview Prep]:::agent
    CO --> IP

    OW --> OUT1(["RecruiterFit"]):::io
    GE --> OUT2(["RecruiterNoFit"]):::io
    IP --> OUT3(["CandidateResp"]):::io

    classDef agent fill:#E3F2FD,stroke:#1565C0,stroke-width:2px,color:#0D47A1
    classDef router fill:#E8F5E9,stroke:#2E7D32,stroke-width:1.5px,color:#1B5E20
    classDef fork fill:#9E9E9E,stroke:#616161,stroke-width:1px,color:#9E9E9E
    classDef io fill:#F5F5F5,stroke:#616161,stroke-width:1px,color:#212121

CV and JD are parsed in parallel. The mode router (a FunctionNode, not an LLM) splits the flow:

  • Recruiter branch: linear chain. Fit Analyzer scores fit, Verdict Router routes to Outreach Writer (on fit / borderline) or Gap Explainer (on no_fit).
  • Candidate branch: parallel fan-out. Research Agent (Tavily MCP) and CV Optimizer run concurrently, synchronize through a JoinNode, then feed Interview Prep.

Internal JoinNodes are omitted from the diagram for clarity. See [app/agent/agent.py](backend/app/agent/agent.py) for the full topology.

Architecture decisions

The graph encodes a deliberate separation between deterministic control flow and LLM-driven generation. Routing and synchronization stay in pure Python; only generation crosses an LLM boundary, and every output is constrained by a Pydantic schema before it leaves a node.

  • Control flow stays out of the LLMs. Routing lives in FunctionNodes that decide branches in pure Python on already-typed state. JoinNodes wait for parallel branches to complete before firing downstream. No LLM ever picks which branch fires next, which removes a whole class of failure modes from the critical path.
  • One schema per agent. Each LLM agent declares its own output_schema. Invalid output fails the node loud and fast instead of corrupting state in a downstream agent.
  • Tool-use escape hatch. ADK currently disallows combining output_schema with tools on gpt-5.4-mini. The Research Agent uses the Tavily MCP toolset and emits CompanyIntelligence as a JSON string, validated with model_validate_json at the API boundary so the typed-state invariant is preserved at the edge.

Agents

All agents run OpenAI gpt-5.4-mini via LiteLlm. The Outreach Writer is the only one dialled up to medium reasoning effort.

| Agent | Role | Output schema | | ------------------ | --------- | ------------------------- | | CV Parser | Parser | ParsedCV | | JD Parser | Parser | ParsedJD | | Fit Analyzer | Recruiter | FitVerdict | | Outreach Writer | Recruiter | OutreachDraft | | Gap Explainer | Recruiter | GapReport | | Research Agent | Candidate | CompanyIntelligence | | CV Optimizer | Candidate | CVOptimizationBundle | | Interview Prep | Candidate | InterviewPrepBundle |

Tracing

Every /v1/analyze run is traced end-to-end with Langfuse. Sub-agent calls, tool calls, latency, and token counts nest under a parent agent observation. The filterable trace attributes propagated to Langfuse carry only metadata and sizes (mode, model, version, cv_chars, jd_chars); raw CV and JD content is kept out of the trace tags so traces stay free of PII.

Stack

| Layer | Stack | | --------- | ------------------------------------------------------------------ | | Backend | Python 3.12, FastAPI, Google ADK v2, uv | | Models | OpenAI gpt-5.4-mini via LiteLlm | | Research | Tavily via MCP (McpToolset) | | Frontend | Next.js 15, React 19, Tailwind v4, shadcn/ui, TanStack Query, Zod | | Tracing | Langfuse | | Deploy | Docker (Cloud Run / Fly.io / HuggingFace Spaces) |

Run it

Prerequisites

Install and configure

cd backend
uv sync
cp .env.example .env   # fill in OPENAI_API_KEY and TAVILY_API_KEY

Start the backend

uv run uvicorn app.main:app --reload --port 8080

API docs at . Try POST /v1/analyze with {"cv_text": "...", "jd_text": "...", "mode": "recruiter" | "candidate"}.

Run the tests

uv run pytest tests/ -q

License

[MIT](./LICENSE)

Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.