A compact reference implementation for governed agentic runtime + gateway workflows.
Covers Assignments 1, 2, and 3 of the AgentCore contractor evaluation.
| Assignment | What is demonstrated |
|---|---|
| 1 — PR Review workflow | LangGraph graph, two MCP tools (get_pr_diff, post_review_comment), guardrails, HITL, explainable output |
| 2 — Tool failure recovery + HITL | file_db_recovery_graph: FileNotFound → reflect → fallback → HITL before update_db_record |
| 3 — Customer support agent design | docs/design/customer-support-agent.md |
run_pr_review.py run_file_db.py
│ │
▼ ▼
agentcore_runtime/graphs/
pr_review_graph.py file_db_recovery_graph.py
│ │
│ audit / guardrails / hitl / llm
│ │
▼ ▼
agentcore_runtime/
mcp_client.py ← call_tool() — MCP protocol over stdio
│
▼
agentcore_gateway/
mcp_server.py (FastMCP stdio — primary, MCP protocol)
server.py (FastAPI REST — alternative, HTTP)
│
tools/
pr_tools.py ← get_pr_diff, post_review_comment
file_tools.py ← read_file, search_file, delete_file
db_tools.py ← query_db, update_db_record
# Clone and enter the repo
git clone <repo-url>
cd agentcore-pr-agent
# Create and activate virtual environment
python -m venv .venv
.venv\Scripts\activate # Windows
# source .venv/bin/activate # macOS/Linux
# Install dependencies
pip install -r requirements.txt
# Copy environment file (ANTHROPIC_API_KEY is optional)
cp .env.example .envThe gateway exposes all 7 tools via the Model Context Protocol over stdio — compatible with Claude Desktop and any MCP client.
python -m agentcore_gateway.mcp_serverRegistered tools:
get_pr_diff read Fetch PR diff
post_review_comment write Post review comment on PR
read_file read Read file by path
search_file read Search for file by query
delete_file destructive Delete a file (HITL gate in agent workflows)
query_db read Query database record
update_db_record destructive Update a database record (HITL gate in agent workflows)
Claude Desktop config (~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"agentcore-gateway": {
"command": "python",
"args": ["-m", "agentcore_gateway.mcp_server"],
"cwd": "/path/to/agentcore-pr-agent"
}
}
}A FastAPI REST gateway is also available for direct HTTP access:
uvicorn agentcore_gateway.server:app --port 8000 --reloadAvailable endpoints:
GET /health
GET /tools
POST /tools/get_pr_diff
POST /tools/post_review_comment
POST /tools/read_file
POST /tools/search_file
POST /tools/delete_file
POST /tools/query_db
POST /tools/update_db_record
python run_pr_review.pyLoads examples/pr_input.json, runs the full LangGraph PR review workflow, prints output to console, and writes audit events to logs/audit_log.jsonl.
HITL fires automatically for the security-critical finding in the mock diff. The runner auto-approves for non-interactive execution. To approve manually, remove the approval_fn override in run_pr_review.py.
python run_file_db.pyLoads examples/file_db_input.json, attempts to read /missing/config.yaml, receives FileNotFound, reflects, searches for a fallback path, retries, queries the DB, and requires HITL approval before update_db_record.
| File | Description |
|---|---|
examples/pr_input.json |
PR review workflow input |
examples/pr_output.json |
PR review workflow output (actual graph run) |
examples/file_db_input.json |
File/DB recovery workflow input |
examples/file_db_output.json |
File/DB recovery workflow output (actual graph run) |
pytest tests/ -vTests cover guardrails, HITL approval logic, reflection/retry routing, and MCP server tool registration and execution. HITL tests use injected lambdas — no input() hang.
See docs/design/architecture-decisions.md for the full list. Key choices:
- LangGraph — used because Assignment 2 explicitly references it;
conditional_edgesexpress failure routing and HITL branching clearly - Mock tools — no external API keys or services required; wiring to live systems is a config change, not an architecture change
- Deterministic workflows — run without
ANTHROPIC_API_KEY; set the key to enable real LLM calls viaagentcore_runtime/llm.py - Injectable HITL —
request_approval(reason, approval_fn=input)keeps tests non-blocking - JSONL audit log — every tool call, HITL decision, and workflow completion is written to
logs/audit_log.jsonl
Mock tools over live integrations. get_pr_diff, read_file, query_db, and the rest are deterministic mocks with no external API calls. Wiring to real GitHub, a filesystem, or a database is a configuration change, not an architecture change. The assessment prohibits paid external dependencies and hardcoded secrets — mocks satisfy both constraints while keeping the repo fully runnable.
Deterministic workflows over mandatory LLM calls. Workflows produce consistent, reviewable output without ANTHROPIC_API_KEY. The LLM wrapper (llm.py) returns a fixed response when the key is absent and makes a real Anthropic API call when configured. An evaluator can run the full workflow without any credentials.
Compact LangGraph workflows over a generalized orchestration framework. Each graph is a single-file, purpose-built StateGraph. No shared base classes, no plugin architecture, no dynamic tool registration. The structure is readable, the state transitions are explicit, and the scope is bounded to what the assessment asks for.
CLI input() as the HITL path. In production, HITL would be an async approval queue with a UI. For this assessment, request_approval() takes an injectable approval_fn — tests pass lambda _: "y" and never hang; runners auto-approve with the same pattern. The production extension point is obvious and documented.
Local JSONL audit log over an observability stack. Every tool call, HITL decision, and workflow completion is written to logs/audit_log.jsonl. No external logging service, no database, no distributed tracing. The pattern is demonstrable and grep-able; scaling it is an infrastructure decision outside assessment scope.
No real PHI, no hardcoded secrets. PHI patterns in tests are synthetic (fake SSNs, DOB strings). The mock PR diff contains API_KEY=abc123 intentionally — it is the trigger for the secret-detection guardrail and HITL path, not a real credential.
MCP server alongside the REST gateway. Both transports are present and share the same underlying tool functions. The MCP server (agentcore_gateway/mcp_server.py) uses FastMCP with stdio transport — the standard MCP protocol compatible with Claude Desktop and any MCP client. The REST gateway (agentcore_gateway/server.py) provides direct HTTP access for testing and inspection. The two share zero business logic — all tool implementations live in agentcore_gateway/tools/ and are imported by both.
AI coding assistant used for acceleration. The assessment explicitly permits this. Architecture decisions, scope boundaries, and design tradeoffs are the author's own.
- Authentication on gateway endpoints
- Docker or cloud deployment
- Real GitHub API, database, or filesystem integration
- Multi-tenancy or session management
- Distributed tracing or external logging systems
- LangGraph checkpointing or persistence
See docs/design/customer-support-agent.md.
Copyright (c) 2026 Prasad Tiruveedi.
This repository was created as part of a technical assessment submission and is intended solely for evaluation purposes.
No production usage rights are granted without explicit permission from the author.