Last updated

iblai/ontology

Mirrored from iblai/ontology ยท README.md. This page is generated โ€” edit it in the repository, not here.

On-premise knowledge layer that makes an organization's existing systems queryable by AI agents over MCP โ€” no data extraction.

MCP Toolbox


What it is

iblai/ontology is a unified knowledge layer that runs inside your network. It makes the systems you already run โ€” SIS/ERP databases (PeopleSoft, Oracle, Postgres), data warehouses (Snowflake), and SaaS apps (Canvas, Salesforce, ServiceNow, Workday, Jira, โ€ฆ) โ€” queryable by AI agents over the Model Context Protocol (MCP).

The prevailing approach extracts your data through a VPN tunnel into a vendor cloud. iblai/ontology does the opposite: no data extraction, no VPN to our cloud, no third-party infrastructure holding your data. The agent runtime (where models execute) is a separate concern and can run anywhere; the knowledge layer โ€” the data, the cache, the permissions โ€” stays on-premise and is exposed over MCP so any authorized runtime can connect.

You will have your data, and we may not even have access to it.

It is domain-agnostic: the same stack serves a university (higher-ed systems) and an enterprise (CRM/ITSM/HCM/data-warehouse), with built-in defaults for both (see the catalog).

How it connects (MCP in, MCP out)

   YOUR NETWORK (ON-PREMISE)
   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
   โ”‚  Source systems                                                โ”‚
   โ”‚  PeopleSoft/Oracle ยท Snowflake ยท Postgres   Canvas ยท Salesforce โ”‚
   โ”‚        โ”‚  (SQL, read-only)                   โ”‚ (REST)           โ”‚
   โ”‚        โ–ผ                                      โ–ผ                  โ”‚
   โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
   โ”‚  โ”‚ Google MCP Toolbox        โ”‚   โ”‚ Custom MCP servers        โ”‚  โ”‚
   โ”‚  โ”‚ (databases) [1]           โ”‚   โ”‚ (APIs) [1]                โ”‚  โ”‚
   โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
   โ”‚                โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                โ”‚
   โ”‚            [2] sync โ†’ text memories (MD) + Postgres cache + vectors โ”‚
   โ”‚                                โ”‚                                โ”‚
   โ”‚            [3] identity: Entra ID JWT + roles.yaml (X-Iblai-Role) โ”‚
   โ”‚                                โ”‚                                โ”‚
   โ”‚            [4] iblai/ontology exposed as ONE MCP server (HTTPS) โ”‚
   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                     โ”‚  MCP over HTTPS, role-scoped
                                     โ–ผ
   EXTERNAL: agent runtime (ibl.ai or anywhere) โ€” forwards the user's
   Entra token per request, never stores institutional data.
  • Inbound uses Google MCP Toolbox for Databases: databases are exposed as MCP tools via config/tools.yaml (kind: source | tool | toolset). REST systems get lightweight custom MCP servers (mcp-servers/). Run ontology mcp validate to check tools.yaml against the Toolbox schema.
  • Outbound, iblai/ontology is itself one MCP server (streamable_http, behind your firewall + Entra ID). Any MCP client โ€” the ibl.ai agent runtime, Claude, Cursor, a custom app โ€” connects and gets results scoped to the caller's role.

Full design: docs/architecture.md.

Quick start

pip install -e ".[dev]"      # core CLI + tests
ontology --help
ontology config init         # scaffold a deployment (config/, sql/, compose)

Hybrid stack โ€” a lean, Django-free CLI + config layer (works on a fresh checkout) and a Django + Celery backend for the long-running services. Install extras as needed:

pip install -e ".[django]"   # backend services (gateway, sync, discovery)
pip install -e ".[llm]"      # BYOK schema analysis (anthropic / openai)
pip install -e ".[db]"       # source drivers (oracle, postgres, mysql, mssql)
pip install -e ".[vector]"   # ChromaDB vector index

Names: distribution iblai-ontology ยท import package iblai_ontology ยท command ontology.

Local checks

./dev.sh mirrors the CI gates so you can confirm everything passes before committing:

./dev.sh setup            # install into the active venv (dev + django extras)
./dev.sh test -k canvas   # pytest (args passed through)
./dev.sh fmt              # auto-fix ruff format + import sort
./dev.sh check            # ruff format/lint/import-sort + full pytest (== CI)

CI runs the same on every PR to main: .github/workflows/ruff-format.yml (ruff) and .github/workflows/tests.yml (pytest).

End to end

1 ยท Discover a service โ€” two ways

A. Live database โ€” connect, verify read-only, introspect, analyze, provision:

ontology service add --from peoplesoft \
  --host psft-db.internal.edu --database CSPRD --user iblai_readonly

--from <catalog-key> prefills the connection shape (driver, port, env) from the built-in catalog. The pipeline runs a read-only safety suite first โ€” seven write attempts that must all be denied โ€” then introspects the schema and generates config.

B. From a SKILL.md โ€” seed an API source with no live connection:

ontology service add --skill canvas      # or: ontology skill import canvas
ontology skill list                      # all vendored skills (higher-ed + enterprise)

This parses the skill's connection env and key operations into a discovery seed (read-only operations become suggested MCP tools).

2 ยท Interpret the schema & see the connection

ontology service schema peoplesoft        # discovered tables, by row count
ontology service connection peoplesoft     # stored connection (secrets redacted)
$ ontology service schema peoplesoft
peoplesoft โ€” oracle | 847 tables, 12,400,000 rows
            Top 20 tables
โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”ณโ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”ณโ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”ณโ”โ”โ”โ”โ”โ”โ”โ”โ”โ”“
โ”ƒ Schema โ”ƒ Table              โ”ƒ Rows      โ”ƒ Columns โ”ƒ
โ”กโ”โ”โ”โ”โ”โ”โ”โ”โ•‡โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ•‡โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ•‡โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”ฉ
โ”‚ SYSADM โ”‚ PS_STDNT_CAR_TERM  โ”‚ 2,345,678 โ”‚ 24      โ”‚
โ”‚ SYSADM โ”‚ PS_STDNT_ENRL      โ”‚ 1,876,543 โ”‚ 31      โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

3 ยท Test it

ontology service test peoplesoft           # 7-test read-only safety suite
ontology mcp validate                       # tools.yaml is MCP Toolbox compliant
ontology mcp test get-student-enrollment --params '{"student_id":"001234567"}'
$ ontology service test peoplesoft
  [PASS] CREATE TABLE blocked   [PASS] INSERT blocked   [PASS] UPDATE blocked
  [PASS] DELETE blocked   [PASS] DROP TABLE blocked   [PASS] ALTER blocked
  [PASS] TRUNCATE blocked
  All safety checks passed.   # credentials confirmed read-only

4 ยท Provision, sync, serve

ontology service approve peoplesoft         # cache schema, tools, sync schedules
ontology sync run peoplesoft                # pull โ†’ cache + text memories + vectors
ontology deploy up                          # bring up the stack (compose)

Then register iblai/ontology as an MCP server in your agent platform (see docs/platform-integration.md):

ontology platform register --url https://ontology.your-org.edu/mcp
ontology platform connect  --server 14 --scope user --role FinancialAidCounselor

Built-in service catalog

ontology catalog list ships defaults (connection shape, adapter, default toolset, sync cadences, and the upstream SKILL.md) for 22 systems across two domains. Seed any of them with ontology service add --from <key> or ontology skill import <key>.

Higher-ed โ€” iblai/higher-education-agents

KeySystemTypeSkill
peoplesoftPeopleSoft (Oracle)databaseโ€”
bannerEllucian BannerapiSKILL.md
canvasInstructure Canvas LMSapiSKILL.md
slateTechnolutions Slate CRMapiSKILL.md
workdayWorkday HCM / StudentapiSKILL.md
eab-navigateEAB NavigateapiSKILL.md
salesforce-education-cloudSalesforce Education CloudapiSKILL.md
servicenowServiceNow ITSMapiSKILL.md
civitas-learningCivitas LearningapiSKILL.md
handshakeHandshake CareersapiSKILL.md
blackbaud-raisers-edgeBlackbaud Raiser's Edge NXTapiSKILL.md

Enterprise โ€” iblai/enterprise-agents

KeySystemTypeSkill
snowflakeSnowflake Data WarehousedatabaseSKILL.md
salesforceSalesforce CRM / Sales CloudapiSKILL.md
hubspotHubSpot CRMapiSKILL.md
servicenow-itsmServiceNow ITSMapiSKILL.md
jiraJiraapiSKILL.md
confluenceConfluenceapiSKILL.md
githubGitHubapiSKILL.md
oktaOkta IdentityapiSKILL.md
slackSlackapiSKILL.md
zendeskZendeskapiSKILL.md
zoomZoomapiSKILL.md
ontology catalog show snowflake     # connection shape, env, default toolset, cadences, skill

Utilities

ontology doctor          # diagnostics: config validity, drivers, per-service env, Entra
ontology health          # PostgreSQL cache, MCP servers, sync engine, text-memory storage
ontology catalog list    # built-in service defaults (--domain higher-ed|enterprise)
ontology mcp validate    # tools.yaml โ†” Google MCP Toolbox schema

CLI reference

GroupCommandsPurpose
serviceadd ยท list ยท status ยท test ยท schema ยท connection ยท discover ยท approve ยท sync ยท removeSource integrations (discovery + provisioning)
skilllist ยท importInspect / seed discovery from a SKILL.md
cataloglist ยท showBrowse built-in service defaults
configinit ยท show ยท set ยท llm ยท validateConfiguration management
syncrun ยท status ยท history ยท scheduleSync operations
roleslist ยท show ยท validateRole & permission management
mcpstatus ยท tools ยท toolsets ยท validate ยท testMCP server administration
platformregister ยท connect ยท attachRegister with the ibl.ai platform
health / doctor(sub-checks)Diagnostics
deployup ยท down ยท logs ยท restart ยท statusDocker Compose lifecycle

Full reference: docs/components/07-cli.md.

Security posture

  • Read-only everywhere. No source writes in v1. Before touching any data, the safety suite attempts seven write operations and requires all seven be denied โ€” otherwise it refuses to proceed and prints remediation SQL.
  • Data stays on-premise. Source credentials never leave your network; the agent runtime queries at runtime, scoped by the authenticated user.
  • Identity through Entra ID. Every MCP request carries the user's Entra ID JWT; the gateway validates it and resolves the caller's role against roles.yaml. See docs/identity.md.
  • Credential isolation & containment. Each inbound MCP server has its own credential scope; connection secrets are encrypted at rest.

Gateway hardening (environment variables)

The gateway middleware is tuned entirely through environment variables on the ontology-gateway container โ€” no code change or rebuild, just set and restart.

Rate limiting (fixed-window throttle, keyed on the authenticated subject and falling back to client IP):

Env varDefaultPurpose
ONTOLOGY_RATELIMIT_ENABLEDtrueMaster on/off switch
ONTOLOGY_RATELIMIT_WINDOW60Window length in seconds (also the Retry-After value)
ONTOLOGY_RATELIMIT_MAX120Max requests per window (general bucket)
ONTOLOGY_RATELIMIT_TOOLS_CALL_MAX30Stricter max per window for tools/call

To loosen limits for higher traffic, raise ONTOLOGY_RATELIMIT_MAX / ONTOLOGY_RATELIMIT_TOOLS_CALL_MAX. Two caveats:

  • The window is fixed, not sliding โ€” a client can burst up to 2ร—MAX across a window boundary. Size the limit accordingly.
  • Counting is per worker process on the default in-memory cache, so with N workers the effective limit is โ‰ˆ N ร— MAX. Set ONTOLOGY_CACHE_URL to a redis://โ€ฆ URL so all workers share one counter and the configured number is the true global limit.

Transport security & response headers:

Env varDefaultPurpose
ONTOLOGY_SECURITY_HEADERS_ENABLEDtrueEmit security response headers
ONTOLOGY_REQUIRE_HTTPStrueReject Bearer tokens received over a plaintext (non-HTTPS) connection
ONTOLOGY_HSTS_MAX_AGE31536000Strict-Transport-Security max-age (seconds; 0 disables HSTS)
ONTOLOGY_HSTS_INCLUDE_SUBDOMAINStrueAdd includeSubDomains to HSTS
ONTOLOGY_CSPdefault-src 'none'; frame-ancestors 'none'Content-Security-Policy value
ONTOLOGY_REFERRER_POLICYno-referrerReferrer-Policy value
ONTOLOGY_FRAME_OPTIONSDENYX-Frame-Options value

HSTS is only emitted over HTTPS. TLS terminates at the Caddy edge, so the gateway trusts the proxy's X-Forwarded-Proto (SECURE_PROXY_SSL_HEADER) to decide whether a connection is secure โ€” keep the gateway reachable only via the proxy, never directly on :8080.

JWT replay protection:

The token jti (a required, validated claim) is checked against a cache-backed replay store keyed on the jti, with each entry expiring exactly when the token does (exp - now).

Env varDefaultPurpose
ONTOLOGY_JWT_REPLAY_MODEbindbind | strict | off (see below)
ONTOLOGY_JWT_REPLAY_TTL_FALLBACK3600Store TTL (seconds) for a token whose exp is missing

Entra ID access tokens are bearer tokens designed for reuse within their lifetime โ€” the ibl.ai platform forwards the same token across many MCP requests โ€” so blind single-use would break the integration. The modes:

  • bind (default): on first sight, bind the jti to the request's client IP; the same jti presented from a different IP is rejected as replay. Legitimate reuse from the platform's stable egress passes; a token stolen and replayed from elsewhere is caught. (IP is read from X-Forwarded-For set by Caddy; deployments with multiple platform egress IPs may need off or strict.)
  • strict: single-use โ€” any second presentation of a jti is rejected. Only for deployments that mint one-time tokens.
  • off: no replay checking.

As with rate limiting, the store is the Django cache: set ONTOLOGY_CACHE_URL to a redis://โ€ฆ URL so the check holds across all worker processes (on the default per-process cache a replay is only caught on the worker that first saw the token). Replay detection is best-effort; short token lifetimes and sender-constrained tokens (DPoP / mTLS) remain the strongest defences.

Vector store authentication:

Env varDefaultPurpose
CHROMA_TOKEN(required by compose)Static bearer token for the ChromaDB vector store

The vector-store container runs ChromaDB's TokenAuthenticationServerProvider, so every request must present CHROMA_TOKEN; without it no container on ontology-internal can read or write embeddings. The same value is passed to the sync-engine and ontology-gateway services, and the shared VectorSearch client presents it automatically. Generate a strong random value (e.g. openssl rand -hex 32) and set it in the root .env; the compose stack fails to start if it is unset. When CHROMA_TOKEN is absent (e.g. a local or air-gapped run against an unauthenticated store) the client connects without auth.

Documentation

DocumentCovers
docs/architecture.mdFull plan: positioning, diagram, seven components, design decisions, rollout
docs/components/01-mcp-inbound.mdMCP Toolbox + custom MCP servers, tools.yaml
docs/components/02-knowledge-materialization.mdSync modes, text memories, Postgres cache, vector index
docs/components/03-identity.md ยท docs/identity.mdEntra ID flow, roles.yaml, Option A vs. B
docs/components/04-mcp-outbound.md ยท docs/platform-integration.mdOutbound MCP server + ibl.ai platform integration
docs/components/05-service-discovery.mdSafety suite, introspection, BYOK LLM, adapters
docs/read-only-db-user.mdProvisioning a read-only Postgres role for a DB source
docs/components/06-provisioning.mdThe 6-step idempotent pipeline
docs/components/07-cli.mdFull CLI reference
docs/deployment.mdDocker Compose stack, networks, Caddyfile, .env, rollout

License

MIT โ€” see LICENSE.

Copyright ยฉ ibl.ai | support@iblai.zendesk.com