montology

montology

Enforces design systems and vocabulary via ontology checks, candidate scanning, linting, and structural search across repositories.

Category
访问服务器

README

<p align="center"><img src="docs/banner.png" alt="montology — your codebase's vocabulary, enforced" width="100%"></p>

Your codebase's vocabulary, enforced — and your agents can't drift it. Words, design tokens, and rulings live in a database; a tree-sitter scan checks every named thing in ten languages against them; a pre-write hook corrects your coding agent before drift ever lands.

# the CLI, works today
uvx --from "git+https://github.com/socialite-ml/montology#subdirectory=.monty/cli" monty init

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

# npm (the launcher)
npm install -g montology

montology

Your design system and your vocabulary, enforced — in any repo, by one command. montology reads what your code already declares — the Tailwind theme, the CSS, every class and every named thing in ten languages — and turns it into an ontology with a gate: drift fails CI with the file, the line, and the repair.

monty init + lint: theme adopted, drift receipted

uvx --from "git+https://github.com/socialite-ml/montology#subdirectory=.monty/cli" monty init

(that one-liner works today, from nothing but uv; npm install -g montology and PyPI are landing)

Sixty seconds to a drift report

cd your-repo
monty init            # .monty/, agent wiring — and your Tailwind theme
                      # auto-adopted as design tokens (the theme is the law)
monty lint
warn design: rogue color #121212 ×2 (first at css/app.scss:37)
     — nearest token: ink #1b1b1f (Δ31)
note design: #ffffff and #fafafa are Δ15 apart (11× / 4×) — one job,
     two values; pick one and tokenize it
note design: class 'ghost-panel' used 6× but defined in no stylesheet
note design: 3 Tailwind arbitrary value(s) — each left the scale
     (p-[13px], text-[#123456]…)

No config, no authoring — the theme you already wrote becomes the law, and every literal that escaped it gets a receipt. Recurring utility compositions surface too: 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.

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 PreToolUse hook (merge-safe, into .claude/settings.json) that lints every proposed Write/Edit 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. Config: [guard] names/design = block | warn | off.

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, 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
monty lint                     # collisions (advisory by default), code-tree
                               # integrity, stale prose — each with its repair

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).

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). First observation, excalidraw's full history: the palette fragmented ~10× in two years (4→11→27→42 distinct colors) while declarations merely doubled — and their one-off CSS-variable cleanup did not hold. Flask's concept lexicon, by contrast: 49 concepts in 15 years, flat since 2019. Convergence is a property of tending, not of software.
  • monty guard --stats — repair-following, measured: every hook denial followed by a clean edit within 30 minutes is a complied denial. The compliance dataset accumulates from ordinary use; every hooked workspace is a passive experiment in whether enforcement closes the literature's text-action disconnect.

The research notes — instruments, first measurements, prior art, open protocols — live in research/FINDINGS.md.

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). The generated words skill carries the whole vocabulary — words, tokens, recipes, rulings, doctrine — and the MCP server exposes ontology_check, scan_candidates, ontology_lint, structural_search and friends. 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.

Contributors

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

The marketing-era codebase lives at the marketing-era tag.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选