npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

ontofence

v1.0.12

Published

Ontology-based safeguard for MCP servers

Readme

🛡️ OntoFence

Semantic guardrails for agentic workflows.

License TypeScript MCP

OntoFence provides a formal security and safety layer for AI agents. By using OWL (Web Ontology Language) as a Golden Source of Truth, it prevents "fatal mistakes" (e.g., fraudulent $1M refunds, HIPAA violations) even if an LLM incorrectly plans a dangerous action.


⚡ Why OntoFence?

LLMs are stochastic and can be tricked by prompt injections or simple logic errors. Traditional guards are often hardcoded and brittle. OntoFence is:

  • Rule-Based: Business rules live in the ontology, not in the code.
  • Explainable: Blocks actions with human-readable reasons, severity, and suggestions.
  • Platform-Agnostic: Wires into any MCP server or AI framework.
  • Zero Hardcoding: Logic changes require updating an OWL file, not rebuilding your app.

🎯 How It Works

Architecture

OntoFence Architecture

If you need to edit this diagram, use the Mermaid code below and re-generate the image:

graph TD
    A[AI Agent / LLM] -- "1. Plan Action" --> B(🛡️ OntoFence)
    B -- "2. Load Rules" --> C[OWL Ontology]
    B -- "3. Execute SPARQL" --> D{Reasoning Engine}
    D -- "4. ALLOW / BLOCK" --> B
    B -- "5. Validated Action" --> E[Real-World API / DB]

Before vs After

| Scenario | Without OntoFence | With OntoFence | | :--- | :--- | :--- | | Finance | Agent refunds $50k via prompt injection. | ❌ Blocked: "Refund exceeds $1k limit" | | Health | Agent shares patient data with researcher. | ❌ Blocked: "Doctor role required for PHI" | | Logic | Agent deletes a production database. | ❌ Blocked: "Resource 'PROD' is immutable" |


🚀 Quick Start

Installation

npm install ontofence

For defining Rules/Ontologies, you'll likely want the TypeScript types:

npm install -D typescript @types/node

Basic Usage

import { OntologyGuard } from "ontofence";
import * as fs from "fs";

const guard = new OntologyGuard();
guard.loadOntology(fs.readFileSync("./finance.owl", "utf-8"));

const result = await guard.validate("refund_money", {
    userId: "user_123",
    amount: 5000
});

if (!result.allowed) {
    console.log(`Blocked: ${result.reason} [${result.severity}]`);
    console.log(`Try: ${result.suggestedActions?.join(", ")}`);
}

📖 API Reference

OntologyGuard

| Method | Signature | Description | | :--- | :--- | :--- | | loadOntology | (owlContent: string, format?: string): void | Load an OWL ontology into the guard. Can be called multiple times to combine rules. Default format: "application/rdf+xml". | | validate | (toolName: string, args: Record<string, any>): Promise<ValidationResult> | Validate a proposed tool call against all loaded constraints. | | registerSchema | (toolName: string, schema: z.ZodTypeAny): void | Registers an optional Zod schema for a tool. If registered, validate will run schema.safeParse before invoking SPARQL, failing eagerly and returning specific error messages if parsing fails. | | reset | (): void | Clears the internal store, discarding all previously loaded ontologies and registered schemas. |

ValidationResult

interface ValidationResult {
    allowed: boolean;       // true if the action is safe
    reason?: string;        // human-readable explanation (on block)
    severity?: Severity;    // "INFO" | "WARNING" | "CRITICAL"
    suggestedActions?: string[]; // actionable fix suggestions
}

Severity Enum

| Value | Meaning | | :--- | :--- | | INFO | Advisory — action may proceed with caution | | WARNING | Suspicious — review recommended | | CRITICAL | Dangerous — action must be blocked |

ProtectedMcpServer

| Method | Signature | Description | | :--- | :--- | :--- | | protectTool | (toolName: string, handler: Function, schema?: z.ZodTypeAny): Function | Returns a wrapped handler that validates against the ontology before executing. If schema is provided, arguments are validated using Zod before SPARQL reasoning, preventing bad inputs from reaching the ontology engine. Throws [ONTOLOGY_BLOCK] error on violation. |


💼 Integration Options

OntoFence is designed to be highly versatile. You can integrate it into your agent architecture in three different ways:

1. Native MCP Integration (TypeScript/Node.js)

If you are building your server in TypeScript using the official @modelcontextprotocol/sdk, this is the fastest and most efficient integration.

import { ProtectedMcpServer, OntologyGuard } from "ontofence";
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { CallToolRequestSchema } from "@modelcontextprotocol/sdk/types.js";
import { z } from "zod";
import * as fs from "fs";

const server = new Server(
    { name: "my-server", version: "1.0.0" },
    { capabilities: { tools: {} } }
);
const guard = new OntologyGuard();
guard.loadOntology(fs.readFileSync("./my-rules.owl", "utf-8"));

const protectedServer = new ProtectedMcpServer(server, guard);

// Optional: Define Zod Schemas to validate arguments *before* expensive semantic reasoning
const PaymentSchema = z.object({
    amount: z.number().positive(),
    userId: z.string()
});

// Pre-create protected handlers at init time (recommended)
const protectedHandlers = {
    sensitive_db_delete: protectedServer.protectTool("sensitive_db_delete", myDeleteHandler),
    process_payment: protectedServer.protectTool("process_payment", myPaymentHandler, PaymentSchema),
};

server.setRequestHandler(CallToolRequestSchema, async (request) => {
    const handler = protectedHandlers[request.params.name];
    if (handler) {
        return await handler(request.params.arguments);
        // Throws [ONTOLOGY_BLOCK] with reason, severity, and suggestions if blocked.
    }
    throw new Error("Tool not found");
});

2. HTTP API (For Python, Rust, Go MCP Servers)

If you are running agents or MCP servers in other languages (like Python), you can use OntoFence as an independent microservice. Since the API server is a standalone application, you'll need to clone the repository:

git clone https://github.com/AntimatterAI/ontofence.git
cd ontofence
npm install
npm run start:api

Runs on http://localhost:3000 and auto-loads .owl files from the examples/ directory.

Then, inside your Python MCP server handler, make a simple HTTP request before executing your logic:

import requests

def my_python_tool_handler(amount: int, user_id: str):
    response = requests.post("http://localhost:3000/validate", json={
        "toolName": "refund_money",
        "args": {"amount": amount, "userId": user_id}
    }).json()
    
    if not response["allowed"]:
        return f"Blocked: {response['reason']}. Try: {response['suggestedActions']}"
        
    # Execute actual logic...

3. Command Line Interface (CLI)

You can directly invoke OntoFence via the CLI. This is great for shell scripts or quick testing without bringing up a server.

npx ontofence ./examples/finance.owl refund_money '{"userId": "user123", "amount": 5000}'

Output:

{
  "allowed": false,
  "reason": "CRITICAL: Refund amount exceeds the golden threshold of $1000",
  "severity": "CRITICAL",
  "suggestedActions": [
    "Reduce the refund amount below $1000 or request manual override."
  ]
}

📝 Writing Your Own Ontology

OntoFence constraints are defined in OWL files using embedded SPARQL queries. Each constraint must:

  1. Be an instance of ont:Constraint
  2. Have an ont:sparql property containing a SPARQL SELECT query
  3. Return ?reason, ?severity, and optionally ?suggestion variables when violated

Example: Custom Constraint

<?xml version="1.0"?>
<rdf:RDF xmlns="http://example.org/ontology#"
     xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
     xmlns:owl="http://www.w3.org/2002/07/owl#"
     xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
     xmlns:ont="http://example.org/ontology#">

    <owl:Ontology rdf:about="http://example.org/ontology"/>
    <owl:Class rdf:about="http://example.org/ontology#Constraint"/>

    <!-- Block deletions on production resources -->
    <ont:Constraint rdf:about="http://example.org/ontology#NoProdDelete">
        <rdfs:label>Production Delete Protection</rdfs:label>
        <ont:sparql>
            PREFIX ont: &lt;http://example.org/ontology#&gt;
            SELECT ?reason ?severity ?suggestion WHERE {
                ?op ont:toolName "delete_resource" ;
                    ont:arg_environment ?env .
                FILTER(?env = "production")
                BIND("Cannot delete resources in the production environment." AS ?reason)
                BIND("CRITICAL" AS ?severity)
                BIND("Use the staging environment, or request approval from an admin." AS ?suggestion)
            }
        </ont:sparql>
    </ont:Constraint>

</rdf:RDF>

How it works

  • When validate("delete_resource", { environment: "production" }) is called, OntoFence injects the operation as temporary RDF triples.
  • Each ont:Constraint SPARQL query is executed against the combined data.
  • If a query returns results, the ?reason, ?severity, and ?suggestion columns become the ValidationResult.
  • Arg keys are mapped to predicates as ont:arg_<key> (e.g., environmentont:arg_environment).

Loading Multiple Ontologies

You can load multiple OWL files to compose a safety mesh:

guard.loadOntology(fs.readFileSync("./finance-rules.owl", "utf-8"));
guard.loadOntology(fs.readFileSync("./hipaa-rules.owl", "utf-8"));
guard.loadOntology(fs.readFileSync("./infra-rules.owl", "utf-8"));
// All constraints from all files are evaluated on every validate() call.

Pre-built Standard Rules

Shipping out-of-the-box, OntoFence includes community-verified, best-practice ontology templates for popular open-source MCP servers (like the official Filesystem and Github servers). These rules prevent dangerous mutations (e.g., editing .git/, modifying /etc, force pushing to main).

import { OntologyGuard, StandardRules } from "ontofence";

const guard = new OntologyGuard();

// Instantly apply strict rules to protect host environments and repos!
guard.loadOntology(StandardRules.FilesystemRules);
guard.loadOntology(StandardRules.GithubRules);

📊 Telemetry & Audit Logging

Security tools must be highly observable. OntoFence includes an AuditLogger that emits a structured JSON payload for every evaluation, designed to be piped directly into your SIEM tool of choice (e.g. Datadog, Splunk).

Setup

import { OntologyGuard, AuditLogger } from "ontofence";

const guard = new OntologyGuard();

// Attach the default logger (emits JSON to console.log)
guard.setAuditLogger(new AuditLogger());

// OR provide a custom callback to route events to a specific destination
guard.setAuditLogger(new AuditLogger((event) => {
    myWinstonLogger.info("Ontofence Audit Event", event);
}));

Event Payload

When an agent attempts an action, the logger will output:

{
  "timestamp": "2026-03-06T12:00:00.000Z",
  "toolName": "refund_money",
  "args": {
    "userId": "user1",
    "amount": 5000
  },
  "validationResult": {
    "allowed": false,
    "reason": "CRITICAL: Refund amount exceeds the golden threshold of $1000",
    "severity": "CRITICAL"
  }
}

⚙️ Configuration

API Server Environment Variables

| Variable | Default | Description | | :--- | :--- | :--- | | PORT | 3000 | Port for the HTTP API server | | CORS_ORIGIN | * | Allowed CORS origin(s). Set to a specific domain in production. | | RATE_LIMIT_MAX | 100 | Maximum requests per IP per minute. Returns 429 when exceeded. |

Endpoints

| Method | Path | Description | | :--- | :--- | :--- | | POST | /validate | Validate a tool call. Body: { "toolName": "...", "args": {...} } | | GET | /health | Health check. Returns { "status": "ok", "loadedOntologies": [...] } | | POST | /reload | Reloads all .owl ontologies from the examples/ directory. |

Note: The API server also includes a file watcher that automatically hot-reloads ontologies when .owl files in the examples/ directory are modified, allowing for zero-downtime policy updates.


🧪 Testing

# Run all tests (unit + integration)
npm test

# Run only Vitest unit tests
npm run test:unit

# Run only integration tests (build + verify)
npm run test:integration

The test suite includes 62 unit tests across 5 suites:

  • Security helpers (Turtle escaping, URI sanitization)
  • Core validation (finance rules, healthcare rules, boundary values, schema validation)
  • State isolation (no leaking between validate calls)
  • MCP wrapper (pass-through, blocking, error structure, Zod schema enforcement)
  • Audit logger (custom handlers, default console output, error resilience)
  • Standard rules (filesystem protection, GitHub branch protection)

Plus 9 integration tests running end-to-end against the example ontologies.


🔧 Features

  • Generic Constraint Engine: Discover and execute any ont:Constraint.
  • Severity Levels: Support for INFO, WARNING, and CRITICAL.
  • Suggested Actions: Provide clear instructions to the LLM/User on how to fix a blocked action.
  • Multi-Ontology: Load multiple OWL files to build a complex safety mesh.
  • Pre-built Standard Ontologies: Shipped templates protect vanilla Filesystem and Github MCP servers effortlessly.
  • Ontology Hot-Reloading: Update safety policies without restarting the server via the /reload endpoint or filesystem watcher.
  • Telemetry & Audit Logging: Emit structured JSON events for SIEM parsing on every evaluation.
  • Input Sanitization: Prevents SPARQL/Turtle injection via user-supplied values.
  • State Isolation: Ephemeral store pattern ensures no cross-request contamination.
  • CORS & Rate Limiting: API server hardened for production exposure.
  • Node.js & TypeScript: Native ESM support with full type declarations.

📄 License

Apache 2.0 © 2026 OntoFence Contributors.