Skip to main content
Glama
DE-BARY-LLC

debary-mcp-compliance

Official
by DE-BARY-LLC

debary-mcp-compliance

tests

An MCP server that gives a language model access to a fair-housing and advertising rule engine for US real-estate listing text — without giving it the decision.

The engine is deterministic: 81 phrase rules, 35 required elements, six states, no model anywhere in the decision path. This server carries the question in and the verdict out. The model on the other end receives every finding, the statute behind it, and the wording the rule base proposes instead. What it does not receive is permission to disagree.

That is the reason this is an MCP server and not a REST endpoint with a nice description. A model needs a tool it cannot argue with, and MCP is the protocol that puts that tool inside its reach without putting it inside its judgement.

Built by DE BARY LLC. The engine it wraps runs at gate.debary.us.


Try it

No configuration, no rule base, no network:

pip install -e .
python demo.py

The demo starts the server as a subprocess, speaks MCP to it, and walks through a listing that fails, the statute behind each finding, a repair, and the re-check that catches what the repair still missed.

⚠️ With nothing configured the server runs on a sample rule base — six rules and four required elements, written for this repository so it can be run and tested by anyone. It labels itself: every result carries backend: "sample" and rules_version: "sample-1". It is illustrative and is not a compliance tool. Point GATE_APP_DIR or GATE_URL at the real base to get real answers.


What it exposes

MCP has three primitives. This server uses all three, and each one is here because it is the right shape for what it carries.

Tools — things the model asks the engine to do

Tool

Purpose

check_listing

Run listing copy through the engine. Returns findings, missing required elements, and a blocking verdict to branch on.

explain_rule

The full rule behind a finding, including the statute. So a model cites the authority instead of recalling one.

suggest_rewrite

Character offsets of every problem span plus the approved replacement wording. Deliberately does not rewrite — composing text is the model's job, verifying it is the engine's.

get_receipt

A stored check: what was examined, against which rule version, and the SHA-256 of the exact text.

Resources — material the model can read directly

URI

Contents

gate://rules

The rule base index: every rule and required element by id, severity and category

gate://rules/{rule_id}

One rule in full, with authority and source document

gate://elements/{state}

Disclosure elements an advertisement must carry in that state

gate://receipt/{receipt_id}

A past check with its anchoring block

Prompts — the workflows, so each client does not reinvent them

Prompt

What it enforces

review_listing

check → cite → rewrite → check the rewrite again. The last step is the one that gets skipped when a model improvises.

explain_verdict

Turn a receipt into something a licensed agent can act on, including what the engine could not verify mechanically.


Design notes

The verdict is not negotiable. blocking is true when any high-severity rule fires or any required element is missing. The tool description says so, the server instructions say so, and the review_listing prompt tells the model to report a failed rewrite plainly rather than presenting it as fixed.

blocking: false is not a clearance. It means no rule fired. elements_manual lists what the engine cannot check mechanically — those still need a person. A tool that quietly reports success for what it did not examine is worse than no tool.

Every finding carries its authority. A finding without a citation is an opinion, and a rule engine that has opinions is a language model with extra steps. This is enforced in the test suite, not just intended.

Three backends, one interface. LocalBackend imports the engine and evaluates in-process — no network, and the listing text never leaves the machine. RemoteBackend calls a running gate over HTTP. SampleBackend carries a small rule base of its own so the server runs on a fresh clone. All three return the same shape, so the MCP layer never learns which one answered.

The fallback announces itself. A sample that silently impersonates the real thing would be a trap. This one puts sample in every result and sample-1 in the version field, and there is a test that fails if either label goes missing.

Two transports. stdio for a desktop client, streamable-http for the container. sse is still accepted for older clients; it is deprecated in the protocol and should not be chosen for anything new.

Requires the 2.x SDK. The Python SDK renamed FastMCP to MCPServer in 2.0 and moved it from mcp.server.fastmcp to mcp.server.mcpserver; result fields went from structuredContent to structured_content. This server targets 2.x only. Supporting both majors behind a shim was considered and rejected — it would add a compatibility layer to a project whose whole argument is that the decision path stays simple.


Running it

Against a local rule base

pip install -e .
GATE_APP_DIR=/path/to/compliance-gate/app debary-mcp-compliance

Against a running gate

GATE_URL=https://gate.debary.us GATE_TOKEN=… debary-mcp-compliance

GATE_APP_DIR wins if both are set: evaluating in-process is faster and keeps the listing text off the wire.

In Docker

docker compose up -d

The container listens on :8765/mcp (streamable HTTP) and is published on host port 8766, bound to loopback. Put a tunnel in front of it rather than opening a port. The rule base is mounted read-only — the container can evaluate rules, not change them.

Claude Desktop

{
  "mcpServers": {
    "debary-compliance": {
      "command": "debary-mcp-compliance",
      "env": { "GATE_APP_DIR": "/path/to/compliance-gate/app" }
    }
  }
}

Claude Code

claude mcp add debary-compliance \
  --env GATE_APP_DIR=/path/to/compliance-gate/app \
  -- debary-mcp-compliance

Configuration

Variable

Meaning

GATE_APP_DIR

Directory holding engine.py and rules.json. Selects the local backend.

GATE_URL

Base URL of a running gate. Selects the remote backend.

(neither set)

Falls back to the built-in sample rule base.

GATE_TOKEN

Bearer token for that gate, if its API is closed.

MCP_TRANSPORT

stdio (default), streamable-http, or sse.

MCP_HOST / MCP_PORT

Bind address for the HTTP transports. Default 0.0.0.0:8765.


Tests

pip install -e ".[dev]"
pytest -q                                            # 21 protocol tests, no setup
GATE_APP_DIR=/path/to/compliance-gate/app pytest -q  # + 3 production tests

The tests do not import the tool functions and call them. They launch the server as a subprocess, complete the handshake over stdio, and drive it as a client — because a tool that works in-process and fails over the wire is a tool that does not work.

What they check, beyond the happy path:

  • every tool declares an output schema, so callers branch on fields rather than prose

  • every finding carries an authority and a replacement wording

  • findings never overlap, so nothing is double-counted and no rewrite is corrupted

  • rewrite offsets actually index the text they claim to match

  • the digest is of the exact text submitted, not a normalised copy

  • an unknown rule id is an error, not an empty answer

  • an element the engine cannot verify comes back manual, never as a pass

  • the sample backend labels itself as one

The three production tests skip unless GATE_APP_DIR is set. They assert the rule version and the counts this project states in public, and that verdicts differ by state — claims no sample can stand in for.


Scope and limits

⚠️ Not legal advice. The rules were compiled from public statutes, agency guidance and industry policy; each carries its source and the date it was read. Compliance is decided by regulators and courts, not by this server.

⚠️ Six states: TX, CA, FL, AZ, NY, NC. A check run against the wrong state silently applies the wrong required elements — the state argument is not cosmetic. The server does not keep its own copy of this list: it asks the engine, because a hand-maintained copy drifted once and made two states unreachable.

⚠️ The sample rule base is not the product. Six rules against public statutes, written so this repository can be run by anyone. The base behind gate.debary.us is larger, is compiled from sourced documents with read dates, and is maintained separately.

⚠️ Advisory findings are state-scoped. A phrase that is binding in one state may come back as advisory in another. That is the engine being precise, not uncertain.


Apache-2.0 · DE BARY LLC, Austin TX

-
license - not tested
Not graded
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

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

  • Deterministic compliance and vertical knowledge bases for autonomous agents. Free 24hr trial.

  • Deterministic trust gate for AI output: leaked-secret, prompt-injection & PII in one call.

  • Deterministic validation for AI-generated artifacts: JSON Schema, OpenAPI response, SQL syntax.

View all MCP Connectors

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/DE-BARY-LLC/debary-mcp-compliance'

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