Skip to main content
Glama

DHL Ops Copilot - MCP + ADK Edition

A re-architected version of DHL Ops Copilot, migrating the original custom function-calling tool layer to the Model Context Protocol (FastMCP) and rebuilding multi-agent orchestration on Google's Agent Development Kit (ADK).


What Changed From The Original

Component

Original Version

MCP + ADK Edition

Why It Matters

Tool Layer

Custom dict-based JSON schemas & manual dispatch function

Standardized Model Context Protocol (FastMCP 4.0)

Decouples tools from any single LLM or client; standard MCP clients (Claude Desktop, ADK, Cursor) can inspect & consume tools without custom code.

Agent Orchestration

Manual while-loop and chat completion message passing

Google ADK (LlmAgent + SequentialAgent)

Native pipeline orchestration with structured state passing and pipeline inspection.

LLM Provider & Model

Groq (llama-3.3-70b-versatile)

Google Gemini (gemini-3.6-flash)

Leverages Google AI Studio free-tier quotas and structured tool calling.

Transport Protocol

In-process Python imports

Dual-mode: Local stdio & Remote streamable-http

Runs locally via stdio with zero network overhead, and deploys to cloud hosting via Streamable HTTP.


Related MCP server: agentic-mcp-gateway

What Stayed The Same (Core Provenance)

  1. Deterministic ID-Pattern Fallback:

    • SHP-xxxx: Normalizes numeric inputs (e.g. 2044 -> SHP-2044) and matches shipment tracking records with hub status and ETA.

    • SO-xxxxx: Normalizes SAP order numbers (e.g. 88213 -> SO-88213) and reports sync status and errors (MATERIAL_MASTER_NOT_FOUND, DUPLICATE_ORDER_REFERENCE).

    • INCxxxx: Normalizes ServiceNow ticket IDs (e.g. 43 -> INC0043) or performs substring matching across issue descriptions.

    • Malformed/garbage IDs gracefully trigger deterministic fallback dictionaries without throwing unhandled exceptions.

  2. SQLite Audit Trail:

    • Every tool execution logs an immutable record to mcp_server/audit.db (id, ts, tool, query, result_status).

    • Note on Render free tier: The free tier filesystem is ephemeral, meaning audit.db resets on container redeploy. For persistent enterprise audit logs, configure a managed SQLite/PostgreSQL mount.

  3. Investigator / Synthesis Hallucination-Constraint Pattern:

    • Investigator Agent: Prohibited from answering the user directly; strictly tasked with calling tools and outputting evidence into {evidence}.

    • Synthesizer Agent: Strictly constrained to {evidence}, requiring inline citations and refusing ungrounded claims.


MCP Tools Description and Details

The FastMCP server (mcp_server/server.py) standardizes operational data access across three core enterprise systems plus internal procedural runbooks.

1. Shipment Tracking Tool: get_shipment_status

Look up live shipment tracking details by tracking identifier.

  • Signature: get_shipment_status(tracking_id: str) -> Dict[str, Any]

  • Input Parameters:

    • tracking_id (string, required): Tracking code formatted as SHP-xxxx (e.g. SHP-2044, SHP-3311) or numeric digits (e.g. 2044).

  • Return Shape:

    {
      "shipment_id": "SHP-2044",
      "found": true,
      "status": "In transit",
      "current_hub": "Frankfurt Hub",
      "eta": "2026-09-13",
      "note": "On schedule.",
      "source": "simulated shipment tracking system"
    }
  • Fallback Behavior: Malformed IDs or missing records return {"shipment_id": "...", "found": false, "status": "not_found", "fallback_applied": true} without raising exceptions.

  • Audit Trace: Logs tool name, tracking ID query, and status to mcp_server/audit.db.


2. SAP Order Backend Tool: get_sap_order

Retrieve enterprise sales order sync status and backend error codes from SAP.

  • Signature: get_sap_order(order_id: str) -> Dict[str, Any]

  • Input Parameters:

    • order_id (string, required): SAP order code formatted as SO-xxxxx (e.g. SO-88213, SO-90144) or numeric digits (e.g. 88213).

  • Return Shape:

    {
      "order_id": "SO-88213",
      "found": true,
      "status": "Sync failed",
      "error_code": "MATERIAL_MASTER_NOT_FOUND",
      "order_value_usd": 4210.00,
      "note": "SKU replication pending.",
      "source": "simulated SAP backend"
    }
  • Fallback Behavior: Malformed IDs return {"order_id": "...", "found": false, "status": "not_found", "fallback_applied": true}.

  • Audit Trace: Logs tool name, order ID query, and status to mcp_server/audit.db.


3. ServiceNow Ticket Tool: get_servicenow_ticket

Look up IT support incident tickets by exact identifier or search by issue keyword.

  • Signature: get_servicenow_ticket(ticket_id: str) -> Dict[str, Any]

  • Input Parameters:

    • ticket_id (string, required): Ticket identifier (e.g. INC0043, 43) or search query (e.g. VPN, sync).

  • Return Shape (Exact Match):

    {
      "ticket_id": "INC0043",
      "found": true,
      "priority": "P2",
      "status": "In Progress",
      "description": "SAP order sync failures reported by 6 regional support agents, multiple orders showing MATERIAL_MASTER_NOT_FOUND.",
      "source": "simulated ServiceNow instance"
    }
  • Return Shape (Keyword Match):

    {
      "query": "VPN",
      "found": true,
      "status": "matches_found",
      "matches": [
        {
          "ticket_id": "INC0091",
          "priority": "P3",
          "status": "Open",
          "description": "Single user unable to connect to VPN, certificate appears expired."
        }
      ],
      "source": "simulated ServiceNow instance"
    }
  • Audit Trace: Logs tool name, ticket ID or query string, and status to mcp_server/audit.db.


4. Standard Operating Procedures Tool: retrieve_sop

Search internal knowledge base runbooks, escalation policies, and procedures.

  • Signature: retrieve_sop(query: str) -> Dict[str, Any]

  • Input Parameters:

    • query (string, required): Natural language search terms (e.g. VPN expired certificate, SAP sync error, customs hold).

  • Return Shape:

    {
      "query": "VPN expired certificate",
      "found": true,
      "status": "found",
      "results": [
        {
          "id": "SOP-VPN-01",
          "title": "VPN Access Troubleshooting",
          "text": "If user cannot connect to VPN: 1. Confirm AD account active. 2. Check VPN cert validity..."
        }
      ],
      "source": "internal knowledge base"
    }
  • Audit Trace: Logs tool name, search query, and status to mcp_server/audit.db.


How To Use In The Frontend

Option A: Google ADK Web UI (Built-In Browser Interface)

The primary frontend interface is powered by Google ADK Web, providing a full chat window with real-time tool execution tracking.

Step 1: Start the Web UI Server

adk web agent --port 8085

Step 2: Open In Browser

Navigate to:

http://127.0.0.1:8085

Step 3: Select Agent & Start Session

  1. On the left navigation pane, select agent (or the loaded application).

  2. Click New Session to open a fresh chat workspace.

Step 4: Interact With Operational Queries

Type natural-language requests into the chat input:

  • Single System Query: What is the current status and location of shipment SHP-2044? The investigator agent automatically calls get_shipment_status("SHP-2044"), and the synthesizer outputs the grounded status with inline citation [get_shipment_status].

  • Multi-System Correlation: Check SAP order SO-88213 and ServiceNow ticket INC0043. The pipeline executes parallel lookups for both systems, detects the MATERIAL_MASTER_NOT_FOUND error, automatically retrieves runbook SOP-SAPSYNC-04, and presents a structured incident brief.

  • Keyword Search: Are there any active tickets regarding VPN access issues? The pipeline calls get_servicenow_ticket("VPN") and returns matching open incidents.

  • Runbook Procedures: What is our policy for shipments delayed on customs hold? The pipeline queries retrieve_sop("customs hold") and summarizes SOP-CUSTOMSHOLD-06.

  • Malformed ID Handling: Look up shipment SHP-INVALID-999. The pipeline gracefully reports that no records were found without crashing.

Step 5: Inspect Evidence & Tool Traces

In the ADK Web UI:

  • Click on the intermediate execution steps to view raw JSON outputs returned by FastMCP tools.

  • Expand the {evidence} dictionary to inspect the exact payload passed from the investigator to the synthesizer.


Option B: Claude Desktop / Cursor (Standard MCP Client)

Because the tool layer uses standard FastMCP, any MCP-compliant frontend can connect to mcp_server/server.py.

Stdio Connection (Local)

Add to claude_desktop_config.json:

{
  "mcpServers": {
    "dhl-ops-tools": {
      "command": "python",
      "args": ["/absolute/path/to/dhl-ops-mcp/mcp_server/server.py"]
    }
  }
}

Streamable HTTP Connection (Remote / Render)

When hosted on Render:

{
  "mcpServers": {
    "dhl-ops-tools": {
      "url": "https://dhl-ops-mcp-server.onrender.com/mcp"
    }
  }
}

Repository Structure

dhl-ops-mcp/
|-- mcp_server/
|   |-- __init__.py
|   |-- server.py
|   |-- audit.py
|   |-- fallback.py
|   \-- audit.db
|-- agent/
|   |-- __init__.py
|   |-- agent.py
|   |-- .env.example
|   \-- .env
|-- tests/
|   |-- __init__.py
|   |-- test_mcp_server.py
|   \-- test_e2e.py
|-- .env.example
|-- pyproject.toml
|-- requirements.txt
|-- render.yaml
\-- README.md

Setup & Local Development

1. Installation

git clone https://github.com/az-cod/DHL_OPS_COPILOT.git dhl-ops-mcp
cd dhl-ops-mcp
git checkout mcp-adk-migration

python -m venv .venv
.venv\Scripts\activate
pip install -r requirements.txt

2. Configure Environment

Create agent/.env (from agent/.env.example):

GOOGLE_API_KEY=your_gemini_api_key_from_ai_studio
GOOGLE_GENAI_USE_VERTEXAI=FALSE
ADK_DEFAULT_MODEL=gemini-3.6-flash

3. Test MCP Server in Isolation

Run the test suite or launch FastMCP inspector:

pytest tests/ -v
fastmcp dev mcp_server/server.py

4. Run ADK Agent Locally

Launch the ADK web chat interface:

adk web agent --port 8085

Deployment (Render Free Tier)

Deploying as two independent microservices on Render:

  1. dhl-ops-mcp-server:

    • Runtime: Python

    • Build command: pip install -r requirements.txt

    • Start command: python mcp_server/server.py

    • Env vars:

      • PORT: 8080

      • MCP_TRANSPORT: streamable-http

  2. dhl-ops-adk-agent:

    • Runtime: Python

    • Build command: pip install -r requirements.txt

    • Start command: adk web agent --host 0.0.0.0 --port 10000

    • Env vars:

      • GOOGLE_API_KEY: (Set securely in Render Dashboard)

      • MCP_SERVER_URL: https://dhl-ops-mcp-server.onrender.com/mcp

Both services are pre-configured in render.yaml for one-click deployment via Render Blueprints.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers