Segun Olumbe

compliance · mcp

bouncer

Your controls against versioned rule packs for the UK Online Safety Act and the ICO Children's Code. Rules are plain files you can diff. For when "is this lawful?" should not be a chatbot answer. Official MCP server on the registry.

  • Node.js
  • JavaScript (ESM)
  • JSON rule packs
  • MCP over stdio
  • GitHub Actions

Problem

Regulators now expect controls you can demonstrate: age assurance, high-privacy defaults for children, a way to report and block on user content. Those either exist in a codebase or they do not. Vulnerability scanners look for code that should not be there. Nothing was checking for the code that must be.

Constraints

  • No model. Whether a control exists should not be a chatbot answer.
  • The engine knows nothing about the law. Everything legal lives in the rule packs.
  • A surface it cannot find is unknown, never a pass.
  • Every pass points at a file and a line.
  • It is an engineering aid, not legal advice, and it says so.

Architecture

A small engine, a set of JSON rule packs, and an adapter that knows where things live in your stack. Read it top to bottom.

  1. Inputs

    • Rule packsJSON files. Each rule ties a legal standard to an assertion over a surface.
    • ConfigWhich packs to run, which rules to ignore, and which verdicts fail the build.
    • Your repositoryRead as files. Nothing is executed.
  2. Adapter

    • Surface mapResolves a surface such as sign-up, profile, chat, or livestream to the files that implement it. Next.js and React Native today.
  3. Engine

    • AssertionsFind a pattern in a surface and expect it present or absent, combined with all-of, any-of, and not.
    • VerdictsPass with a file and line, fail when the surface exists without the control, unknown when the surface cannot be found.
  4. Out

    • ReportTerminal output, or a self-contained HTML audit report.
    • CI gateExits non-zero when a required control is missing.
    • MCP serverFour tools: run a check, list the rules, explain a rule, list the packs.

Key decisions

  1. Checking that required code exists

    Instead of scanning for code that should not

    Scanners hunt for what should not be there. A repository can be free of vulnerabilities and still fail every obligation in a regulation. bouncer asks the opposite question, and the two are meant to run together.

  2. Rules as JSON packs

    Instead of rules written into the engine

    The engine knows nothing about the law; the packs do. A pack is a file you can read, diff, and review, and you can point bouncer at a directory of your own.

  3. An honest unknown

    Instead of passing what it cannot see

    If the sign-up surface cannot be located, bouncer cannot say whether age assurance is there. It reports unknown and never shows green for a surface it did not find.

  4. Gating application source

    Instead of policy-as-code over configuration

    Policy engines gate configuration and infrastructure. These obligations live in application code: a report button, a default setting, an age gate.

  5. Naming what a scan cannot prove

    Instead of pretending everything is checkable

    Some obligations are process, not code: a registration with the regulator, a signed agreement, a tax remittance. Those rules surface as gaps to track, not as things a static scan claims to have verified.

What broke, and the fix

  1. The MCP Registry rejected the server manifest.

    Cause
    The description was over the registry's 100-character limit.
    Fix
    Shortened it. The manifest is now published to the registry as part of every release.

Outcome

  • Published on npm and the MCP Registry.
  • Five packs and 33 rules: the UK Online Safety Act, the ICO Children's Code, and three Nigerian packs for data protection, consumer protection, and tax.
  • 19 tests on Node's built-in runner, run in CI on Node 18, 20, and 22.
  • It runs as its own check in both BashBop repositories.
  • A green report means the coded controls a rule looks for were found. It is not a substitute for a compliance review.