Install
$ agentstack add mcp-lucastraba-ai-canon ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
ai-canon
Keep your team's AI agent customizations in one canonical repo, then sync them into every repo, agent, and OS.
Define your canon once (skills, rules, MCP servers, helper scripts) in a single git repo. Each consumer repo declares which subset it wants via a manifest. Developers run one command and get native config for the agents they actually use:
| Agent | Skills | MCP | Rules | | --- | --- | --- | --- | | Claude Code | .claude/skills/ | .mcp.json | Not applicable | | Codex CLI | .agents/skills/ | .codex/config.toml | Not applicable | | Cursor | .cursor/skills/ | .cursor/mcp.json | .cursor/rules/-rules.mdc | | OpenCode | .opencode/skills/ | opencode.json | Not applicable |
(For rules, lean on AGENTS.md: every major agent reads it now. ai-canon fills the gaps that are still tool-specific.)
When to use this (and when not to)
Tools like rulesync and Ruler solve one repo → many agents and support far more tools than ai-canon does. If your canon lives happily inside a single repository, use them. Microsoft APM covers multi-repo distribution too, as a full package ecosystem with manifests, lockfiles, and org governance; if you want packages from many sources across many agents, use that.
ai-canon is the small version of that idea, one canon repo → many repos → many agents, with a few safety behaviors the bigger tools skip:
- A central, versioned canon repo owned by your platform/AI-enablement folks
- Per-repo manifests: the backend repo gets backend skills, the frontend repo gets frontend skills, everyone gets the common set
- A CI-friendly drift check (
ai-canon doctor --check) so repos notice when the canon moved - Ownership safety: generated files carry a marker and are never silently overwritten if hand-authored; stale skills are cleaned up only within your namespace
- Secrets hygiene:
${VAR}placeholders in MCP config resolve from the developer's environment; servers with missing values are skipped and reported, never written with unresolved placeholders
Quick start
1. Author a canon (once per team)
mkdir our-ai-canon && cd our-ai-canon && git init
npx ai-canon init canon
git add . && git commit -m "our AI canon" && git push
This scaffolds:
canon.json name, namespace, defaults
canon/
skills/common/*.md skills (SKILL.md format + frontmatter)
mcp/common.json MCP server catalog (${VAR} placeholders allowed)
rules/common.md rules content (for agents without AGENTS.md support)
scripts/ helper scripts installed to .ai/scripts/
manifests/
.json one manifest per consumer repo
The scaffold includes manifests/example.json. Copy it once per consumer repo and edit the selected content:
cp manifests/example.json manifests/your-app.json
# Edit "repo" to "your-app", then select the skills/rules/MCPs/scripts it needs.
git add manifests/your-app.json && git commit -m "add your-app manifest" && git push
The filename must match the consumer's repo value (normally its directory name).
2. Wire up each consumer repo
cd your-app
npx ai-canon init --canon git@github.com:your-org/our-ai-canon.git
git add .ai.yaml .gitignore && git commit -m "adopt ai-canon"
3. Every developer, any machine
npx ai-canon sync
Interactive on a TTY (pick agents, skills, MCPs); fully scriptable otherwise:
npx ai-canon sync --agent claude,cursor --no-interactive
npx ai-canon sync --agent codex --skill acme-test --mcp context7
A successful first sync is explicit about every local file it created:
ai-canon [acme]: your-app -> claude, codex
Changes (5)
created .claude/skills/acme-test/SKILL.md
created .agents/skills/acme-test/SKILL.md
created .mcp.json
created .codex/config.toml
created .ai.lock.json
The canon is cloned/fetched into the repo-local, gitignored .ai/.canon on every run, so updating everyone is just git push to the canon repo; developers pick it up on their next sync.
4. Keep repos honest in CI
npx ai-canon doctor --check # exit 1 if generated files drifted from the canon
Concepts
canon.json (canon repo root)
{
"name": "acme",
"namespace": "acme",
"generatedNotice": "GENERATED FILE. Do not edit directly. Run: ai-canon sync"
}
namespace scopes every canon skill name to -*. Stale cleanup also requires ai-canon's structured ownership marker, so hand-authored skills are left alone; the marker lets owned cleanup remain correct if a canon deliberately changes namespace.
Skills
Standard SKILL.md files with a little extra frontmatter:
---
name: acme-open-pr
description: Open a PR following Acme conventions. Use when the user says "open a PR".
agents: [claude, codex] # optional, default: all
default: false # optional, opt-in skill (default: true)
requires-env: [GITHUB_TOKEN] # optional, skipped + reported if missing
---
Instructions...
MCP catalog
{
"mcpServers": {
"context7": { "command": "npx", "args": ["-y", "@upstash/context7-mcp"] },
"jira": {
"command": "uvx",
"args": ["mcp-atlassian"],
"env": { "JIRA_API_TOKEN": "${JIRA_API_TOKEN}" },
"agents": ["claude", "codex"],
"default": false
}
}
}
Placeholders resolve from the process environment or the gitignored .ai.local/env. Developers can add personal servers in .ai.local/mcp.json; they merge on top of the canon.
Manifests (one per consumer repo)
{
"version": 1,
"repo": "backend",
"skills": ["common/*.md", "common/acme-jira-*.md", "backend/*.md"],
"rules": ["common.md", "backend.md"],
"mcp": ["common.json", "backend.json"],
"scripts": ["open-pr/*"],
"defaultAgents": ["claude", "codex"]
}
Consumer .ai.yaml
canon: git@github.com:your-org/our-ai-canon.git # or a relative path
repo: backend # manifest name; defaults to the directory name
canonRef: v1.2.0 # optional pin (tag, branch, or commit; default: remote default branch)
Safety rules
- Treat the canon repository as trusted code. It distributes agent instructions, MCP commands, and executable helper scripts. Review canon changes like application code and protect who can push to it.
- Generated files are local developer state: keep them gitignored (
initsets this up). They may contain resolved secrets. Sync refuses secret-bearing generated config that is already tracked by Git; remove it from the index withgit rm --cachedbefore continuing. - Every generated file carries a structured
[ai-canon:owned]marker. Files at managed destinations (including skills, scripts, and root agent configs) are overwritten only when that marker or a legacy 0.1 marker proves ownership. Otherwise, sync refuses before changing anything. Override deliberately with--force. - Stale skills are removed only when ownership is proven (legacy 0.1 files additionally require the current namespace prefix). Stale owned scripts are cleaned only under
.ai/scripts/. - Manifest paths are confined to their canon directories, and generated destinations are confined to the consumer repo. Absolute paths, traversal, backslashes, and escaping symlinks are rejected.
- MCP servers with unresolved
${VAR}placeholders are skipped and reported, never written. - Secret-bearing root MCP files are mode
0600on POSIX. Git URLs are redacted in errors and lockfiles, but credentials should come from your Git credential manager rather than being embedded in URLs. - Sync validates and plans the whole operation before writing. Guard conflicts make no changes; a later filesystem failure rolls the entire plan back, and individual file replacement is atomic.
Local canon development
AI_CANON_SOURCE=../our-ai-canon npx ai-canon sync --no-interactive # use a local checkout
AI_CANON_REF=origin/my-branch npx ai-canon sync # test a canon branch
.ai.lock.json records which canon commit/content generated the current files (audit only).
Recovery and rollback
- Preview drift without changing files:
npx ai-canon doctor --check. - Inspect the configured source, manifest, pending changes, removals, and conflicts:
npx ai-canon doctor. - Roll back by setting
canonRefin.ai.yamlto a known tag or commit, then runnpx ai-canon sync --no-interactive. - Return to the remote default branch by removing
canonRefand syncing again. - If a generated root config was intentionally replaced by hand-authored content, sync stops before modifying anything. Move personal MCP entries to
.ai.local/mcp.json, or review the replacement and use--forceonce. - If
.ai/.canonis damaged, remove only that gitignored cache directory and sync again. ai-canon also replaces it automatically when the configured canon URL changes.
doctor --check reports writes, updates, removals, conflicts, and lockfile drift, and exits 1 whenever the next sync would change local state.
Development
pnpm install
pnpm check # typecheck
pnpm test # e2e CLI tests
pnpm build # bundle dist/cli.mjs
Releasing
Maintainers configure the repository's NPM_TOKEN secret once, bump package.json, update CHANGELOG.md, and push a matching v tag. The release workflow reruns checks, publishes with npm provenance, and creates GitHub release notes. A mismatched tag fails before publishing.
License
MIT
Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: lucastraba
- Source: lucastraba/ai-canon
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.