Skip to content

NoumenaDigital/shield

Repository files navigation

Shield

NOUMENA MCP Gateway — a secure, policy-controlled proxy for Model Context Protocol servers.

Shield sits between AI clients and your MCP backend servers. It aggregates multiple MCP backends into a single endpoint, namespaces their tools and resources to avoid name conflicts, enforces Rego-based access policies, and optionally requires OAuth 2.0 bearer-token authentication on every connection.

Shield is designed to be immediately useful: a single command gives you a working gateway with no infrastructure required. The same configuration scales to enterprise deployments with authentication, fine-grained access policies, and a full audit trail — without the heavyweight setup that most enterprise MCP solutions demand.


Table of Contents


Features

  • Multi-backend aggregation — proxy any number of stdio or HTTP MCP servers behind a single endpoint.
  • Automatic namespacing — tools, resources, and prompts are prefixed with their backend name (e.g. wikipedia:search) so name collisions across backends are impossible.
  • Policy engine — restrict tool access with OPA Rego policies. Enforcement applies when Rego policy files are loaded; configuring the policy engine without any loaded .rego files does not by itself deny access.
  • OAuth 2.0 authentication — validate bearer tokens via token introspection; advertise protected-resource metadata for automatic client discovery.
  • Audit trail — every tool call, resource access, and prompt invocation is recorded with structured logs for compliance and debugging.
  • Admin UI — built-in web interface (:8080 by default) with catalog browsing, session inspection, and audit log viewer.
  • Per-session isolation — every MCP client gets its own dedicated backend connections; one client cannot affect another.

Prerequisites

  • Go 1.26.1 or newer
  • (Optional) Docker — required to run the demo backends or stdio backends that are packaged as containers
  • (Optional) Node.js / npx — for the MCP Inspector client

Installation

Clone the repository and build the binary:

git clone https://github.com/noumenadigital/shield.git
cd shield
go build -o shield ./cmd/shield

Or run directly without building:

go run ./cmd/shield <command>

Quickstart

Start a gateway with no backends (useful for a smoke-test):

go run ./cmd/shield server

The MCP endpoint is now available at http://localhost:8081/mcp and the admin UI at http://localhost:8080/.

Connect an MCP client to the gateway using the MCP Inspector:

npx @modelcontextprotocol/inspector --server-url http://localhost:8081/mcp

Usage

Commands

Command Description
shield server Start the MCP gateway. Accepts -f <config.yaml> or -catalog <mcp.json> flag.
shield from-catalog <mcp.json> Convert mcpServers JSON catalog file into a full YAML config and writes it to stdout.

Starting with an existing mcp.json

If you already have an mcp.json (e.g. from Claude Desktop or another MCP client), you can start a gateway immediately:

./shield server -catalog mcp.json

Tools from all listed backends are automatically aggregated and namespaced. For example, a search tool on a wikipedia backend becomes wikipedia:search.

Generating a config file from a catalog

Migrate from a JSON catalog to a full YAML configuration in one step:

./shield from-catalog mcp.json > config.yaml
./shield server -f config.yaml

Running with a YAML config file

./shield server -f path/to/config.yaml

Configuration

Shield is configured with a YAML file. The top-level sections are:

mcp:            # MCP gateway listener (default port: 8081)
admin:          # Admin web interface (default port: 8080)
backends:       # Named backend MCP servers (stdio or HTTP)
policyEngine:   # OPA Rego access-control policies (optional)
authentication: # OAuth 2.0 bearer-token authentication (optional)

Minimal example — two backends, no auth

mcp:
  port: 8081

backends:
  wikipedia:
    url: http://localhost:18000/mcp
  local-tool:
    command: /usr/local/bin/my-mcp-server
    args: ["--verbose"]

With Rego policy enforcement

mcp:
  port: 8081

backends:
  wikipedia:
    url: http://localhost:18000/mcp

policyEngine:
  type: rego
  source: "."      # load *.rego files from the same directory
  package: whitelist

Place .rego files next to the config file to whitelist tools:

# global-whitelist.rego
package whitelist

mcp.wikipedia.tools.search.allowed := true

With OAuth 2.0 authentication

authentication:
  identityProvider:
    url: https://auth.example.com/realms/my-realm
    clientID: shield-server
    clientSecret: "env.SHIELD_CLIENT_SECRET"
    scopes:
      - profile
      - email

For the full configuration reference see docs/configuration.md. For the full architecture reference see docs/architecture.md. For the Rego policy authoring guide see docs/rego.md.


Version

Check the installed version:

$ shield version
shield v0.1.0

Health Check

Shield exposes a health endpoint for load balancers and monitoring systems:

$ curl http://localhost:8081/health
{
  "status": "ok",
  "name": "noumena-shield",
  "version": "<build-tag-or-dev>",
  "time": "YYYY-MM-DDTHH:MM:SSZ"
}

Endpoint Details:

  • Path: /health
  • HTTP Method: GET
  • Response Code: 200 OK (when healthy)
  • Content-Type: application/json
  • Authentication: Not required (always accessible)
  • Response Fields:
    • status: Server status ("ok" when healthy)
    • name: Server name ("noumena-shield")
    • version: Server version (injected from the build tag; defaults to "dev" for local/non-release builds)
    • time: Current UTC time in RFC3339 format

This endpoint is useful for:

  • Kubernetes liveness/readiness probes: Configure your container orchestration to periodically check /health
  • Load balancer health checks: Route traffic only to healthy Shield instances
  • Monitoring systems: Verify Shield is running and responsive

Release Process

Shield uses GitHub Actions and GoReleaser to automate semantic versioning and releases.

Making a Release

  1. Trigger the release workflow via GitHub Actions:

    • Go to Actions → Release workflow → "Run workflow"
    • Enter a version (e.g., 0.2.0 or v0.2.0) — both formats are accepted
    • The workflow normalizes the version to v-prefixed semver (v0.2.0)
    • The workflow validates the semver format and checks that the tag doesn't already exist
  2. Automated steps:

    • GoReleaser builds and archives binaries for:
      • Platforms: Linux, macOS, Windows
      • Architectures: amd64, arm64
      • Format: shield-{os}-{arch}.tar.gz (.zip for Windows)
    • Generates SHA256 checksums
    • Automatically extracts release notes from commit messages since the last release
    • Creates a GitHub release with all artifacts
    • Uses: default GITHUB_TOKEN provided by GitHub Actions (workflow grants contents: write)

Version Injection

The binary version is automatically injected at build time via GoReleaser using the git tag:

var version = "dev"  // Set to the git tag (e.g., v0.1.0) at build time

The version is printed by the shield version command and must match the git tag.


Contributing

  1. Fork the repository and create a feature branch.
  2. Install pre-commit hooks (enforces go fmt, go vet, golangci-lint, and tests on every commit):
    pre-commit install
  3. Make your changes, ensuring all tests pass:
    go test -short ./...
  4. Open a pull request with a clear description of your change.

License

Shield is licensed under the Apache License 2.0.


References

About

No description, website, or topics provided.

Resources

Security policy

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages