ControlsGuard MCP Server
Provides an adapter that runs the server's workflow node functions on a real LangGraph state graph as an alternative orchestration runtime.
Integrates with OpenAI and any OpenAI-compatible endpoint (configurable via CG_LLM_BASE_URL, including Gemini's) as an alternative LLM provider backing the agent.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@ControlsGuard MCP ServerAre there any control gaps on ledger-core?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
ControlsGuard
A grounded, agentic GenAI assistant that answers questions about company policies, controls, risks and the systems they protect, and finds control-coverage gaps. Built as a portfolio project for a GenAI Developer role in a controls-technology team: it applies hosted foundation models through context engineering, RAG, Graph RAG and tool-using agents, and treats guardrails, evaluation and observability as first-class.
It runs offline with no API keys (a deterministic mock model + local embeddings), and switches to a real model with three environment variables.
Quick start
pip install -r requirements.txt
export PYTHONPATH=src
python -m controlsguard.cli "How quickly must a leaver's access be removed?"
python -m controlsguard.cli "Are there any control gaps on ledger-core?"
python -m unittest discover -s tests -t . # 70 tests
python evals/run_evals.py # quality + safety gates, writes evals/report.md
uvicorn controlsguard.api:create_app --factory --port 8000
python -m controlsguard.mcp_server # MCP server (stdio); add --http for streamable HTTP
docker compose up --buildUse a real model: CG_LLM_PROVIDER=anthropic|openai, CG_LLM_MODEL=<model id>, CG_LLM_API_KEY=...
(CG_LLM_BASE_URL for any OpenAI-compatible endpoint, including Gemini's).
Related MCP server: KaaS MCP Server
How it works
question -> guard_input -> retrieve -> graph_expand -> build_context -> act (LLM <-> tools) -> verify -> respond
| injection? | off-topic? | grounding,
v blocked v abstain / clarify v PII, leak checkStage | What it does |
| Cleans markdown, parses structured fields, structure-aware chunking (one control/risk per chunk, sentence-window split with overlap for long sections, contextual header on every chunk) |
| Hybrid search: BM25 + dense vectors fused with Reciprocal Rank Fusion. Per-retriever ranks are returned for explainability |
| Offline TF-IDF + SVD embedder behind an |
| Knowledge graph (policy -> control -> risk -> system, owners, related controls), every edge carries chunk-level provenance. Traversal, paths, and |
| Context engineering: assembles system instructions, tool specs, memory, graph facts and sources into a token budget with explicit priorities, stable |
| Session/state management with TTL + LRU eviction, token-windowed memory, entity tracking for follow-ups ("what about its related controls?") |
| Function-calling tools with JSON-schema contracts: |
| The orchestrated workflow; tool loop with a hard step cap, argument validation, unknown-tool denial, fail-soft tool errors |
| Input/output/data guardrails (below) |
| MCP server exposing the same tools plus |
| A2A Agent Card + JSON-RPC |
| Provider abstraction: mock, Anthropic (tool use), OpenAI-compatible |
| A tiny LangGraph-shaped state graph, and an adapter that runs the same node functions on real LangGraph |
| JSON audit log, trace spans, Prometheus metrics at |
Guardrails and responsible AI
Prompt injection blocked before any retrieval or model call; indirect injection (instructions hidden inside retrieved documents or tool output) scrubbed line by line
PII redaction (email, PAN, Aadhaar, SSN, Luhn-validated cards, phone) on input, model output, memory and logs; digit patterns are anchored so a long number can't be partially redacted
Grounding check: every substantive sentence needs a valid citation and lexical support in the cited text, or the answer is replaced by a safe fallback instead of being shown
Abstention on off-topic questions and clarification on dangling references
System-prompt leak detection, tool allow-list, schema validation, API-key auth, input size limits
Evaluation (evals/)
47 labelled cases (see evals/report.md after a run) with CI gates: retrieval hit@k/MRR with a BM25 vs vector vs
hybrid ablation, answer correctness + citation correctness, graph and coverage questions, refusals, injection
blocking, PII leakage (including partial leaks), and an indirect-injection test against a deliberately poisoned
document. The run fails the build if any gate regresses, mirroring the corpus's own control C-AI-02 (prompt and
model changes need evaluation evidence).
Honest limitations
The default model is a mock. It writes extractive, cited answers so the full pipeline is testable offline; it is not a language model. Quality numbers describe the retrieval, graph, guardrail and harness layers. To judge answer quality with a real LLM, run the eval against
CG_LLM_PROVIDER=anthropic|openaiand extend the dataset.The corpus is synthetic (6 policies, 19 controls, 8 risks, 6 systems). One gap,
R-VENDORonledger-core, is planted so the coverage check has something real to find.Offline embeddings are lexical-semantic (LSA). With a hosted embedding model, semantic recall (e.g. eval case
ret-19, "root rights" vs "administrator and root credentials") should improve; it is kept in the report as a known miss.Guardrails are transparent heuristics (regex, lexical overlap), a first layer rather than a replacement for model-based classifiers. The vector store is in memory (swap for pgvector/OpenSearch at scale).
langgraph_app.pyand the live Anthropic/OpenAI adapters were not run against the real services here (no network access to package indexes or APIs in the build environment). The adapters are covered by tests with a fake transport. The A2A surface follows the 0.3.0 Agent Card /message/sendshape; verify against a real A2A client.
JD skill map
JD requirement | Where |
Python for GenAI, preprocessing, scripting | whole project; |
LLMs, tokenisation, embeddings, context windows |
|
Prompt engineering (role, few-shot, step-by-step, format) |
|
Context engineering |
|
RAG: chunking, vector search, semantic + keyword |
|
Knowledge graphs / Graph RAG |
|
Agentic workflows, planning, memory, tool calling |
|
MCP |
|
A2A |
|
Agent harness: sessions, state, memory, guardrails |
|
Consuming GenAI APIs (OpenAI / Gemini / Claude) |
|
Docker, Git, CI |
|
Deployment, monitoring, maintenance |
|
Compliance, privacy, responsible AI |
|
Code review, testing, documentation | 70 tests, eval gates, this README |
Cloud (AWS/GCP/Azure), LangChain/LlamaIndex, CrewAI/ADK | not covered: deploy the container to any of them; frameworks are deliberately avoided to show the underlying mechanics |
This server cannot be deployed
Related MCP Connectors
Persistent memory, hybrid search and a goal graph for AI agents, over stdio or remote HTTP.
Exposes FEDLIN's public security scanners as agent-callable tools over Streamable HTTP.
Agent-native MCP server over the public saagarpatel.dev corpus. Read-only, stateless.
Serve a folder of Markdown notes as an MCP server: hybrid search, reading, and sourced answers.
Related MCP Servers
- AlicenseNot gradedqualityAmaintenanceExposes a deterministic, centrality-aware GraphRAG retrieval planner as operator tools over stdio or SSE, letting agents index corpora, run seed-steerable multi-hop retrievals, resolve entities, inspect graph neighborhoods, and fetch documents. All responses come back in milliseconds with zero LLM calls in the query path, so the calling agent does the reasoning while the server handles hop-by-hop retrieval.2MIT
- FlicenseNot gradedqualityAmaintenanceExposes a compiled Markdown knowledge base to any MCP-capable coding agent through a single ask tool, returning cited answers grounded in full wiki articles over stdio or streamable HTTP.-
- FlicenseNot gradedqualityAmaintenanceExposes a compiled Markdown knowledge base to MCP-capable coding agents through a single ask tool that returns cited, Markdown-formatted answers grounded in whole wiki articles rather than embedded fragments. Runs locally over stdio or remotely over streamable HTTP with optional bearer-token authentication.-
- FlicenseNot gradedqualityAmaintenanceExposes a compiled Markdown knowledge base to MCP-capable coding agents through a single ask tool that returns cited answers grounded in whole wiki articles rather than embedded fragments. Supports local stdio and remote streamable-HTTP transports, with optional bearer-token authentication on the network transport.-