Skip to main content
Glama
vvXranjan

cfr-compliance-mcp

by vvXranjan

CFR Compliance MCP

An agentic compliance analysis system that evaluates contract clauses against authoritative U.S. federal regulations using MCP-based retrieval, deterministic rules, LLM reasoning, evidence verification, durable memory, human review workflows, and production-ready persistence.


Why This Project

LLMs are powerful, but they should not be allowed to freely invent regulatory evidence or autonomously execute high-stakes decisions.

This system demonstrates a controlled AI architecture where:

  • authoritative regulatory retrieval comes first — current CFR text is the only source of regulatory truth

  • deterministic checks constrain the workflow — LLM-free rules provide fast, auditable verdicts before any model is consulted

  • LLM reasoning is evidence-grounded — the model must cite only the provided regulation, and provenance is attached by the retrieval layer, never the model

  • verification gates uncertain outputs — conflicts and ungrounded results resolve to NEEDS_REVIEW, never silent acceptance

  • historical memory is advisory — prior outcomes are context, not law, and can never override the current regulation

  • humans control unresolved decisions — an explicit review lifecycle preserves the original automated result and an immutable audit trail

  • persistence and audit trails make every decision inspectable — via filesystem or optional PostgreSQL, with a review dashboard

Related MCP server: Legal Info MCP Server

Key Capabilities

  • MCP-based retrieval of the official eCFR API (8 typed tools)

  • Configurable LLM evaluation via an OpenAI-compatible endpoint

  • Deterministic compliance rules (LLM-free, auditable)

  • Evidence grounding + independent verification

  • Prompt-injection defenses and security boundaries

  • Advisory compliance memory with durable JSONL storage

  • Immutable analysis snapshots

  • Optional PostgreSQL backend with versioned SQL migrations

  • Queryable analysis history

  • Human-in-the-loop review with optimistic concurrency

  • Immutable audit events

  • Server-rendered Jinja2 dashboard

  • Docker + Docker Compose deployment

  • Liveness and readiness endpoints

  • Comprehensive offline + PostgreSQL integration + live LLM test suites

Architecture

flowchart TD
    C[Contract / Clause] --> S[Security Boundary]
    S --> R[Authoritative eCFR Retrieval]
    R --> M[Memory Lookup<br/>Advisory only]
    M --> D[Deterministic Evaluation]
    D --> L[LLM Evaluation]
    L --> V[Verification]
    V -->|uncertain| NR[NEEDS_REVIEW]
    V -->|verified| OK[VERIFIED]
    NR --> HR[Human Review]
    OK --> P[Persistence]
    HR --> P
    P -->|File| F[FileRepository - JSON reports]
    P -->|Optional PostgreSQL| PG[PostgresRepository - history + review]

Compliance Memory is drawn below retrieval on purpose: it is advisory context that can influence an evaluation, but it is never authoritative regulatory evidence and can never reorder the hierarchy.

Core Engineering Decisions

Authoritative Retrieval Before Reasoning

The pipeline runs security → retrieval → deterministic rules → LLM → verification. Regulatory text is always fetched and made usable before any reasoning begins. If retrieval fails, the clause resolves to NEEDS_REVIEW — the system will not guess.

LLMs Do Not Control Evidence Provenance

The model is instructed to reference only the provided regulation text, and evidence provenance (source, retrieved_at, retrieval_method, version) is attached by the retrieval layer. The model never manufactures where evidence came from; ungrounded output is routed to review.

Compliance Memory Is Advisory

Verified historical outcomes are stored in an append-only JSONL store and can be surfaced as labeled HISTORICAL_CONTEXT (data, never instructions). Memory:

  • never establishes or replaces a CFR requirement

  • is injected only into the user prompt, never the system instructions

  • cannot trigger a verdict reuse unless current authoritative retrieval is usable

  • is not auto-indexed when it participated (prevents feedback loops)

Human Review Does Not Overwrite Automated Results

A reviewer decision transitions an explicit lifecycle and appends an immutable event; it never rewrites the original ComplianceResult, evidence, or audit trail.

PostgreSQL Is Optional

file is the default and fully self-contained. PostgreSQL is an explicit opt-in that adds queryable history and the review workflow. There is no silent fallback — misconfiguration fails clearly.

Fail-Open vs Fail-Fast Boundaries

  • Evaluation path: optional persistence/memory failures are logged and never fail a successful compliance analysis (fail-open).

  • Configuration path: an invalid backend or unreachable configured database fails fast rather than silently degrading (fail-fast).

Human-in-the-Loop Review

NEEDS_REVIEW
    ↓
UNDER_REVIEW
    ↓
APPROVED / REJECTED / ESCALATED
  • Optimistic concurrency — a decision carries an expected_version; a stale write is rejected instead of overwriting another reviewer.

  • Immutable decision events — every transition is appended to an audit log.

  • Original results preserved — the automated result, evidence, and audit are never modified by review.

Dashboard

A server-rendered Jinja2 dashboard is served by the API at /dashboard:

  • Overview — aggregate compliance metrics and recent analyses

  • Analysis history — paginated, filterable list with click-through

  • Analysis detail — clause results, authoritative CFR evidence, verification, audit, and memory-participation indicator

  • Review queue — actionable NEEDS_REVIEW items with state filters

  • Review detail — automated result, evidence, verification/audit, memory context, immutable decision history, and a decision form (valid transitions only)

Authoritative CFR evidence and advisory historical memory are visually distinct — memory is never presented as regulation. No screenshots are bundled; run the app and visit /dashboard.

Quick Start

Prerequisites: Python 3.12+, uv, and a working eCFR connection. An LLM key is only needed for the LLM-fallback evaluation step.

File persistence (default)

cp .env.example .env       # fill in credentials if desired
uv sync --extra dev
uv run uvicorn api:app --host 0.0.0.0 --port 8000
open http://localhost:8000/dashboard

Enable on-disk report persistence by setting CFR_REPORTS_DIR=reports in .env.

PostgreSQL (opt-in)

# 1. Configure the backend + DSN
CFR_PERSISTENCE_BACKEND=postgres
CFR_DATABASE_URL=postgresql://user:pass@host/db

# 2. Apply the versioned schema (idempotent, safe to re-run)
uv run python scripts/migrate.py --dsn "$CFR_DATABASE_URL"

# 3. Start the API (fails fast at startup if the DB is unreachable)
uv run uvicorn api:app --host 0.0.0.0 --port 8000

Docker Compose (reproducible local stack)

docker compose up -d --build
open http://localhost:8000/dashboard

The Compose stack runs the app + PostgreSQL 16 with a named volume, a one-shot migration service, and health checks. The app waits for migrations to complete.

Environment Variables

Variable

Requirement

Purpose

ATM_API_KEY

Optional (LLM)

Preferred credential for the LLM evaluation step

ATM_BASE_URL

Optional

LLM endpoint (default https://atm.accure.ai/v1)

ATM_MODEL

Optional

LLM model (default Nemotron)

OPENAI_API_KEY

Optional

Fallback OpenAI-compatible credential

ECFR_BASE_URL

Optional

eCFR API base URL

CFR_REPORTS_DIR

Optional (file backend)

Enable report persistence

CFR_PERSISTENCE_BACKEND

Backend-specific

file (default) or postgres

CFR_DATABASE_URL

Backend-specific

PostgreSQL connection string

CFR_MEMORY_ENABLED

Optional

Enable advisory Compliance Memory

CFR_MEMORY_DIR

Optional

Memory store directory

CORS_ORIGINS

Optional

Allowed CORS origins

JAEGER_AGENT_HOST/PORT

Optional

Best-effort tracing export

Never commit a real .env; it is git-ignored and excluded from Docker builds.

API Endpoints

Endpoint

Method

Description

/health

GET

Liveness check

/health/ready

GET

Readiness (reflects backend usability)

/evaluate-clause

POST

Evaluate a single clause

/evaluate-bulk

POST

Evaluate a batch (max 200), optionally persist

/analyses

GET

Paginated analysis history

/analyses/{analysis_id}

GET

Full immutable report

/reviews

GET

Review queue (defaults to actionable)

/reviews/{analysis_id}/{clause_id}

GET

Full review view

/reviews/{analysis_id}/{clause_id}/decide

POST

Record a review decision

/dashboard

GET

Server-rendered review dashboard

/api/docs

GET

Interactive OpenAPI docs

Testing

# Offline suite (no external services required)
uv run pytest --deselect tests/test_live_llm_integration.py -q

# Optional PostgreSQL integration tests (clean-skip without a test DB)
CFR_TEST_DATABASE_URL=postgresql://user:pass@host/db uv run pytest tests/test_postgres_integration.py

# Live LLM tests (require an LLM key + network)
uv run pytest tests/test_live_llm_integration.py

# Lint
uv run ruff check .

Current validation: 268 offline tests, 9 PostgreSQL integration tests (clean-skip when unavailable), and 9 live LLM tests.

Project Structure

agent/
  compliance_pipeline.py   # orchestration + authority order
  compliance_agent.py      # LLM evaluation
  security.py              # prompt-injection + input defenses
  deterministic_rules.py   # LLM-free rules
  verification_agent.py    # evidence/consistency verification
  memory.py / memory_store.py  # advisory compliance memory
  reporting.py             # report persistence
  persistence/             # File / Postgres / in-memory repositories + review lifecycle
api.py                     # FastAPI service
dashboard.py               # server-rendered dashboard routes
templates/ static/         # dashboard UI
migrations/ scripts/       # SQL migrations + migration runner
src/cfr_compliance_mcp/    # FastMCP server + eCFR client + tools
tests/                     # offline, integration, live suites
benchmark/                 # deterministic benchmark harness
compose.yaml  Dockerfile  pyproject.toml  uv.lock

Tech Stack

AI / LLM — FastMCP, eCFR retrieval, deterministic rules, configurable OpenAI-compatible LLM, verification, advisory memory

Backend — Python 3.12+, FastAPI, Pydantic v2, httpx, structured logging

Persistence — filesystem JSON reports (default) + optional PostgreSQL (psycopg 3, versioned SQL migrations)

Infrastructure — Docker, Docker Compose, health/readiness endpoints

Testing — pytest, offline + optional PostgreSQL integration + live LLM

What This Project Demonstrates

  • Agentic AI system design — a full retrieval → reason → verify → decide pipeline with explicit boundaries

  • MCP tool integration — a typed server wrapping a real regulatory API

  • LLM orchestration — deterministic + probabilistic control flow

  • Retrieval and evidence grounding — provenance-first design

  • AI security boundaries — prompt-injection defense and input sanitization

  • Human-in-the-loop workflows — explicit review lifecycle with audit

  • Transactional persistence — optimistic concurrency and immutable events

  • API engineering — validated request/response models, structured errors

  • Dockerized deployment — reproducible builds and a Compose stack

  • Testing and integration validation — offline, PostgreSQL, and live suites

Current Limitations

  • reviewer_identity is an unauthenticated placeholder (no auth system yet)

  • PostgreSQL is single-instance (no distributed orchestration)

  • Live LLM tests depend on external provider availability

  • Compliance Memory is intentionally local and advisory

  • The system does not automatically execute remediation

Roadmap

  • Authenticated reviewer identities and role-based access control

  • Production observability and richer audit reporting

  • Background job processing for long-running evaluations

  • A broader, versioned compliance benchmark suite

  • Multi-node deployment support


AI-assisted compliance analysis is not a substitute for legal or regulatory professionals. Non-trivial findings are routed to human review; nothing in this system autonomously issues legal authorization.

Available Tools

8 tools
get_title_structureA

Fetch the hierarchical structure of a CFR title (no regulation text) — useful for planning which part/section to retrieve next.

ParametersJSON Schema
NameRequiredDescriptionDefault
dateNooptional as-of date (YYYY-MM-DD). Defaults to the latest available date for this title if omitted.
titleYesCFR title number (1-50).

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full transparency burden. It discloses the most important behavioral characteristic — it returns only hierarchical structure, not regulation text — which prevents an agent from using this as a text-retrieval tool. 'Fetch' also implies a read operation with no mutation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One sentence that front-loads the action/resource, includes the critical exclusion (no regulation text), and ends with the practical use case. There is no filler or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description is sufficient for a simple fetch tool: it states what is returned, what is not returned, and why an agent would call it, while the supplied output schema covers return structure. The optional date parameter is already documented in the schema, so no additional detail is needed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with both 'title' and 'date' fully described, so the description need not repeat parameter details. The tool description adds no parameter-level semantics beyond the schema, matching the baseline for full schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb ('Fetch') and resource ('hierarchical structure of a CFR title'), and explicitly excludes regulation text, which distinguishes it from sibling retrieval tools like retrieve_title or retrieve_part. The stated purpose ('planning which part/section to retrieve next') further clarifies its role.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clearly signals when to use this tool: as a planning/navigation step before retrieving a specific part or section. It does not explicitly name alternatives or give when-not-to-use conditions, but the 'no regulation text' caveat and sibling list make the intended context evident.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_version_historyA

Fetch point-in-time version history for a CFR title, optionally scoped to a part/section and/or filtered by an issue-date range.

Use this to determine which version of a regulation was in effect on a specific date (e.g. when a contract was signed), as opposed to retrieve_section/retrieve_part/retrieve_title, which return the text as of a date but not its full change history.

ParametersJSON Schema
NameRequiredDescriptionDefault
partNooptional CFR part number to scope the history to.
titleYesCFR title number (1-50).
sectionNooptional CFR section number to scope the history to.
issue_date_onNooptional exact issue date filter (YYYY-MM-DD).
issue_date_gteNooptional "on or after" issue date filter (YYYY-MM-DD).
issue_date_lteNooptional "on or before" issue date filter (YYYY-MM-DD).

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does well: 'Fetch' indicates a read operation, and the contrast with retrieve_section/part/title clarifies that this tool returns history rather than point-in-time text. It doesn't mention pagination or result limits, but the presence of an output schema partially mitigates that.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and well-structured: the core purpose is front-loaded, followed by a concrete use case and clear differentiation from siblings. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 6-parameter read tool with an output schema, the description covers purpose, scoping/filtering options, the primary use case, and how it differs from sibling tools. Nothing essential is missing for correct selection and invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description mostly paraphrases the scoping/filtering behavior already present in the schema and adds little new parameter-level semantic detail.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb and resource: 'Fetch point-in-time version history for a CFR title.' It clearly distinguishes this tool from sibling text-retrieval tools by stating it returns full change history, not just the text as of a date.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly states when to use the tool: to determine which version of a regulation was in effect on a specific date. It also names the relevant alternatives and explains why they are not appropriate for change-history needs.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_agenciesA

List all agencies referenced in the CFR, with their title/chapter cross-references.

Useful for mapping a contract clause's implied regulator (e.g. "environmental", "labor", "acquisition") to the correct CFR title before running search_regulations or search_by_keyword.

Returns: On success: {"agencies": [...as returned by eCFR, including nested child agencies...]}. On failure: {"error": true, "error_type": ..., "message": ..., "retryable": ...}.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It discloses both success and error return shapes, including a retryable flag and nested child agencies. It doesn't mention performance or pagination, but for a zero-parameter listing operation this is a minor omission rather than a critical gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The main purpose is front-loaded in the first sentence, followed by a compact usage scenario and a clear return format section. Every sentence earns its place; there is no filler or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a no-parameter list tool, the description is complete: it explains the resource, the purpose, the relationship to sibling tools, and the expected success and failure payloads. Nothing an agent needs to use it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so there are no parameter semantics to add. The description doesn't need to compensate for schema gaps, and the baseline 4 is appropriate since the dimension is trivially satisfied.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a clear verb-object pair: 'List all agencies referenced in the CFR' with their title/chapter cross-references. It also differentiates itself from search siblings by framing itself as a mapping step before search_regulations/search_by_keyword.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly says when to use the tool: to map an implied regulator to a CFR title before running search_regulations or search_by_keyword. This provides actionable context and names the relevant alternatives, even if it doesn't enumerate all non-use cases.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

retrieve_partA

Retrieve the text of an entire CFR part (a cluster of related sections).

Prefer retrieve_section when the clause maps to one exact section — a part's response can be large.

ParametersJSON Schema
NameRequiredDescriptionDefault
dateNooptional as-of date (YYYY-MM-DD). Defaults to the latest available date for this title if omitted.
partYesCFR part number, e.g. "261".
titleYesCFR title number (1-50).

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the responsibility for behavioral disclosure. It adds one useful warning—that a part's response can be large—but does not mention other operational traits such as pagination, error behavior, or performance implications.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with the core purpose front-loaded and the cautionary sibling guidance in the second sentence. There is no filler, redundancy, or unnecessary detail.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given full schema parameter coverage and an output schema, the description is complete enough for correct tool selection and invocation. It conveys what the tool retrieves, warns about large responses, and directs the agent to the right alternative.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and each parameter is already described with type, default, and example. The description adds contextual color by calling a part a cluster of sections, but it does not add new parameter-level semantics beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names the specific operation ('Retrieve the text'), the resource ('entire CFR part'), and defines a part as a cluster of related sections. It also distinguishes itself from retrieve_section by calling out the exact-section scenario.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly instructs the agent to prefer retrieve_section when the clause maps to one exact section, giving a clear routing rule. This is sufficient to choose between the closely related siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

retrieve_sectionA

Retrieve the exact legal text of one CFR section (e.g. 40 CFR 261.10).

ParametersJSON Schema
NameRequiredDescriptionDefault
dateNooptional as-of date (YYYY-MM-DD). Defaults to the latest available date for this title if omitted.
partYesCFR part number, e.g. "261".
titleYesCFR title number (1-50).
sectionYesCFR section number, e.g. "10".

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the behavioral burden. 'Retrieve' clearly indicates a non-mutating read operation, and 'exact legal text' tells the agent the output is verbatim statutory language rather than a summary. It does not cover auth requirements, rate limits, or error behavior, but for a simple read tool with an output schema these are secondary.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, front-loaded sentence that immediately states the action and object, then offers an illustrative example. There is no fluff, no repetition of schema descriptions, and every word contributes.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a low-complexity retrieval tool, the one-sentence description plus a fully documented input schema and an output schema is complete. The agent knows exactly what the tool returns (exact legal text of one section), what parameters to provide (covered in schema), and what format to expect (covered by output schema). No critical selection or invocation information is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already fully documents all four parameters (100% coverage), so the baseline is 3. The description adds a concrete example, '40 CFR 261.10', which illustrates how the required title, part, and section parameters map to a standard citation and reinforces the expected string formats for part and section.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states the specific verb 'Retrieve' and the exact resource: 'the exact legal text of one CFR section', with a concrete example citation. The phrase 'one section' clearly distinguishes it from siblings like retrieve_part and retrieve_title, which operate on larger units, and from search_by_keyword, which searches rather than retrieves exact text.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies when to use the tool—whenever a single CFR section's text is needed—but it never explicitly contrasts it with alternatives such as retrieve_part, retrieve_title, or search_regulations. The sibling list hints at the family of tools, yet no when-to-use / when-not-to-use guidance is provided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

retrieve_titleA

Retrieve the text of an entire CFR title.

WARNING: some titles (notably Title 40 / EPA) are large enough that this can be slow or time out upstream. Strongly prefer retrieve_part or retrieve_section when you know which part or section is relevant — use this only for small titles or genuinely title-wide questions.

ParametersJSON Schema
NameRequiredDescriptionDefault
dateNooptional as-of date (YYYY-MM-DD). Defaults to the latest available date for this title if omitted.
titleYesCFR title number (1-50).

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

There are no annotations, so the description carries the full behavioral burden. It discloses a key behavioral trait: certain large titles may be slow or time out. It also implies a read-only operation by saying 'Retrieve the text.' It doesn't cover every possible edge case, but it adds meaningful behavioral context beyond the basic operation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact: one clear purpose sentence followed by a concise, high-signal warning. Every sentence earns its place, the warning is scannable with 'WARNING:' and the guidance is front-loaded without unnecessary detail.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given that the tool has only two parameters, a rich input schema, and an output schema, the description fully covers what an agent needs: purpose, scope, performance caveats, and sibling alternatives. Nothing critical is missing for correct selection and invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the schema already documents title as 'CFR title number (1-50)' and date with a full default/format description. The tool description does not need to repeat parameter details and does not add meaningful parameter-level semantics, so the baseline score of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a clear verb and resource: 'Retrieve the text of an entire CFR title.' The word 'entire' disambiguates it from retrieve_part and retrieve_section, so an agent can immediately recognize the tool's scope and distinguish it from sibling tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The warning explicitly states when not to use this tool and names alternatives: 'Strongly prefer retrieve_part or retrieve_section when you know which part or section is relevant — use this only for small titles or genuinely title-wide questions.' This gives the agent actionable selection criteria rather than leaving it to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_by_keywordA

Search the CFR using a list of distinct keywords/terms rather than a single free-text phrase.

Keywords are joined into one query string before searching — for precise multi-word phrase search, use search_regulations instead.

ParametersJSON Schema
NameRequiredDescriptionDefault
dateNo"current" (default) for in-force text only, an explicit YYYY-MM-DD date, or None for all historical matches.current
pageNopage number (>= 1, default 1).
keywordsYeslist of search terms, e.g. ["hazardous", "ignitability"].
per_pageNoresults per page (1-100, default 20).
agency_slugsNooptional list of agency slugs to restrict the search to.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden, and it does disclose an important behavioral trait: 'Keywords are joined into one query string before searching'. This explains how multiple terms are combined and clarifies the search semantics. It could additionally state that the operation is read-only, but 'search' strongly implies a non-destructive read action.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no filler. The core purpose and distinguishing behavior are front-loaded, and the alternative tool reference is included in the second sentence. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has an output schema, fully documented parameters, and a clear sibling pointer. Given the moderate complexity, the description is sufficient for an agent to select and invoke the tool correctly. It covers what the tool does, how keywords are handled, and which sibling to use for phrase searches.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already documents all five parameters comprehensively, so the baseline is 3. The description adds value by explaining that keywords are treated as 'distinct keywords/terms' and are 'joined into one query string', which clarifies the intended interpretation of the `keywords` parameter beyond the schema's generic 'list of search terms'.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Search the CFR using a list of distinct keywords/terms'. It clearly distinguishes this tool from search_regulations by stating the input mode is a list of distinct keywords rather than a single free-text phrase, so an agent can immediately tell the tools apart.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit selection guidance: use this tool for a list of distinct keywords/terms, and explicitly directs users to `search_regulations` for precise multi-word phrase search. This tells the agent not only when to use this tool, but also when to choose an alternative.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_regulationsB

Full-text search across the CFR for a free-text query or phrase.

ParametersJSON Schema
NameRequiredDescriptionDefault
dateNothe sentinel "current" (default) for only in-force text (excludes superseded historical matches), an explicit YYYY-MM-DD date to scope results to content in force on that date, or None for no date restriction at all — matches from every historical version of the CFR are included, which may return duplicate or superseded text alongside current text. Callers that specifically want historical, including superseded, matches should pass date=None explicitly rather than relying on the default.current
pageNopage number (>= 1, default 1).
queryYesfree-text search query, e.g. "hazardous waste characteristics".
per_pageNoresults per page (1-100, default 20).
agency_slugsNooptional list of agency slugs to restrict the search to.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.2/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden of behavioral disclosure. It only states that this is a full-text search; it does not mention important behaviors such as date scoping, pagination, agency filtering, or the fact that date=None may return duplicates and superseded text. No contradictions exist, but transparency is minimal.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence with no filler. It communicates the essential operation immediately and every word earns its place, making it a model of concise structure.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the rich input schema (100% parameter coverage) and the presence of an output schema, the description does not need to explain return values or parameter details. The main gap is that it does not position this tool relative to search_by_keyword, but invocation-critical details are available in the structured data.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description itself adds no parameter-specific meaning beyond the schema, which already thoroughly documents query, date, page, per_page, and agency_slugs, including the nuanced date sentinel behavior.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('search'), a clear resource ('the CFR'), and a specific input type ('free-text query or phrase'), making the tool's core function immediately understandable. However, it does not distinguish itself from the sibling tool search_by_keyword, so it stops short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives no guidance on when to use this tool versus alternatives such as search_by_keyword or the various retrieval tools. There is no mention of scenarios that favor this tool or exclusions, so an agent must infer usage from the name and schema alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. 8 tool updatesv0.1.0
    • First observedget_title_structure
    • First observedget_version_history
    • First observedlist_agencies
    • First observedretrieve_part
    • First observedretrieve_section
    • First observedretrieve_title
    • First observedsearch_by_keyword
    • First observedsearch_regulations

TDQS

A4.1/5.0
Disambiguation4/5

Most tools are clearly separated by operation type and granularity: retrieve_section/part/title, get_title_structure vs get_version_history, and list_agencies are all distinct. The main area of potential confusion is search_regulations vs search_by_keyword, though the descriptions do explain the free-text vs keyword-list difference.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern: search_*, retrieve_*, get_*, and list_*. The use of retrieve for legal text and get for metadata/history is a predictable and readable convention.

Tool Count5/5

Eight tools is well-scoped for a CFR research server. The set covers search, retrieval at three granularity levels, structural navigation, version history, and agency lookup without redundancy or bloat.

Completeness4/5

The core CFR workflow is well covered: search, navigate structure, retrieve text, and check historical versions. A minor gap is the lack of an explicit list_titles or list_parts tool, but get_title_structure and list_agencies provide workarounds for discovering the CFR hierarchy.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    A
    maintenance
    The most comprehensive keyless federal-data MCP server. 36 tools for SAM.gov + USAspending + Federal Register + eCFR + Grants.gov. No API key, no registration, no signup. Works in Claude Desktop, Claude Code, Codex CLI, Cursor, Continue, Gemini CLI, and any MCP-aware host.
    36
    100
    107
    6
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    A modular MCP server providing structured, methodology-driven prompt endpoints for rapid legal/compliance landscape mapping, gap discovery, and risk prioritization across privacy, IP, AI governance, security, consumer, and disclosure domains, with argument-based adaptability to any product context.
    18
    6
    MIT
  • F
    license
    Not graded
    quality
    C
    maintenance
    Pro Se Engine is an MCP server that provides 39 legal research tools across 6 government APIs, enabling AI agents to access case law, SEC filings, federal legislation, regulations, government contracts, and document processing workflows.
    -
  • A
    license
    Not graded
    quality
    B
    maintenance
    An MCP server that turns the US Code of Federal Regulations into an agent-navigable citation graph, enabling traversal of regulatory references and detection of stale citations via structured tools.
    MIT

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/vvXranjan/cfr-compliance-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server