@contentrain/mcp 0.3.1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +147 -238
  3. package/dist/apply-manager-CaTuu7Lj.mjs +751 -0
  4. package/dist/apply-manager-CaTuu7Lj.mjs.map +1 -0
  5. package/dist/astro-parser-RofKmKQi.mjs +166 -0
  6. package/dist/astro-parser-RofKmKQi.mjs.map +1 -0
  7. package/dist/branch-lifecycle-DB6sgeJi.mjs +97 -0
  8. package/dist/branch-lifecycle-DB6sgeJi.mjs.map +1 -0
  9. package/dist/chunk-BEJ448es.mjs +35 -0
  10. package/dist/compiler-rIC4ETHv.mjs +44509 -0
  11. package/dist/compiler-rIC4ETHv.mjs.map +1 -0
  12. package/dist/compiler-sfc.cjs-BbD04rn_.mjs +50279 -0
  13. package/dist/compiler-sfc.cjs-BbD04rn_.mjs.map +1 -0
  14. package/dist/config-CPlhDwsv.mjs +27 -0
  15. package/dist/config-CPlhDwsv.mjs.map +1 -0
  16. package/dist/context-yh3cuw5N.mjs +46 -0
  17. package/dist/context-yh3cuw5N.mjs.map +1 -0
  18. package/dist/core/apply-manager.d.mts +144 -0
  19. package/dist/core/apply-manager.d.mts.map +1 -0
  20. package/dist/core/apply-manager.mjs +6 -0
  21. package/dist/core/config.d.mts +8 -0
  22. package/dist/core/config.d.mts.map +1 -0
  23. package/dist/core/config.mjs +2 -0
  24. package/dist/core/content-manager.d.mts +53 -0
  25. package/dist/core/content-manager.d.mts.map +1 -0
  26. package/dist/core/content-manager.mjs +2 -0
  27. package/dist/core/context.d.mts +13 -0
  28. package/dist/core/context.d.mts.map +1 -0
  29. package/dist/core/context.mjs +3 -0
  30. package/dist/core/graph-builder.d.mts +12 -0
  31. package/dist/core/graph-builder.d.mts.map +1 -0
  32. package/dist/core/graph-builder.mjs +2 -0
  33. package/dist/core/meta-manager.d.mts +14 -0
  34. package/dist/core/meta-manager.d.mts.map +1 -0
  35. package/dist/core/meta-manager.mjs +2 -0
  36. package/dist/core/model-manager.d.mts +44 -0
  37. package/dist/core/model-manager.d.mts.map +1 -0
  38. package/dist/core/model-manager.mjs +2 -0
  39. package/dist/core/scan-config.d.mts +24 -0
  40. package/dist/core/scan-config.d.mts.map +1 -0
  41. package/dist/core/scan-config.mjs +2 -0
  42. package/dist/core/scanner.d.mts +25 -0
  43. package/dist/core/scanner.d.mts.map +1 -0
  44. package/dist/core/scanner.mjs +3 -0
  45. package/dist/core/validator.d.mts +23 -0
  46. package/dist/core/validator.d.mts.map +1 -0
  47. package/dist/core/validator.mjs +3 -0
  48. package/dist/detect-C8XmJ4S6.mjs +362 -0
  49. package/dist/detect-C8XmJ4S6.mjs.map +1 -0
  50. package/dist/fs-BbuGnVcG.mjs +52 -0
  51. package/dist/fs-BbuGnVcG.mjs.map +1 -0
  52. package/dist/git/branch-lifecycle.d.mts +28 -0
  53. package/dist/git/branch-lifecycle.d.mts.map +1 -0
  54. package/dist/git/branch-lifecycle.mjs +2 -0
  55. package/dist/git/transaction.d.mts +25 -0
  56. package/dist/git/transaction.d.mts.map +1 -0
  57. package/dist/git/transaction.mjs +4 -0
  58. package/dist/graph-builder-fPrDDwnu.mjs +162 -0
  59. package/dist/graph-builder-fPrDDwnu.mjs.map +1 -0
  60. package/dist/id-BdD4HvMY.mjs +12 -0
  61. package/dist/id-BdD4HvMY.mjs.map +1 -0
  62. package/dist/index.d.mts +1 -359
  63. package/dist/index.mjs +15 -2161
  64. package/dist/index.mjs.map +1 -1
  65. package/dist/meta-manager-CECrfsKm.mjs +53 -0
  66. package/dist/meta-manager-CECrfsKm.mjs.map +1 -0
  67. package/dist/model-manager-BcWWu5l2.mjs +963 -0
  68. package/dist/model-manager-BcWWu5l2.mjs.map +1 -0
  69. package/dist/node-Cbq5eR5i.mjs +300 -0
  70. package/dist/node-Cbq5eR5i.mjs.map +1 -0
  71. package/dist/scan-config-AJGxCdNd.mjs +159 -0
  72. package/dist/scan-config-AJGxCdNd.mjs.map +1 -0
  73. package/dist/scanner-BdTiv8sw.mjs +619 -0
  74. package/dist/scanner-BdTiv8sw.mjs.map +1 -0
  75. package/dist/serializer-Dueih-i2.mjs +33 -0
  76. package/dist/serializer-Dueih-i2.mjs.map +1 -0
  77. package/dist/server-CTcDpxwW.mjs +1861 -0
  78. package/dist/server-CTcDpxwW.mjs.map +1 -0
  79. package/dist/server.d.mts +7 -0
  80. package/dist/server.d.mts.map +1 -0
  81. package/dist/server.mjs +11 -0
  82. package/dist/source-map-generator-DpO-ejrt.mjs +893 -0
  83. package/dist/source-map-generator-DpO-ejrt.mjs.map +1 -0
  84. package/dist/svelte-parser-COTNG92w.mjs +225 -0
  85. package/dist/svelte-parser-COTNG92w.mjs.map +1 -0
  86. package/dist/templates/index.d.mts +8 -0
  87. package/dist/templates/index.d.mts.map +1 -0
  88. package/dist/templates/index.mjs +2 -0
  89. package/dist/templates-3HWi-PTu.mjs +824 -0
  90. package/dist/templates-3HWi-PTu.mjs.map +1 -0
  91. package/dist/transaction-BsECnmL5.mjs +128 -0
  92. package/dist/transaction-BsECnmL5.mjs.map +1 -0
  93. package/dist/tsx-parser-Bf8Firrq.mjs +2 -0
  94. package/dist/tsx-parser-CYVyBWjn.mjs +234 -0
  95. package/dist/tsx-parser-CYVyBWjn.mjs.map +1 -0
  96. package/dist/util/detect.d.mts +20 -0
  97. package/dist/util/detect.d.mts.map +1 -0
  98. package/dist/util/detect.mjs +2 -0
  99. package/dist/util/fs.d.mts +12 -0
  100. package/dist/util/fs.d.mts.map +1 -0
  101. package/dist/util/fs.mjs +2 -0
  102. package/dist/util/id.d.mts +6 -0
  103. package/dist/util/id.d.mts.map +1 -0
  104. package/dist/util/id.mjs +2 -0
  105. package/dist/util/serializer.d.mts +14 -0
  106. package/dist/util/serializer.d.mts.map +1 -0
  107. package/dist/util/serializer.mjs +2 -0
  108. package/dist/validator-ku84AyFr.mjs +755 -0
  109. package/dist/validator-ku84AyFr.mjs.map +1 -0
  110. package/dist/vue-parser-CjS4YAoQ.mjs +225 -0
  111. package/dist/vue-parser-CjS4YAoQ.mjs.map +1 -0
  112. package/package.json +107 -43
  113. package/dist/fs-D83-Ii_y.mjs +0 -75
  114. package/dist/fs-D83-Ii_y.mjs.map +0 -1
  115. package/dist/index.d.mts.map +0 -1
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2024 Contentrain
3
+ Copyright (c) 2026 Contentrain
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,282 +1,191 @@
1
- # @contentrain/mcp
1
+ # `@contentrain/mcp`
2
2
 
3
- MCP (Model Context Protocol) server for [Contentrain](https://contentrain.io) CMS content management. Enables AI agents (Claude, Codex, Cursor, etc.) and humans to create, read, update, and delete Contentrain models, content, and assets — with automatic git branch synchronization.
3
+ Local-first MCP server and core primitives for Contentrain.
4
4
 
5
- ## Why?
5
+ Contentrain is AI-generated content governance infrastructure:
6
6
 
7
- Contentrain is a git-based headless CMS. This MCP server lets AI assistants directly manage your Contentrain content through a standardized protocol, so you can say things like:
7
+ - agent produces content decisions
8
+ - MCP applies deterministic filesystem and git workflow
9
+ - humans review and merge
10
+ - the system keeps schema, locale, and serialization consistent
8
11
 
9
- - *"Create a blog post model with title, excerpt, and cover image fields"*
10
- - *"Add a new blog post in English and Turkish"*
11
- - *"List all FAQ entries and update the second one"*
12
+ This package is the runtime core behind Contentrain's MCP integration. It can be used as:
12
13
 
13
- All changes are committed and pushed to your git repository automatically.
14
+ - a stdio MCP server (`contentrain-mcp`)
15
+ - an embeddable server (`createServer(projectRoot)`)
16
+ - a low-level toolkit for config, models, content, validation, scanning, and git transaction flow
14
17
 
15
- ## Prerequisites
18
+ ## 🚀 Install
16
19
 
17
- - A Contentrain project already set up via the [Contentrain Web App](https://app.contentrain.io)
18
- - The project's GitHub repository cloned locally
19
- - Node.js >= 18
20
+ ```bash
21
+ pnpm add @contentrain/mcp
22
+ ```
20
23
 
21
- > **Important:** Contentrain projects must be initialized through the Web App first. The Web App creates the repository structure, the `contentrain` branch, models, and environment configuration. This MCP server operates on an existing Contentrain project — it does not replace the initial setup.
24
+ Requirements:
22
25
 
23
- ## Quick Start
26
+ - Node.js `22+`
27
+ - git available on the machine
24
28
 
25
- ### 1. Install
29
+ Optional parser support for higher-quality source scanning:
26
30
 
27
- ```bash
28
- # From npm (when published)
29
- npm install -g @contentrain/mcp
31
+ - `@vue/compiler-sfc`
32
+ - `@astrojs/compiler`
33
+ - `svelte`
30
34
 
31
- # Or from source
32
- git clone https://github.com/Contentrain/contentrain-mcp.git
33
- cd contentrain-mcp
34
- pnpm install && pnpm build
35
- ```
35
+ They are listed as optional dependencies. The scanner still works without them, but Vue/Astro/Svelte detection is stronger when they are installed.
36
36
 
37
- ### 2. Configure your MCP client
37
+ ## ✨ What It Does
38
38
 
39
- Add to your MCP client configuration:
39
+ `@contentrain/mcp` manages a `.contentrain/` directory in your project and exposes MCP tools for:
40
40
 
41
- **Claude Desktop** (`~/Library/Application Support/Claude/claude_desktop_config.json`):
41
+ - project initialization
42
+ - model creation and deletion
43
+ - content save, delete, and list
44
+ - validation and auto-fix
45
+ - normalize scan and apply flows
46
+ - bulk operations
47
+ - branch submission and branch-health awareness
42
48
 
43
- ```json
44
- {
45
- "mcpServers": {
46
- "contentrain": {
47
- "command": "contentrain-mcp",
48
- "env": {
49
- "CONTENTRAIN_REPO_PATH": "/path/to/your/contentrain-project",
50
- "CONTENTRAIN_BRANCH": "contentrain"
51
- }
52
- }
53
- }
54
- }
55
- ```
49
+ All write operations are designed around git-backed safety:
56
50
 
57
- **Cursor** (`.cursor/mcp.json` in your project root):
58
-
59
- ```json
60
- {
61
- "mcpServers": {
62
- "contentrain": {
63
- "command": "contentrain-mcp",
64
- "env": {
65
- "CONTENTRAIN_REPO_PATH": "/path/to/your/contentrain-project",
66
- "CONTENTRAIN_BRANCH": "contentrain"
67
- }
68
- }
69
- }
70
- }
71
- ```
51
+ - write to a dedicated `contentrain/*` branch
52
+ - keep canonical JSON output
53
+ - update `.contentrain/context.json`
54
+ - surface validation and next-step hints to the caller
72
55
 
73
- **Claude Code** (`.mcp.json` in your project root):
74
-
75
- ```json
76
- {
77
- "mcpServers": {
78
- "contentrain": {
79
- "command": "contentrain-mcp",
80
- "env": {
81
- "CONTENTRAIN_REPO_PATH": "/path/to/your/contentrain-project",
82
- "CONTENTRAIN_BRANCH": "contentrain"
83
- }
84
- }
85
- }
86
- }
87
- ```
56
+ ## 🧰 Tool Surface
88
57
 
89
- > If installed from source instead of globally, replace `"command": "contentrain-mcp"` with `"command": "node"` and add `"args": ["/absolute/path/to/contentrain-mcp/dist/index.mjs"]`.
58
+ Current MCP tools exposed by the server:
90
59
 
91
- ### 3. Start using
60
+ | Tool | Purpose |
61
+ | --- | --- |
62
+ | `contentrain_status` | Project status, config, models, branch health, context |
63
+ | `contentrain_describe` | Full schema and sample data for a model |
64
+ | `contentrain_describe_format` | File-format and storage contract reference |
65
+ | `contentrain_init` | Create `.contentrain/` structure and base config |
66
+ | `contentrain_scaffold` | Apply a starter template such as blog, docs, landing, saas |
67
+ | `contentrain_model_save` | Create or update a model definition |
68
+ | `contentrain_model_delete` | Delete a model definition |
69
+ | `contentrain_content_save` | Save content entries for any model kind |
70
+ | `contentrain_content_delete` | Delete content entries |
71
+ | `contentrain_content_list` | Read content entries |
72
+ | `contentrain_validate` | Validate project content, optionally auto-fix structural issues |
73
+ | `contentrain_submit` | Push `contentrain/*` branches to remote |
74
+ | `contentrain_scan` | Graph- and candidate-based hardcoded string scan |
75
+ | `contentrain_apply` | Normalize extract/reuse execution with dry-run support |
76
+ | `contentrain_bulk` | Bulk locale copy, status updates, and deletes |
92
77
 
93
- Once configured, your AI assistant has access to 17 tools. Here's an example conversation:
78
+ ## 🚀 Quick Start
94
79
 
80
+ ### Run as an MCP server
81
+
82
+ ```bash
83
+ CONTENTRAIN_PROJECT_ROOT=/path/to/project npx contentrain-mcp
95
84
  ```
96
- You: List all my models
97
- Agent: → calls contentrain_list_models
98
- You have 3 models: blog (MD, localized), faq (JSON), authors (JSON)
99
-
100
- You: Show me the blog model schema
101
- Agent: → calls contentrain_describe_model { modelId: "blog" }
102
- Blog model has fields: title (string, required), description (string),
103
- category (one-to-one → blogcategories), imagesrc (media), author (one-to-one → authors)
104
-
105
- You: Create a new blog post titled "Getting Started with Contentrain"
106
- Agent: → calls contentrain_create_content {
107
- modelId: "blog",
108
- data: { title: "Getting Started with Contentrain", slug: "getting-started-with-contentrain", description: "..." },
109
- locale: "en",
110
- status: "draft",
111
- content: "# Getting Started\n\nWelcome to Contentrain..."
112
- }
113
- Created entry e7f3a1b9c0d2 in blog model (draft).
114
- Committed and pushed to contentrain branch.
115
-
116
- You: Now publish it
117
- Agent: → calls contentrain_update_content {
118
- modelId: "blog",
119
- entryId: "e7f3a1b9c0d2",
120
- data: { status: "publish" },
121
- locale: "en"
122
- }
123
- Updated and published.
85
+
86
+ If `CONTENTRAIN_PROJECT_ROOT` is omitted, the current working directory is used.
87
+
88
+ ### Embed the server in your own process
89
+
90
+ ```ts
91
+ import { createServer } from '@contentrain/mcp/server'
92
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
93
+
94
+ const server = createServer(process.cwd())
95
+ const transport = new StdioServerTransport()
96
+
97
+ await server.connect(transport)
124
98
  ```
125
99
 
126
- ## Environments
100
+ ## 🔄 Example MCP Flow
127
101
 
128
- Contentrain uses **git branches** to manage environments. Each environment maps to a branch:
102
+ Typical agent workflow:
129
103
 
130
- | Environment | Branch | Description |
131
- |-------------|--------|-------------|
132
- | Default | `contentrain` | Main content branch (created automatically) |
133
- | Staging | `contentrain-staging` | Preview/staging environment |
134
- | Production | `contentrain-production` | Production environment |
104
+ 1. Call `contentrain_status`
105
+ 2. If needed, call `contentrain_init`
106
+ 3. Create models with `contentrain_model_save` or `contentrain_scaffold`
107
+ 4. Save content with `contentrain_content_save`
108
+ 5. Validate with `contentrain_validate`
109
+ 6. For hardcoded strings, use `contentrain_scan` then `contentrain_apply`
110
+ 7. Push review branches with `contentrain_submit`
135
111
 
136
- Environments are created via the Contentrain Web App. The branch naming follows the pattern `contentrain-{environment-name}`.
112
+ ## 🧪 Normalize Flow
137
113
 
138
- ### Targeting a specific environment
114
+ Normalize is intentionally split into two phases:
139
115
 
140
- Set the `CONTENTRAIN_BRANCH` environment variable to the target environment's branch:
116
+ ### 1. Extract
141
117
 
142
- ```json
143
- {
144
- "mcpServers": {
145
- "contentrain": {
146
- "command": "contentrain-mcp",
147
- "env": {
148
- "CONTENTRAIN_REPO_PATH": "/path/to/project",
149
- "CONTENTRAIN_BRANCH": "contentrain-staging"
150
- }
151
- }
152
- }
153
- }
154
- ```
118
+ `contentrain_scan` finds candidate strings.
155
119
 
156
- ### Multiple environments simultaneously
157
-
158
- You can register multiple MCP server instances — one per environment:
159
-
160
- ```json
161
- {
162
- "mcpServers": {
163
- "contentrain-default": {
164
- "command": "contentrain-mcp",
165
- "env": {
166
- "CONTENTRAIN_REPO_PATH": "/path/to/project",
167
- "CONTENTRAIN_BRANCH": "contentrain"
168
- }
169
- },
170
- "contentrain-staging": {
171
- "command": "contentrain-mcp",
172
- "env": {
173
- "CONTENTRAIN_REPO_PATH": "/path/to/project",
174
- "CONTENTRAIN_BRANCH": "contentrain-staging"
175
- }
176
- }
177
- }
178
- }
179
- ```
120
+ `contentrain_apply` with `mode: "extract"`:
180
121
 
181
- ## Available Tools
182
-
183
- ### Model Management
184
-
185
- | Tool | Description |
186
- |------|-------------|
187
- | `contentrain_list_models` | List all models with metadata |
188
- | `contentrain_describe_model` | Get full schema with field definitions |
189
- | `contentrain_create_model` | Create a new model (JSON, MD, or MDX) |
190
- | `contentrain_add_field` | Add a field to an existing model |
191
- | `contentrain_delete_model` | Delete a model and all its content |
192
-
193
- ### Content Management
194
-
195
- | Tool | Description |
196
- |------|-------------|
197
- | `contentrain_list_content` | List all entries for a model |
198
- | `contentrain_get_content` | Get a single entry by ID |
199
- | `contentrain_create_content` | Create a new entry with validation |
200
- | `contentrain_update_content` | Update specific fields of an entry |
201
- | `contentrain_delete_content` | Delete an entry (all locales + markdown) |
202
- | `contentrain_validate` | Dry-run validation against model schema |
203
-
204
- ### Asset Management
205
-
206
- | Tool | Description |
207
- |------|-------------|
208
- | `contentrain_list_assets` | List all registered assets |
209
- | `contentrain_register_asset` | Register an existing file as an asset |
210
- | `contentrain_deregister_asset` | Remove an asset from the registry |
211
-
212
- ### Diagnostics
213
-
214
- | Tool | Description |
215
- |------|-------------|
216
- | `contentrain_doctor` | Full diagnostic scan — detects ID, schema, relation, asset, and sync issues. Use `fix=true` to auto-repair (pushes to a staging branch for review). |
217
- | `contentrain_doctor_apply` | Merge a staged doctor fix into the target branch |
218
- | `contentrain_doctor_discard` | Discard a staged doctor fix without merging |
219
-
220
- ## Environment Variables
221
-
222
- | Variable | Default | Description |
223
- |----------|---------|-------------|
224
- | `CONTENTRAIN_REPO_PATH` | `process.cwd()` | Path to the git repository |
225
- | `CONTENTRAIN_BRANCH` | `contentrain` | Target environment branch |
226
- | `CONTENTRAIN_REMOTE` | `origin` | Git remote name |
227
- | `CONTENTRAIN_DIR` | `contentrain` | Contentrain directory name |
228
- | `CONTENTRAIN_DRY_RUN` | `false` | Skip git operations (local changes only) |
229
- | `CONTENTRAIN_AUTHOR_NAME` | — | Git commit author name |
230
- | `CONTENTRAIN_AUTHOR_EMAIL` | — | Git commit author email |
231
-
232
- ## Programmatic Usage
233
-
234
- You can also use the writer directly in your own code:
235
-
236
- ```typescript
237
- import { ContentrainWriter } from '@contentrain/mcp'
238
-
239
- const writer = new ContentrainWriter({
240
- repoPath: '/path/to/your/project',
241
- branch: 'contentrain',
242
- })
243
-
244
- // Read operations (no git transaction needed)
245
- const models = await writer.model.list()
246
- const entries = await writer.content.list('blog-posts')
247
-
248
- // Write operations (uses git worktree + commit + push)
249
- await writer.transaction(async (tx) => {
250
- await tx.content.create('blog-posts', {
251
- title: 'Hello World',
252
- excerpt: 'My first post',
253
- }, { status: 'draft' })
254
- }, { message: 'add new blog post' })
255
- ```
122
+ - creates or updates models
123
+ - writes content entries
124
+ - records source tracking
125
+ - creates a review branch
126
+
127
+ ### 2. Reuse
128
+
129
+ `contentrain_apply` with `mode: "reuse"`:
130
+
131
+ - patches source files using agent-provided expressions
132
+ - adds imports when needed
133
+ - enforces patch path safety and scope checks
134
+ - creates a separate review branch
135
+
136
+ This split keeps content extraction separate from source rewriting.
256
137
 
257
- ## How Git Sync Works
138
+ ## 📦 Core Exports
258
139
 
259
- Every write operation runs inside a **transaction**:
140
+ The package also exposes low-level modules for embedding and advanced use:
260
141
 
261
- 1. Creates an isolated git worktree from the target branch
262
- 2. Applies all changes inside the worktree
263
- 3. Commits and pushes to the target branch
264
- 4. If the push is rejected (remote advanced), performs a **structural 3-way merge** — diffing JSON entries by their `ID` field instead of text lines — then retries (up to 3 attempts)
265
- 5. Cleans up the worktree
142
+ - `@contentrain/mcp/server`
143
+ - `@contentrain/mcp/core/config`
144
+ - `@contentrain/mcp/core/context`
145
+ - `@contentrain/mcp/core/model-manager`
146
+ - `@contentrain/mcp/core/content-manager`
147
+ - `@contentrain/mcp/core/validator`
148
+ - `@contentrain/mcp/core/scanner`
149
+ - `@contentrain/mcp/core/graph-builder`
150
+ - `@contentrain/mcp/core/apply-manager`
151
+ - `@contentrain/mcp/util/detect`
152
+ - `@contentrain/mcp/util/fs`
153
+ - `@contentrain/mcp/git/transaction`
154
+ - `@contentrain/mcp/git/branch-lifecycle`
155
+ - `@contentrain/mcp/templates`
266
156
 
267
- This means concurrent writes from multiple agents or the Contentrain web app won't conflict.
157
+ These are intended for Contentrain tooling and advanced integrations, not for direct manual editing of `.contentrain/` files.
268
158
 
269
- ## Development
159
+ ## 🧠 Design Constraints
160
+
161
+ Key design decisions in this package:
162
+
163
+ - local-first, filesystem-based MCP
164
+ - no GitHub API dependency in MCP
165
+ - JSON-only content storage
166
+ - git-backed write workflow
167
+ - canonical serialization
168
+ - framework-agnostic MCP layer
169
+ - agent decides content semantics, MCP enforces deterministic execution
170
+
171
+ ## 🛠 Development
172
+
173
+ From the monorepo root:
270
174
 
271
175
  ```bash
272
- pnpm install # Install dependencies
273
- pnpm dev # Watch mode build
274
- pnpm test # Run tests (watch mode)
275
- pnpm test:run # Run tests once
276
- pnpm lint # Lint with oxlint
277
- pnpm build # Production build
176
+ pnpm --filter @contentrain/mcp build
177
+ pnpm --filter @contentrain/mcp test
178
+ pnpm --filter @contentrain/mcp typecheck
179
+ pnpm exec oxlint packages/mcp/src packages/mcp/tests
278
180
  ```
279
181
 
280
- ## License
182
+ ## 🔗 Related Packages
183
+
184
+ - `contentrain` — CLI and local review tooling
185
+ - `@contentrain/query` — generated runtime query SDK
186
+ - `@contentrain/rules` — IDE/agent rules and prompts
187
+ - `@contentrain/types` — shared schema and model types
188
+
189
+ ## 📄 License
281
190
 
282
191
  MIT