A config-driven, pluggable knowledge compiler. Madrigal transforms structured knowledge (markdown files with frontmatter) into normalized, schema-aware output formats - JSON bundles, AI skill files, rule sets, and more.
Inspired by Style Dictionary, Madrigal applies the same "define once, compile everywhere" philosophy to knowledge bases, research repositories, coding guidelines, design systems, and organizational rules. Consumers own the domain vocabulary; Madrigal owns reliable parsing, normalization, linting, and compilation.
npm install @anarchitecture/madrigalCreate a madrigal.config.yaml:
sources:
- "knowledge/**/*.md"
schema:
preserveUnknownFrontmatter: true
id:
field: id
strategy: path
kind:
field: type
default: record
byPath:
"knowledge/studies/**": study
title:
field: title
relationships:
wikilinks: true
kinds:
study:
required: [title, methodology, research_period, source_url]
theme: {}
vocabularies:
durability:
values: [evergreen, timebound]
platforms:
json-export:
format: json-bundleCreate a knowledge file at knowledge/studies/checkout-trust.md:
---
title: Checkout Trust Study
type: study
methodology: Interviews
research_period: Q1
source_url: https://example.com/research
durability: evergreen
tags:
- onboarding
---
Participants connected onboarding clarity to [[Trust Signals]].Build programmatically:
import { build } from '@anarchitecture/madrigal';
const result = await build();
for (const output of result.results) {
console.log(`${output.platform}: ${output.unitCount} units`);
console.log(output.output);
}The atomic unit. Each .md file with frontmatter becomes a normalized KnowledgeUnit with an id, title, body, kind, tags, source path, raw frontmatter, normalized attributes, extracted relationships, and provenance tracking. Optional rule-oriented fields such as domain, brand, system, and enforcement are preserved when present.
Consumer-owned mapping rules that tell Madrigal how to read a knowledge base: where IDs, titles, kinds, and relationships come from, how path-based fallback should work, and whether unknown frontmatter should be preserved.
Consumer-defined structural types (for example study, theme, competitor, or rule). Kinds can declare required fields for linting and strict validation.
Consumer-owned controlled terms and aliases. Madrigal can canonicalize configured fields in attributes while preserving the raw parsed value in frontmatter.
Optional logical groupings of knowledge (e.g., accessibility, typography, layout). Defined in config and validated at load time when present.
Organizational units that can inherit from each other. A brand can include other brands/groups, and brand-specific knowledge overrides globals with the same id.
Optional rule-oriented strength: must, should, may, context, or deprecated. Existing severity frontmatter is still accepted as a legacy alias for rule-focused workflows.
Output compilers that transform knowledge units into specific formats. Four built-in formats are included:
| Format | Description |
|---|---|
json-bundle |
Searchable JSON with metadata |
skill-md |
Markdown skill file for AI agents |
ai-rules-md |
Rule file for AI coding assistants |
mesh-domain |
AI app-info mesh domain format |
Named build targets in config. Each platform specifies a format and optional grouping (brand, domain, or system).
# Glob patterns for knowledge source files
sources:
- "knowledge/**/*.md"
# Schema mapping and normalization
schema:
preserveUnknownFrontmatter: true
id:
field: id # Explicit frontmatter ID field
strategy: path # path | filename
kind:
field: type # Frontmatter field used as the unit kind
default: record
byPath:
"knowledge/studies/**": study
title:
field: title
relationships:
wikilinks: true # Extract [[Target]] and [[Target|Label]]
# Kind definitions and required fields
kinds:
<name>:
required:
- title
# Controlled vocabularies and aliases
vocabularies:
<field>:
values:
- canonical-value
aliases:
old-value: canonical-value
# Domain definitions
domains:
<name>:
description: "..."
# Brand definitions
brands:
<name>:
systems: # Optional: associated design systems
- web
include: # Optional: inherit from other brands
- global
# Build targets
platforms:
<name>:
format: json-bundle # Required: registered format name
groupBy: brand # Optional: brand | domain | system
destination: out/ # Optional: output path---
title: Record Title # Field name is configurable
id: custom-id # Optional, generated from path by default
type: study # Field name is configurable
source_url: https://example.com/source
durability: evergreen # Consumer-owned attribute
enforcement: should # Optional for rule-oriented records
tags:
- research
---
Markdown body content here, including optional [[Wiki Links]].import { defaultRegistry, type Format } from '@anarchitecture/madrigal';
const myFormat: Format = {
name: 'custom-html',
extension: '.html',
compile(units, options) {
return `<html>...</html>`;
},
};
defaultRegistry.register(myFormat);Preprocessors transform knowledge units after loading but before compilation:
import { defaultPreprocessorRegistry, type Preprocessor } from '@anarchitecture/madrigal';
const enricher: Preprocessor = {
name: 'tag-enricher',
async process(units, config) {
return units.map(u => ({
...u,
tags: [...u.tags, 'enriched'],
}));
},
};
defaultPreprocessorRegistry.register(enricher);Madrigal exports StorageAdapter and SearchAdapter interfaces for implementing custom backends (databases, vector stores, etc.).
Run the full pipeline: load config, load knowledge, run preprocessors, compile all platforms.
Load and parse a madrigal.config.yaml file.
Load knowledge units from markdown files matching source globs.
Resolve knowledge units for a specific brand, applying inheritance and severity overrides.
Validate a configuration object.
Start a stdio MCP server that exposes five tools for querying the knowledge base:
search_knowledge, get_knowledge_unit, list_knowledge_units, get_brand_rules, review_content.
import { serveMcp } from '@anarchitecture/madrigal';
import { dirname, resolve } from 'node:path';
import { fileURLToPath } from 'node:url';
const baseDir = dirname(fileURLToPath(import.meta.url));
// Single bundle
await serveMcp({ baseDir, bundlePath: 'publish/to-artifactory/knowledge.json' });
// Multiple bundles merged into one index (for aggregator repos)
await serveMcp({
baseDir,
bundlePath: 'publish/to-artifactory/knowledge.json',
bundlePaths: [
resolve(baseDir, '../other-repo/publish/to-artifactory/knowledge.json'),
],
});Save this as mcp-server.js at the repo root and register it in your MCP client config.
Repos that use Madrigal should own their agent skills alongside their knowledge. Skills live in skills/{skill-name}/SKILL.md — always a named subdirectory, never at the repo root. This mirrors the local install path (~/.claude/skills/{name}/SKILL.md) so publishing is mechanical.
Single-skill repo:
skills/
my-knowledge-base/
SKILL.md
Multi-skill repo (e.g. one skill per brand or design system):
skills/
arcade/
SKILL.md
market/
SKILL.md
Skill files reference the MCP tools (search_knowledge, etc.) with domain-specific routing instructions. The repo team owns the skill — it is not generated by Madrigal.
To install a skill locally for development:
mkdir -p ~/.claude/skills/{skill-name}/
ln -sf "$(pwd)/skills/{skill-name}/SKILL.md" ~/.claude/skills/{skill-name}/SKILL.mdMadrigal uses Changesets for versioning.
For a release-bearing change, run:
pnpm changesetAfter the change lands on main, the Version Packages GitHub Actions
workflow creates a version PR when changesets are pending. Merging to main
does not publish Madrigal.
To publish a GitHub Release tarball, merge the version PR and push a matching tag:
VERSION=$(node -e "console.log(JSON.parse(require('fs').readFileSync('package.json', 'utf8')).version)")
git tag "anarchitecture-madrigal@$VERSION"
git push origin "anarchitecture-madrigal@$VERSION"The Publish tarball to GitHub Release workflow can also be run manually with
the package version from package.json.
Manual release commands are also available:
pnpm version-packages
pnpm release| Resource | Description |
|---|---|
| CODEOWNERS | Project lead(s) |
| GOVERNANCE.md | Project governance |
| LICENSE | Apache License, Version 2.0 |