Skip to main content
Glama

Your codebase's vocabulary, enforced — and your agents can't drift it. Words and rulings live in a database; a tree-sitter scan checks every named thing your code declares against them — classes, structs, functions, types, modules, protocols — across twelve languages; a pre-write hook corrects your coding agent before drift ever lands.

montology reads what your code already declares — every named thing in Python, TypeScript, Go, Rust, Swift, Java, Ruby, Elixir, C and C++ (and, where there is a UI, the Tailwind theme and the CSS) — and turns it into an ontology with a gate: drift fails CI with the file, the line, and the repair. It is a vocabulary layer for all of your code, not a styling tool; a repo with no UI in it uses every part of this except the last.

# the CLI
uvx --from "git+https://github.com/shinyobjectz/montology#subdirectory=.monty/cli" monty init

# the agent skill (Claude Code, Cursor, and friends)
npx skills add shinyobjectz/montology

# npm (the launcher)
npm install -g montology

monty init + lint: theme adopted, drift receipted

Sixty seconds to a drift report

cd your-repo
monty init            # .monty/, agent wiring, the pre-write guard hook
monty explain         # the X-ray: what this repo is, in one pass
monty scan --candidates   # the words your code is already asking for
monty lint            # the gate — every finding carries its repair
monty config          # what the gate enforces, and how to change it
monty intake ask …    # no words yet? the agent's `intake` skill asks the team
                      # in a form, round by round, and ends in a glossary
FAIL collision: struct 'Harness' at Sources/Runner.swift:14 is the word
     'harness' — "the thing that runs a scenario end to end". Rename it,
     or record the exception: monty onto except harness --where … --why …
FAIL divergence: type 'RowID' is declared as String (db/rows.ts:8) and as
     Int (api/rows.ts:12) — one noun, two things
warn retired: 'pointer' was RENAMED to 'cursor' (the word moved when the
     UI stopped owning it). Name it 'cursor' — the old name stays retired.
note design: rogue color #121212 ×2 (first at css/app.scss:37)
     — nearest token: ink #1b1b1f (Δ31)

Every finding names the file, the line and the repair. The first three are about the CODE — a struct wearing a word that means something else, a type declared as two different things, a name a ruling retired — and the last is the same contract applied to a hex code, which is a word that means one thing. If your repo has no UI you will never see that line.

Where there IS a UI, the same machinery goes further: monty design recipes mines the class strings your markup repeats (flex flex-wrap gap-2 items-center ×102 — on shadcn/ui's own repo) so they can become named things.

Related MCP server: engineering-standards

The firewall: your agent cannot write drift

the guard denies the edit before it lands, with the tokens to use

Everything above is post-hoc. The guard runs before the write: monty init installs a pre-write hook in every harness it wires (merge-safe — .claude/settings.json and .cursor/hooks.json), and the plugin ships its own, so a plugin install is guarded without an init. It lints every proposed Write/Edit/NotebookEdit against the ontology in milliseconds — a declaration named after a retired word (renames are rulings; always blocks), a collision with an enforced word, a rogue hex when tokens exist. Deny is exit 2 with the repair on stderr: the harness feeds it straight back to the model, which corrects and retries. The agent physically cannot introduce a second gray or resurrect a renamed concept — it gets the token or the current word handed to it mid-edit. The guard fails open (malformed payload, no workspace, any internal error → allow silently) so it can never break an editor; humans in vim never meet it. monty doctor says, per harness, whether it is actually wired; monty config guard.names block|warn|off tunes it.

monty explain — the one-shot conceptual X-ray

point it at a repo it has never seen

Point montology at any repo cold: one command composes the declared surface, the vocabulary it has, the vocabulary it is asking for (with definitions drafted on the atomic tier when one serves — law-checked, refused over wrong), where meanings actually gather (semantic clusters vs the directory tree's claimed architecture: cross-cutting concepts, grab-bag directories), the design system as measured, and every place the repo contradicts itself — straight to the terminal, because an instrument prints findings, it does not decorate them.

The part that keeps you: words

A repo's concepts drift exactly like its colors. montology's vocabulary is a database, not a doc — one word, one meaning, a one-line test, an optional dotted code — rendered into a generated agent skill and enforced against every declaration tree-sitter can parse (python, ts/tsx, js, go, rust, swift, elixir, ruby, java, c, c++):

candidates → check-first → advisory collisions

monty onto check thread        # FREE / TAKEN / RULED — before naming ANYTHING
monty scan --candidates        # the words your codebase is asking for
monty onto add thread "a stateful user↔agent session" --code atl.thread --pos noun
monty onto amend thread --definition "…" --why "a later ruling narrowed it"
monty lint                     # collisions (advisory by default), code-tree
                               # integrity, stale prose — each with its repair

Not every symbol sharing a word's name is drift, and treating them alike produces a list nobody reads. A word carries what it names — verb, noun, or value type — and the judgment follows from it: Store.open is English doing ordinary work below the surface, while a noun answering for a second thing is the failure a vocabulary exists to prevent. A collision you keep is a recorded decision, in the database with the rest of the vocabulary:

monty onto except open --where "lib/**" --why "ordinary work below the surface"
monty onto except --drafts     # what an old [scan] allow list would become

What an exception can never do is silence a divergence — one value-typed word declared as two different values (@type name :: term() in one module, @type name :: %{…} in another). That is a separate law with a separate line: an exception says a symbol may share the name, not that the name may mean two things.

Rulings end arguments permanently: overloads ("say cell, not sandbox"), collisions with frameworks (whose word it is, who moved), and renames — the old name retires, old material stays readable, and monty migrate old new --apply propagates the rename through the code by token (tree-sitter positions, strings and comments untouched, losslessly round-trippable — proven on eight real repos).

When a ruling narrows a word you already authored, monty onto amend corrects the record in place: the name and its history stay, every field that changes is ledgered with the text it replaced, and an unknown name or a no-op is refused. Editing the database around the authoring path is the same drift the gate exists to catch.

Meaning over time

monty vitals: one verdict per repo

Three instruments make a repo's meaning a tracked quantity:

  • monty vitals — the pulse: gate state, vocabulary state, design state, guard compliance → one verdict (TENDED / DRIFTING / UNTENDED) with every reason carrying its repair — plus whether the firewall is wired and the org upstream it inherits. --json is the dashboard shape; --strict exits 1 unless TENDED, so a repo can gate on its own tending. Track it per repo the way you track CI.

  • monty drift — the telescope: the git history sampled into lexicon, palette and convergence curves (--csv for the research lane). On excalidraw's full history the palette fragmented ~10× in two years (4→11→27→42 distinct colors) while declarations merely doubled. Flask's concept lexicon: 49 concepts in 15 years, flat since 2019.

  • monty guard --stats — repair-following, measured: every hook denial followed by a clean edit within 30 minutes is a complied denial.

Semantic hearing

similar → the string laws pass → the audit hears the duplicate

The string laws enforce one word, one meaning. The [semantics] extra hears the dual — one meaning, one word — with POTION static embeddings (~30 MB, numpy-only; no torch, no runtime): monty onto audit flags two words defined into the same idea, local words that duplicate inherited org words under different names, candidates that are secretly existing words, and owner groupings that don't match where meanings cluster. Advisory permanently — a cosine score proposes, only a ruling decides.

One ontology, every repo

The org's vocabulary is authored once — any montology workspace's .monty/ontology.db is the artifact — and inherited everywhere:

inherit the org ontology, renames cross the fleet

monty init --from git@github.com:acme/ontology.git    # or a path, or a .db URL
monty onto pull                                       # refresh from the pin

Upstream rows refresh on every pull; local words always survive; a name defined in both places is a loud conflict (local wins — reconcile deliberately). When the org renames a word, every repo's next pull prints the exact monty migrate command: that is how a rename crosses the fleet.

The two models it carries (and the ones it refuses)

montology is deliberately near-modelless — the deterministic laws do the enforcing — but it carries exactly two, each chosen for a measured floor:

model

size

lane

what it does

what it refuses

POTION (potion-base-8M, model2vec)

~30 MB, numpy-only

[semantics] extra

static embeddings over definitions: onto similar, onto audit — duplicate meanings, org/local doubles, misfiled clusters. Millisecond inference, no torch, no runtime.

deciding anything. A cosine score proposes; only a ruling makes vocabulary.

gemma3:270m (via Ollama, optional)

292 MB, user-installed

monty gen <word>

drafts ONE-LINE definitions under the word laws (refused over written wrong) when no host agent is present — the autonomous lane.

bodies and prose. The 270M capability floor is atomic one-liners; everything longer is the host agent's work or a served endpoint (MONTOLOGY_MODEL_URL).

Nothing heavier ships, ever: no torch, no onnxruntime, no bundled weights. The host agent (Claude, Cursor, Codex) is always the best drafter available, and the gate never needs a model at all.

For agents

monty init wires the repo for Claude Code, Cursor, and Codex (merge-safe: sections are appended, JSON keys merged, global config never touched) — MCP server, the instructions section, and the pre-write guard hook in each harness's own dialect. monty doctor reports which of those actually landed.

Two skills ship: montology routes the work (new repo → set up, empty vocabulary → build one, working repo → the check-first contract), and intake runs the guided walkthrough for a codebase whose words were never written down. The generated words skill carries the whole vocabulary — words, tokens, recipes, rulings, doctrine — tiering into reference pages rather than truncating when it outgrows its budget.

The MCP server exposes ontology_check, ontology_add, ontology_amend, ontology_rule, ontology_similar, ontology_words, ontology_lint, scan_surface, scan_candidates, structural_search, repo_explain, repo_vitals and workspace_config. Prose is rendered from the database, never authored; a stale render fails the build.

Under the hood

tree-sitter (via tree-sitter-language-pack) measures declarations and CSS structurally; ast-grep (invoked, one static binary) powers structural pattern search; SQLite holds the vocabulary. The stress battery (stress/run.py, weekly in CI) proves four properties on eight real repos — flask, excalidraw, gin, ripgrep, phoenix, sinatra, spring-petclinic, redis: merge-safe idempotent init, zero-error parsing, truthful collision reporting, and lossless migrate round-trips.

The taxonomy library

62 public ontologies and taxonomies, licence-verified, grouped by domain. Browse with monty onto sources [group].

core — any business, any industry

ontology

licence

commercial

source

BFO — Basic Formal Ontology

CC BY 4.0

yes — attribution

bfo

DCMI Metadata Terms (Dublin Core)

CC BY 4.0

yes — attribution

dublin-core

NAICS (North American Industry Classification System)

US federal work — public domain (17 U.S.C. §105)

public domain

naics

PROV-O — the Provenance Ontology (W3C)

W3C Software and Document Licence

yes

prov-o

QUDT — Quantities, Units, Dimensions and Types

CC BY 4.0

yes — attribution

qudt

RO — the Relation Ontology

CC0 1.0

public domain

ro

Schema.org vocabulary (types + properties)

CC BY-SA 3.0

yes — share-alike

schemaorg

SIC codes

US federal work — public domain (17 U.S.C. §105)

public domain

sic

SKOS — Simple Knowledge Organization System (W3C)

W3C Software and Document Licence

yes

skos

health & life sciences

ontology

licence

commercial

source

ChEBI — Chemical Entities of Biological Interest

CC BY 4.0

yes — attribution

chebi

Human Disease Ontology

CC0 1.0

public domain

doid

Gene Ontology

CC BY 4.0

yes — attribution

go

Mondo Disease Ontology

CC BY 4.0

yes — attribution

mondo

NCI Thesaurus (OBO edition)

CC BY 4.0

yes — attribution

ncit

Uberon multi-species anatomy ontology

CC BY 3.0

yes — attribution

uberon

finance

ontology

licence

commercial

source

FIBO — Financial Industry Business Ontology

MIT

yes

fibo

retail & e-commerce

ontology

licence

commercial

source

Google Product Taxonomy

none — a bare .txt on www.google.com, no licence, no terms page, and developers.google.com's CC BY 4.0 site policy does not reach it

no — unlicensed

google-product

Shopify Product Taxonomy

MIT

yes

shopify-product

advertising & media

ontology

licence

commercial

source

AdCOM — Advertising Common Object Model (IAB Tech Lab)

CC BY 3.0 (stated in the repo README, no LICENSE file)

yes — attribution

adcom

Google NLP Content Categories

CC BY 4.0 (Google Cloud docs)

yes — attribution

google-nlp-categories

Google Topics API Taxonomy

W3C Software and Document Licence

yes

google-topics

IAB Ad Product Taxonomy 2.0

CC BY 3.0 (as above)

yes — attribution

iab-adproduct

IAB Audience Taxonomy 1.1

CC BY 3.0 (as above)

yes — attribution

iab-audience

IAB Content Taxonomy 3.1

CC BY 3.0 (stated in the repo README, no LICENSE file — so every automated scan calls it unlicensed)

yes — attribution

iab-content

The Open Graph protocol

Open Web Foundation Agreement 0.9

yes

open-graph

OpenOOH Venue Taxonomy

Apache-2.0

yes

openooh-venue

OpenRTB (IAB Tech Lab)

CC BY 3.0 (stated in the repo README, no LICENSE file)

yes — attribution

openrtb

Curlie (the DMOZ successor) web directory

CC BY 3.0 Unported

yes — attribution

dmoz-curlie

IABTechLab/iab-mapper (2.x → 3.0 mappings)

BSD-2-Clause

yes

iab-mapper

IPTC Media Topics

CC BY 4.0 — IPTC states it for all NewsCodes

yes — attribution

iptc-media-topics

IAB taxonomies as JSON (iPullRank)

MIT

yes

ipullrank-iab-json

agriculture & food

ontology

licence

commercial

source

AGRO — the Agronomy Ontology

CC BY 4.0

yes — attribution

agro

FoodOn — the Food Ontology

CC BY 4.0

yes — attribution

foodon

environment & climate

ontology

licence

commercial

source

ENVO — the Environment Ontology

CC0 1.0

public domain

envo

software & infrastructure

ontology

licence

commercial

source

AsyncAPI Specification

Apache-2.0

yes

asyncapi

CDEvents (Continuous Delivery Foundation)

Apache-2.0

yes

cdevents

Conventional Commits

MIT

yes

conventional-commits

OWASP CycloneDX

Apache-2.0

yes

cyclonedx

JSON Schema

BSD-style (JSON Schema Specification Authors)

yes

json-schema

OpenAPI Specification

Apache-2.0

yes

openapi

OpenTelemetry Semantic Conventions

Apache-2.0

yes

otel-semconv

purl — Package URL specification

MIT

yes

purl

Semantic Versioning

CC BY 3.0

yes — attribution

semver

SPDX — specification and licence list

Community Specification Licence 1.0; pre-existing portions CC BY 3.0

yes — attribution

spdx

SWO — the Software Ontology

CC BY 4.0

yes — attribution

swo

DOAP — Description of a Project

Apache-2.0

yes

doap

OASIS TOSCA (Topology and Orchestration Specification)

Apache-2.0

yes

tosca

security

ontology

licence

commercial

source

CVE — Common Vulnerabilities and Exposures

CC0 1.0

public domain

cve

CWE — Common Weakness Enumeration

MITRE royalty-free licence (research, development AND commercial; reproduce the copyright designation)

yes — attribution

cwe

MITRE D3FEND — defensive countermeasures

MIT

yes

d3fend

MITRE ATT&CK

MITRE royalty-free licence (research, development AND commercial; reproduce the copyright designation)

yes — attribution

mitre-attack

AI, ML & data science

ontology

licence

commercial

source

Croissant — ML dataset metadata (MLCommons)

Apache-2.0

yes

croissant

EDAM — data, operations, formats and identifiers

CC BY-SA 4.0

yes — share-alike

edam

MITRE ATLAS — adversarial threats to AI systems

Apache-2.0

yes

mitre-atlas

OpenTelemetry GenAI Semantic Conventions

Apache-2.0

yes

otel-genai

OWASP Top 10 for LLM Applications

CC BY-SA 4.0

yes — share-alike

owasp-llm

STATO — the Statistical Methods Ontology

CC BY 3.0

yes — attribution

stato

geography

ontology

licence

commercial

source

GeoNames ontology + gazetteer

CC BY 4.0

yes — attribution

geonames

trade & occupations

ontology

licence

commercial

source

Harvard Growth Lab classifications (ISIC/HS/SITC/O*NET)

BSD-3-Clause

yes

cid-classifications

research & information

ontology

licence

commercial

source

DCAT — Data Catalog Vocabulary (W3C)

W3C Software and Document Licence

yes

dcat

IAO — Information Artifact Ontology

CC BY 4.0

yes — attribution

iao

general knowledge

ontology

licence

commercial

source

wikidata-taxonomy (extraction CLI)

MIT (the tool; Wikidata's own data is CC0)

yes

wikidata-taxonomy

Contributors

git clone https://github.com/shinyobjectz/montology && cd montology
uv sync && just              # the action surface
just check                   # the gate (montology lints itself, strictly:
                             # its own toml sets collisions = "enforce")

Available Tools

7 tools
ontology_addB

Author a word — check-first: a taken name is refused with findings. Re-renders the words skill on success.

Inputs: name (required), definition (required), code, kind, +2 more. Returns: result

ontology_checkA

Is this name free, defined, or ruled on? Run BEFORE naming anything.

Inputs: name (required). Returns: result

ontology_lintC

The gate: collisions, code resolution, drift — each FAIL carries its repair.

Inputs: no named parameters. Returns: result

ontology_wordsB

The vocabulary as rows (kind: core | inner | adopted | custom | empty for all).

Inputs: kind. Returns: result

scan_candidatesC

Vocabulary the codebase is asking for: recurring declared names with no word.

Inputs: top. Returns: result

scan_surfaceC

What the code declares: counts by language, skips said out loud.

Inputs: no named parameters. Returns: result

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    C2.9/5.0

    Scored across 7 tools

    Disambiguation4/5

    Tools are largely distinct: check/words/add target the ontology, scan_surface/scan_candidates focus on code analysis, lint is a holistic gate, and structural_search is clearly separate. Minor overlap exists between ontology_check (single name) and ontology_lint (overall issues), but contexts are clear.

    Naming Consistency2/5

    Naming mixes prefixes: ontology_check, ontology_words, ontology_add, ontology_lint use 'ontology_' while scan_surface and scan_candidates use 'scan_', and structural_search is standalone. Patterns also vary between verb-based (check, add, lint) and noun-like (words) or adjective-noun (structural_search).

    Tool Count5/5

    With 7 tools, the surface is well-scoped for managing a code ontology: basic CRUD (check, words, add), scanning (surface, candidates), validation (lint), and advanced search (structural_search). Not overly large or thin.

    Completeness3/5

    Core workflows (check, add, list, lint, scan) are covered, but the set lacks update/delete operations for words (only add exists) and no way to view details of a single word beyond listing. This leaves minor lifecycle gaps, though most typical use cases are supported.

    Maintenance

    ActivityStale
    ResponsivenessLimited data

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      D
      maintenance
      Provides comprehensive codebase analysis including project structure evaluation, cross-language duplicate detection, microservices validation, and configuration optimization with AI-powered pattern learning that generates actionable improvement reports.
      MIT
    • A
      license
      A
      quality
      D
      maintenance
      Enforces team engineering standards across Git, code review, Rails, frontend, deployment, incidents, observability, API design, database, ADRs, and technical debt, with tools for branch name and commit message validation.
      4
      MIT
    • A
      license
      A
      quality
      B
      maintenance
      Enables AI assistants and developers to analyze code for language-specific best practices and idiomatic patterns across programming languages, CI automation, and configuration formats.
      16
      2
      MIT