Skip to content
← Back to work

Autonomous Overnight Ops Agent

TypeScript · custom MCP server · Claude Agent SDK · scheduled task

The problem

A service desk's worst hour is the first one: staff arrive to an inbox of overnight messages, routine quote requests mixed with the occasional emergency. This agent does the triage overnight, so that hour starts already sorted — and the genuinely urgent items are flagged before anyone reads them.

It's also the demo that closes a gap. My other four show prompt engineering, evals, and Claude API/Code workflows. This one is built on the newer agentic primitives a Claude specialist gets asked for: a custom MCP server, the Agent SDK, an autonomous tool-using loop, and a scheduled trigger — in TypeScript.

Architecture

schedule (07:00) ↓ Claude Agent SDK loop src/agent/run.ts (Claude reasons + plans) ↓ MCP (stdio) northgate-ops MCP server src/mcp-server/server.ts 5 tools over the CRM + KB ↓ customers · service history · overnight queue · pricing · escalation

The custom MCP server

A standalone Model Context Protocol server (@modelcontextprotocol/sdk) exposes the service desk as five typed tools: lookup_customer, get_service_history, list_overnight_queue, search_knowledge_base, and log_to_crm. Inputs are validated with Zod. The data layer is a thin seam — local JSON today, a real CRM/DMS in production — so the tool surface never changes. Because it speaks plain MCP, the same server drops straight into Claude Code or Cowork.

The agent loop, per message

  • Match the sender to a customer; pull service history when it's relevant (context for comebacks).
  • Ground any price or escalation question against the knowledge base — never invent a number.
  • Decide a category, an urgency, and whether a human must take over before any reply goes out.
  • Write a ready-to-send draft and log the decision to the CRM.

What it produced (verified run)

MSG-9001  [quote-request/medium]            Daniel Reyes
MSG-9002  [quote-request/medium]            Marisol Tan
MSG-9003  [complaint/high]      ⚠ HUMAN     Grace Villanueva
MSG-9004  [quote-request/medium]            Erwin Castillo
MSG-9005  [safety/high]         ⚠ HUMAN     Unknown caller

Triaged 5 messages — 2 flagged for a human.
Most urgent: MSG-9003 — comeback after a paid repair — senior advisor must call.

The complaint (a repair that didn't hold) and the overheating engine are pulled out for a human; the safety reply tells the customer not to drive and that the team will arrange a tow. Routine quotes get drafts and are logged. Nothing irreversible happens autonomously — the agent stages decisions for a person to release.

Honest about what's verified

The demo is explicit about what runs where. The MCP server and the full triage pipeline are tested end-to-end offlinenpm test exercises all five tools with no model (10 assertions), and npm run dry-run drives the real MCP client/server through the whole pipeline. The Agent SDK adds the reasoning layer on top and runs live on a Claude subscription; the runner even falls back to the deterministic dry-run if the SDK or auth is unavailable, so the demo never hard-fails. Building the testable core so it doesn't depend on a paid call — that's the difference between "I wired an agent" and "I can ship one".

← Back to work