← All blueprints

Inbox Chief of Staff Custom

blueprint · 4 agents · 3 MCP servers
1402★ stars
201forks
4.8rating

What it does

A triager classifies each unread thread as needs-reply, needs-scheduling, or FYI. A router sends each to the right handler: a reply drafter writes a response in the user's voice, a scheduler reads the calendar and drafts an invite with proposed times, and FYI items are filed to notes with a summary. Any send or invite pauses for human approval. This blueprint showcases a routing step that fans work out to specialized handlers by category.

The cast · 4 agents

Filerfilerfast

For FYI threads, write a one-line summary to the user's notes so nothing is lost, and mark the thread read. No reply.

notes.create_page
Triagertriagerfast

Read the unread threads and classify each as 'reply', 'schedule', or 'fyi'. Report the category and a one-line reason per thread. When unsure between reply and fyi, choose reply.

mail.list_messages
Schedulerschedulerfast

For threads needing scheduling, read the calendar for open slots and draft an invite proposing two or three times. Do not send the invite; leave it as a draft.

mail.list_eventsmail.draft_invite
Reply DrafterreplyDrafterreasoning

For threads needing a reply, draft a response in the user's voice that moves the thread forward. Keep it concise. Save as a draft; never send.

mail.draft_email

Flow

Triagertriaged
⑂ route (by triaged.category)
reply
Reply Draftersummary
asksummary
schedule
Schedulersummary
asksummary
fyi
Filersummary

Interface

Inputs
batchstring
Which mail to process, e.g. 'unread since yesterday'.
Outputs
summarystring
What was drafted, scheduled, or filed this pass.
⤓ Export runnable code
# Generated by @socketcat/compiler for target: langgraph
# blueprint: com.socketcat/inbox-chief-of-staff 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):
    batch: object
    summary: object
    triaged: object
    __route_Route_1: object

def node_AgentInvoke_0(state):
    return _rt.run_agent("triager", state, {"batch":"batch"}, "triaged")

def node_Route_1(state):
    return _rt.run_route("triaged.category", state, "__route_Route_1")

def node_Join_2(state):
    return {}

def node_AgentInvoke_3(state):
    return _rt.run_agent("replyDrafter", state, {"triaged":"triaged"}, "summary")

def node_Ask_4(state):
    return _rt.run_ask("Review the drafted replies. Approve to send, or edit first.", state, "summary")

def node_AgentInvoke_5(state):
    return _rt.run_agent("scheduler", state, {"triaged":"triaged"}, "summary")

def node_Ask_6(state):
    return _rt.run_ask("Review the proposed times and draft invite. Approve to send.", state, "summary")

def node_AgentInvoke_7(state):
    return _rt.run_agent("filer", state, {"triaged":"triaged"}, "summary")

def node_AgentInvoke_8(state):
    return _rt.run_agent("filer", state, {"triaged":"triaged"}, "summary")

def route_Route_1(state):
    lbl = state.get("__route_Route_1")
    if lbl == "reply": return "AgentInvoke_3"
    if lbl == "schedule": return "AgentInvoke_5"
    if lbl == "fyi": return "AgentInvoke_7"
    return "AgentInvoke_8"

def build():
    b = StateGraph(State)
    b.add_node("AgentInvoke_0", node_AgentInvoke_0)
    b.add_node("Route_1", node_Route_1)
    b.add_node("Join_2", node_Join_2)
    b.add_node("AgentInvoke_3", node_AgentInvoke_3)
    b.add_node("Ask_4", node_Ask_4)
    b.add_node("AgentInvoke_5", node_AgentInvoke_5)
    b.add_node("Ask_6", node_Ask_6)
    b.add_node("AgentInvoke_7", node_AgentInvoke_7)
    b.add_node("AgentInvoke_8", node_AgentInvoke_8)
    b.add_edge(START, "AgentInvoke_0")
    b.add_edge("AgentInvoke_0", "Route_1")
    b.add_conditional_edges("Route_1", route_Route_1, {"AgentInvoke_3": "AgentInvoke_3", "AgentInvoke_5": "AgentInvoke_5", "AgentInvoke_7": "AgentInvoke_7", "AgentInvoke_8": "AgentInvoke_8"})
    b.add_edge("Join_2", END)
    b.add_edge("AgentInvoke_3", "Ask_4")
    b.add_edge("Ask_4", "Join_2")
    b.add_edge("AgentInvoke_5", "Ask_6")
    b.add_edge("Ask_6", "Join_2")
    b.add_edge("AgentInvoke_7", "Join_2")
    b.add_edge("AgentInvoke_8", "Join_2")
    return b.compile()

INPUTS = ["batch"]
OUTPUTS = ["summary"]

if __name__ == "__main__":
    _rt.main(build, INPUTS, OUTPUTS)
blueprint.json (the portable format)
{
  "id": "com.socketcat/inbox-chief-of-staff",
  "flow": {
    "type": "sequence",
    "blocks": [
      {
        "in": {
          "batch": "batch"
        },
        "out": "triaged",
        "use": "triager",
        "type": "agent"
      },
      {
        "by": "triaged.category",
        "else": [
          {
            "in": {
              "triaged": "triaged"
            },
            "out": "summary",
            "use": "filer",
            "type": "agent"
          }
        ],
        "type": "route",
        "cases": [
          {
            "label": "reply",
            "blocks": [
              {
                "in": {
                  "triaged": "triaged"
                },
                "out": "summary",
                "use": "replyDrafter",
                "type": "agent"
              },
              {
                "out": "summary",
                "type": "ask",
                "prompt": "Review the drafted replies. Approve to send, or edit first."
              }
            ]
          },
          {
            "label": "schedule",
            "blocks": [
              {
                "in": {
                  "triaged": "triaged"
                },
                "out": "summary",
                "use": "scheduler",
                "type": "agent"
              },
              {
                "out": "summary",
                "type": "ask",
                "prompt": "Review the proposed times and draft invite. Approve to send."
              }
            ]
          },
          {
            "label": "fyi",
            "blocks": [
              {
                "in": {
                  "triaged": "triaged"
                },
                "out": "summary",
                "use": "filer",
                "type": "agent"
              }
            ]
          }
        ]
      }
    ]
  },
  "tags": [
    "productivity",
    "email",
    "routing",
    "human-in-the-loop"
  ],
  "title": "Inbox Chief of Staff",
  "agents": {
    "filer": {
      "model": {
        "hint": "fast"
      },
      "title": "Filer",
      "tools": [
        "notes.create_page"
      ],
      "instructions": "For FYI threads, write a one-line summary to the user's notes so nothing is lost, and mark the thread read. No reply."
    },
    "triager": {
      "model": {
        "hint": "fast"
      },
      "title": "Triager",
      "tools": [
        "mail.list_messages"
      ],
      "instructions": "Read the unread threads and classify each as 'reply', 'schedule', or 'fyi'. Report the category and a one-line reason per thread. When unsure between reply and fyi, choose reply."
    },
    "scheduler": {
      "model": {
        "hint": "fast"
      },
      "title": "Scheduler",
      "tools": [
        "mail.list_events",
        "mail.draft_invite"
      ],
      "instructions": "For threads needing scheduling, read the calendar for open slots and draft an invite proposing two or three times. Do not send the invite; leave it as a draft."
    },
    "replyDrafter": {
      "model": {
        "hint": "reasoning"
      },
      "title": "Reply Drafter",
      "tools": [
        "mail.draft_email"
      ],
      "instructions": "For threads needing a reply, draft a response in the user's voice that moves the thread forward. Keep it concise. Save as a draft; never send."
    }
  },
  "estate": {
    "triaged": {
      "type": "object",
      "description": "The triager's classification of each thread, including a 'category'."
    }
  },
  "$schema": "socketcat.dev/blueprint/v0",
  "authors": [
    {
      "url": "https://socketcat.com",
      "name": "SocketCat"
    }
  ],
  "license": "MIT",
  "servers": [
    {
      "ref": "io.github.adelaidasofia/google-workspace-mcp",
      "alias": "mail"
    },
    {
      "ref": "com.notion/mcp",
      "alias": "notes"
    },
    {
      "ref": "io.github.slack/slack-mcp",
      "alias": "chat"
    }
  ],
  "summary": "Triages unread mail and routes each thread to a reply drafter, a scheduler, or a filer, pausing for approval before anything sends.",
  "targets": [
    "langgraph",
    "*"
  ],
  "version": "1.0.0",
  "interface": {
    "inputs": {
      "batch": {
        "type": "string",
        "description": "Which mail to process, e.g. 'unread since yesterday'."
      }
    },
    "outputs": {
      "summary": {
        "type": "string",
        "description": "What was drafted, scheduled, or filed this pass."
      }
    }
  },
  "extensions": {
    "dev.langgraph": {
      "checkpointer": "memory"
    }
  },
  "description": "A triager classifies each unread thread as needs-reply, needs-scheduling, or FYI. A router sends each to the right handler: a reply drafter writes a response in the user's voice, a scheduler reads the calendar and drafts an invite with proposed times, and FYI items are filed to notes with a summary. Any send or invite pauses for human approval. This blueprint showcases a routing step that fans work out to specialized handlers by category."
}

More in Productivity & HR

Browse all →

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

Recruiting Screener

com.socketcat/recruiting-screener
CrewAI

Turns a job description into a ranked shortlist: reads résumés from your drive, scores them against the role, and drafts outreach to the top few.

8783 servers
111