Skip to content

Architecture

Emmanuel Knafo edited this page Sep 14, 2026 · 1 revision

title: Architecture description: LangGraph agent topology, the Foundry services defined in azure.yaml, and the MCP tool servers.

Overview

The agent is a LangGraph supervisor and specialist multi-agent graph, packaged as a Microsoft Foundry hosted agent and wired to two read-only MCP tool servers. Today the graph only runs locally, in-process, through src/quote-preparation-agent/main.py; no Foundry Responses-protocol host server exists yet (see Home's gating callout).

flowchart LR
    subgraph Foundry["Microsoft Foundry project (author-only, not deployed)"]
        Agent["quote-preparation-agent\n(hosted, LangGraph)"]
        Model["gpt-4o-mini deployment\n(GlobalStandard)"]
        Toolbox["quote-tools toolbox"]
    end

    subgraph ContainerApps["Azure Container Apps (author-only, not deployed)"]
        Application["application-server"]
        Rulebook["rulebook-server"]
    end

    Agent -->|chat completions| Model
    Agent -->|MCP tool calls| Toolbox
    Toolbox -->|application-conn| Application
    Toolbox -->|rulebook-conn| Rulebook
Loading

LangGraph topology

src/quote-preparation-agent/graph.py defines a supervisor that routes to three specialist nodes in a fixed order:

flowchart TD
    START([START]) --> Supervisor{{supervisor}}
    Supervisor -->|not yet complete| Intake[intake]
    Supervisor -->|valid case, lookup pending| ReferenceLookup[reference_lookup]
    Supervisor -->|composition pending| Composition[composition]
    Intake -->|returns control| Supervisor
    ReferenceLookup -->|returns control| Supervisor
    Composition --> END([END])
Loading
  • intake validates the applicant-supplied case reference against the CASE-SYN-### pattern and never calls an MCP tool.
  • reference_lookup fetches the synthetic application record and the pinned rulebook through the Phase 4 MCP tool wrappers in toolbox.py. An invalid case reference from intake skips this node entirely and routes straight to composition, so composition can still produce a bounded rejection message.
  • composition has no tool access. It assembles a bounded, bilingual applicant-facing message from a fixed status template and the rulebook's own synthetic notice; it never includes an amount or a reviewer-only field.

The graph is always compiled without a checkpointer: this local/unhosted phase has no Foundry Responses protocol and no hosted session to persist across.

toolbox.py calls the MCP servers' tool functions in-process (loading each server's main.py under a private module name) rather than opening a streamable_http_client/ ClientSession against a running server, since the servers here are local, unauthenticated, and read-only. Swapping in a real MCP client session is a drop-in replacement once a hosted deployment is authorized. toolbox.py also wraps the pure deterministic calculator (calculate_quote) and only the read/create-draft surface of the approval repository; approve, reject, and revise are intentionally never imported here, since those transitions may only be performed by a human reviewer.

azd services (azure.yaml)

Service Host Purpose
ai-project azure.ai.project Declares the gpt-4o-mini (GlobalStandard, capacity 10) model deployment
application-conn azure.ai.connection Remote-tool connection pointing at application-server
rulebook-conn azure.ai.connection Remote-tool connection pointing at rulebook-server
quote-tools azure.ai.toolbox Bundles both MCP connections into one toolbox the agent can bind
quote-preparation-agent azure.ai.agent (hosted) The LangGraph agent itself, Python 3.13, built remotely (dependencyResolution: remote_build)

quote-preparation-agent declares kind: hosted and the responses protocol (version 2.0.0), matching a real Foundry hosted-agent service definition. This is a declared service type, not confirmation that it is deployed or running; see the top-of-file banner in azure.yaml and Home's gating callout.

MCP tool servers

mcp/application-server and mcp/rulebook-server are minimal FastMCP servers that run fully independently of each other and of the LangGraph agent process, with no shared runtime or import. Both expose read-only, synthetic-data tools with no write, SQL, URL, or path-based tool surface:

  • application-server exposes get_application(fixture_id) against the fixtures in data/synthetic/fixtures/.
  • rulebook-server exposes get_rulebook(rulebook_id) against the pinned RULEBOOK-SYN-ON rulebook in data/synthetic/rulebook.json.

Each server has its own Dockerfile; infra/modules/mcp-container-apps.bicep provisions them as separate Azure Container Apps under the ${namePrefix}-mcp-env managed environment, but that template is author-only and has not been applied (see Operations).

Web chat pilot (code only, not deployed)

apps/web-chat is a standalone React/FastAPI chat frontend adapted from the sibling repository's pilot, intended to invoke quote-preparation-agent through a dedicated managed identity once the agent itself is deployable. infra/web-chat.bicep templates a Container App for it, deliberately outside azure.yaml and infra/main.bicep, deployed out-of-band by a human operator via az deployment group create. Neither the app nor the template has been deployed to Azure; there is no live URL to link here.

Environments and CI/CD

See Operations for the release path, identity prerequisites, and how to inspect a release, and Workflows for the full workflow table and gating status.