← All blueprints

Recruiting Screener CrewAI

blueprint · 3 agents · 3 MCP servers
878★ stars
111forks
4.5rating

What it does

An intake agent converts the job description into explicit must-have and nice-to-have criteria. A screener reads each résumé from the drive folder and scores it against those criteria with cited evidence, ignoring names and schools to reduce bias. A ranker builds a shortlist, records it for the hiring team, and drafts a specific outreach note for the top candidates. A clean sequential crew; a human makes the actual call.

The cast · 3 agents

Intakeintakereasoning

Turn the job description into a concrete rubric: must-have skills and experience, nice-to-haves, and clear disqualifiers. Keep it specific enough to score against.

no tools · reasoning only
Rankerrankerfast

Rank the candidates by score, produce a shortlist with a one-line reason each, record it for the hiring team, and draft a warm, specific outreach note for the top candidates. Do not send; leave the notes as drafts.

drive.draft_email
Screenerscreenerreasoning

Read each résumé in the folder and score it against the rubric, citing the evidence for every point. Judge on demonstrated skills and experience only — ignore names, schools, and photos. Flag anything you could not verify.

drive.list_filesdrive.read_doc

Flow

→ Intake → criteria
→ Screener → scores
→ Ranker → shortlist

Interface

Inputs
jdstring
The job description, and the drive folder of résumés to screen.
Outputs
shortliststring
The ranked shortlist with reasons and the drafted outreach notes.
⤓ Export runnable code
# Generated by @socketcat/compiler for target: langgraph
# blueprint: com.socketcat/recruiting-screener v1.0.0   schema: socketcat.dev/blueprint/v0
# This code is yours. Edit it freely. The socketcat_runtime helper is optional and can be vendored.

from typing import TypedDict
from langgraph.graph import StateGraph, START, END
import socketcat_runtime as _rt

class State(TypedDict, total=False):
    jd: object
    shortlist: object
    criteria: object
    scores: object

def node_AgentInvoke_0(state):
    return _rt.run_agent("intake", state, {"jd":"jd"}, "criteria")

def node_AgentInvoke_1(state):
    return _rt.run_agent("screener", state, {"criteria":"criteria"}, "scores")

def node_AgentInvoke_2(state):
    return _rt.run_agent("ranker", state, {"scores":"scores"}, "shortlist")

def build():
    b = StateGraph(State)
    b.add_node("AgentInvoke_0", node_AgentInvoke_0)
    b.add_node("AgentInvoke_1", node_AgentInvoke_1)
    b.add_node("AgentInvoke_2", node_AgentInvoke_2)
    b.add_edge(START, "AgentInvoke_0")
    b.add_edge("AgentInvoke_0", "AgentInvoke_1")
    b.add_edge("AgentInvoke_1", "AgentInvoke_2")
    b.add_edge("AgentInvoke_2", END)
    return b.compile()

INPUTS = ["jd"]
OUTPUTS = ["shortlist"]

if __name__ == "__main__":
    _rt.main(build, INPUTS, OUTPUTS)
▸blueprint.json (the portable format)
{
  "id": "com.socketcat/recruiting-screener",
  "flow": {
    "type": "sequence",
    "blocks": [
      {
        "in": {
          "jd": "jd"
        },
        "out": "criteria",
        "use": "intake",
        "type": "agent"
      },
      {
        "in": {
          "criteria": "criteria"
        },
        "out": "scores",
        "use": "screener",
        "type": "agent"
      },
      {
        "in": {
          "scores": "scores"
        },
        "out": "shortlist",
        "use": "ranker",
        "type": "agent"
      }
    ]
  },
  "tags": [
    "hr",
    "recruiting",
    "sequential",
    "screening"
  ],
  "title": "Recruiting Screener",
  "agents": {
    "intake": {
      "model": {
        "hint": "reasoning"
      },
      "title": "Intake",
      "instructions": "Turn the job description into a concrete rubric: must-have skills and experience, nice-to-haves, and clear disqualifiers. Keep it specific enough to score against."
    },
    "ranker": {
      "model": {
        "hint": "fast"
      },
      "title": "Ranker",
      "tools": [
        "drive.draft_email"
      ],
      "instructions": "Rank the candidates by score, produce a shortlist with a one-line reason each, record it for the hiring team, and draft a warm, specific outreach note for the top candidates. Do not send; leave the notes as drafts."
    },
    "screener": {
      "model": {
        "hint": "reasoning"
      },
      "title": "Screener",
      "tools": [
        "drive.list_files",
        "drive.read_doc"
      ],
      "instructions": "Read each résumé in the folder and score it against the rubric, citing the evidence for every point. Judge on demonstrated skills and experience only — ignore names, schools, and photos. Flag anything you could not verify."
    }
  },
  "estate": {
    "scores": {
      "type": "array",
      "description": "The screener's per-candidate scores with evidence."
    },
    "criteria": {
      "type": "object",
      "description": "The intake agent's must-haves and nice-to-haves from the JD."
    }
  },
  "$schema": "socketcat.dev/blueprint/v0",
  "authors": [
    {
      "url": "https://socketcat.com",
      "name": "SocketCat"
    }
  ],
  "license": "MIT",
  "servers": [
    {
      "ref": "io.github.adelaidasofia/google-workspace-mcp",
      "alias": "drive"
    },
    {
      "ref": "io.github.modelcontextprotocol/filesystem",
      "alias": "fs"
    },
    {
      "ref": "app.linear/linear",
      "alias": "tracker"
    }
  ],
  "summary": "Turns a job description into scored, evidence-backed candidate rankings and drafts outreach to the top few.",
  "targets": [
    "crewai",
    "langgraph",
    "*"
  ],
  "version": "1.0.0",
  "interface": {
    "inputs": {
      "jd": {
        "type": "string",
        "description": "The job description, and the drive folder of résumés to screen."
      }
    },
    "outputs": {
      "shortlist": {
        "type": "string",
        "description": "The ranked shortlist with reasons and the drafted outreach notes."
      }
    }
  },
  "extensions": {
    "com.crewai": {
      "process": "sequential"
    }
  },
  "description": "An intake agent converts the job description into explicit must-have and nice-to-have criteria. A screener reads each résumé from the drive folder and scores it against those criteria with cited evidence, ignoring names and schools to reduce bias. A ranker builds a shortlist, records it for the hiring team, and drafts a specific outreach note for the top candidates. A clean sequential crew; a human makes the actual call."
}

More in Productivity & HR

Browse all →

Inbox Chief of Staff

com.socketcat/inbox-chief-of-staff
Custom

Triages your inbox, then routes each thread to the right handler — draft a reply, propose meeting times, or file it — with your approval before anything sends.

★ 14023 servers
⑂ 201

Meeting to Action

com.socketcat/meeting-to-action
LangGraph

Turns a meeting transcript into a summary, then files the action items as tracked tickets and calendar follow-ups in parallel — and posts the recap.

★ 11763 servers
⑂ 158

Standup Digest

com.socketcat/standup-digest
CrewAI

Every morning it reads yesterday's tracker and GitHub activity, groups it by person, and posts a tight digest so standup is a read, not a round-robin.

★ 10243 servers
⑂ 138