Skip to content

Commit 69f1adf

Browse files
committed
Update docs
1 parent a6f27c1 commit 69f1adf

2 files changed

Lines changed: 161 additions & 21 deletions

File tree

docs/MCP.md

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -109,11 +109,35 @@ Saltus reuses WordPress capability checks such as:
109109
| Settings updates | `manage_options` |
110110
| Term creation | taxonomy edit/manage capability |
111111

112-
REST routes are also gated by model configuration. The master `show_in_rest` option acts as both the WordPress core registration gate and the Saltus REST gate. Each Saltus feature (meta, settings, duplicate, export, reorder) can be independently enabled or disabled using a `show_in_rest` flag in its own config section within the model's `config` key. The `models` and `health` capabilities are always enabled when `show_in_rest` is not false for that model (or always, for health).
112+
REST routes and MCP tools are gated by model configuration.
113113

114-
Similarly, MCP tools are gated by the `mcp_tools` master option at the model level, and each feature can be independently gated with `show_in_mcp` in its config section. When `mcp_tools` is absent or false, no MCP tools are generated for that model. When `mcp_tools` is true, all features are enabled for MCP unless a feature's `show_in_mcp` is explicitly `false`.
114+
### Master Options (Model Level)
115115

116-
Enable all Saltus REST-backed capabilities for a model:
116+
At the model level, two master options in the `options` array control access:
117+
- **`show_in_rest`**: Controls whether model-scoped REST routes (and consequently MCP tools) are registered. If explicitly set to `false`, all model-scoped REST and MCP capabilities for the model are disabled. Defaults to `true` (if omitted or not `false`).
118+
- **`mcp_tools`**: Must be set and truthy (e.g., `true`) in model options to enable any MCP tools for that model.
119+
120+
The framework-scoped health capability (`health` ability / REST route) is independent of per-model opt-in and is always available. The `models` capability is always enabled for a model as long as its `show_in_rest` is not `false` (or always, for MCP, if `mcp_tools` is enabled).
121+
122+
### Feature-Level Gating
123+
124+
Each individual framework capability can be gated in the model's `config` array. They map to specific configuration sections:
125+
- **Meta (`meta`):** `'meta'` key (root level of `config`)
126+
- **Settings (`settings`):** `'settings'` key (root level of `config`)
127+
- **Duplicate (`duplicate`):** `'duplicate'` key (nested under `config.features.duplicate`)
128+
- **Export (`export`):** `'single_export'` key (nested under `config.features.single_export`)
129+
- **Reorder (`reorder`):** `'drag_and_drop'` key (nested under `config.features.drag_and_drop`)
130+
131+
### Resolution Rules
132+
133+
For each feature/capability configuration section:
134+
1. **Omitted (Null):** If a capability config section is omitted from the model configuration, the feature defaults to **enabled** for both REST and MCP.
135+
2. **Boolean Value:** If defined as a simple boolean (e.g., `'meta' => false` or `'features' => ['duplicate' => false]`), it acts as a joint gate. A value of `false` disables both REST and MCP for that capability; a value of `true` enables both.
136+
3. **Array Value:** If defined as an array, REST and MCP gating can be configured independently:
137+
- **REST Route Gating:** Governed by the `show_in_rest` key in the section array. If the key is omitted, REST is **enabled** (`true`). If present, it resolves to its boolean value.
138+
- **MCP Tool Gating:** Governed by the `show_in_mcp` key in the section array. If the key is omitted, MCP is **enabled** (`true`). If present, it resolves to its boolean value.
139+
140+
Enable all Saltus REST-backed and MCP capabilities for a model:
117141

118142
```php
119143
return [
@@ -126,7 +150,7 @@ return [
126150
];
127151
```
128152

129-
Enable REST for all features but block MCP for specific features:
153+
Example showing various feature-level configurations:
130154

131155
```php
132156
return [
@@ -137,37 +161,28 @@ return [
137161
'mcp_tools' => true,
138162
],
139163
'config' => [
164+
// 1. Array style: enabled for REST but disabled for MCP
140165
'meta' => [
141166
'show_in_rest' => true,
142167
'show_in_mcp' => false,
143168
],
144-
'settings' => [
145-
'show_in_rest' => true,
146-
],
169+
// 2. Boolean style: disabled for both REST and MCP
170+
'settings' => false,
171+
147172
'features' => [
173+
// 3. Array style: enabled for REST, and defaults to enabled for MCP
148174
'duplicate' => [
149175
'show_in_rest' => true,
150176
],
151-
'single_export' => [
152-
'show_in_rest' => true,
153-
],
154-
'drag_and_drop' => [
155-
'show_in_rest' => true,
156-
],
177+
// 4. Omitted config for single_export and drag_and_drop:
178+
// both default to enabled for REST and MCP
157179
],
158180
],
159181
];
160182
```
161183

162184
If `show_in_rest` is explicitly `false`, Saltus does not expose model-scoped REST or MCP routes for that model. The health ability is framework-scoped and remains independent of per-model opt-in.
163185

164-
Config section keys:
165-
- `meta` — top-level key in `config`
166-
- `settings` — top-level key in `config`
167-
- `duplicate` — nested under `config.features.duplicate`
168-
- `single_export` — nested under `config.features.single_export`
169-
- `drag_and_drop` — nested under `config.features.drag_and_drop`
170-
171186
## Available Abilities
172187

173188
<!-- BEGIN AUTO-GENERATED MCP ABILITIES -->

docs/ROADMAP.md

Lines changed: 126 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
- PHPStan Level 7 clean across the configured analysis set as of 2026-07-02, including the asset loading helper path
1010
- MCP v1 refactoring complete: per-tool REST dispatch, RestBackedToolInterface, ToolContributor, @phpstan-type AbilityDefinition
1111
- MCP namespace/category/prefix now filterable via MCPConfig utility class (saltus/framework/mcp/namespace, saltus/framework/mcp/ability_category, saltus/framework/mcp/ability_prefix)
12-
- MCP/REST capability gating refactored: McpPolicy class with mcp_tools/show_in_mcp gating; ModelRestPolicy switched from saltus_rest array to per-feature config-section model (config.meta.show_in_rest)
12+
- MCP/REST capability gating refactored: McpPolicy class with mcp_tools/show_in_mcp gating; ModelRestPolicy switched from saltus_rest array to per-feature config-section model (using show_in_rest and show_in_mcp gates)
1313
- Legacy refactoring: inline REST controller logic extracted into shared service classes (SaltusSingleExport, MetaFieldProvider, ReorderPostsService, SettingsManager) wired into both REST controllers and MCP tools — resolved 2026-07-03
1414
- Conditional registration fix: `is_needed()` gate bypass for RestRouteProvider/ToolContributor registries via two-pass approach in `Core`, ensuring REST routes always appear in WP-REST index even before `REST_REQUEST` is defined — resolved 2026-07-06
1515
- 250 PHPUnit tests passing (669 assertions), PHPStan Level 7 clean across the configured analysis set
@@ -397,3 +397,128 @@ frontend:
397397
## Tracking
398398
- Check GitHub Issues for active sprint items.
399399
- Active development on `feature/mcp-v1` branch.
400+
401+
402+
403+
//// new
404+
• Current state: Saltus already has the “external agent connects to WordPress
405+
and modifies content through governed abilities” piece partly implemented.
406+
What it does not appear to have yet is a first-class “context control center”
407+
model or a mandatory editorial approval queue for agent writes.
408+
409+
────────────────────────────────────────────────────────────────────────────────
410+
411+
• For Saltus, that translates less like “Drupal AI” and more like a WordPress-
412+
native AI governance layer for CPT-driven plugins.
413+
414+
Saltus already has the foundation: model-defined CPTs, REST routes, MCP/
415+
Abilities tools, capability checks, audit logging, rate limits, health checks,
416+
and per-model mcp_tools / show_in_mcp gates. The missing higher-level product
417+
layer would be this:
418+
419+
Context Control Center
420+
421+
A Saltus model/config area where a plugin defines:
422+
423+
- brand voice
424+
- field-level writing rules
425+
- audience profiles
426+
- taxonomy/content standards
427+
- allowed statuses
428+
- forbidden actions
429+
- required review rules
430+
- per-CPT AI instructions
431+
432+
In Saltus terms, this could live as model config, for example:
433+
434+
'options' => [
435+
'show_in_rest' => true,
436+
'mcp_tools' => true,
437+
],
438+
'config' => [
439+
'ai_context' => [
440+
'brand_voice' => 'Clear, practical, expert, no hype.',
441+
'audiences' => ['developers', 'site editors'],
442+
'rules' => [
443+
'never_publish_directly' => true,
444+
'require_human_review' => true,
445+
'preserve_technical_accuracy' => true,
446+
],
447+
],
448+
]
449+
450+
Then MCP tools like create_post, update_post, update_settings, and
451+
update_meta_fields would receive this context before executing or expose it
452+
through a new tool like saltus/get-context.
453+
454+
Inside AI
455+
456+
This would mean AI operating from inside WordPress admin.
457+
458+
Examples:
459+
460+
- AI buttons beside metabox fields
461+
- “Improve title”
462+
- “Summarize this CPT entry”
463+
- “Generate excerpt from meta”
464+
- “Validate against brand rules”
465+
- “Suggest taxonomy terms”
466+
- “Prepare draft update”
467+
468+
The key point: inside AI would still use Saltus models and WordPress
469+
permissions. It should not bypass CPT config, field schemas, validation, or
470+
post status rules.
471+
472+
Outside AI
473+
474+
This maps directly to Saltus MCP/Abilities.
475+
476+
External agents such as Codex, Claude Desktop, Cursor, or custom automation
477+
clients connect to WordPress and call:
478+
479+
- saltus/list-models
480+
- saltus/get-model
481+
- saltus/list-posts
482+
- saltus/get-post
483+
- saltus/create-post
484+
- saltus/update-post
485+
- saltus/update-settings
486+
- saltus/get-meta-fields
487+
488+
Saltus already has this architectural direction. The next step would be adding
489+
stronger editorial governance around mutating tools.
490+
491+
Editorial Review
492+
493+
Right now, agent writes can be permission-gated and audited. To match the idea
494+
you quoted, Saltus would need an approval layer:
495+
496+
- agent proposes a change
497+
- Saltus stores it as a draft, revision, or pending change record
498+
- human editor reviews diff
499+
- editor approves, rejects, or edits
500+
- only approved changes are published
501+
- audit log records the full chain
502+
503+
Practically, mutating MCP tools should default to:
504+
505+
AI write -> draft/pending/revision -> human approval -> publish
506+
507+
Not:
508+
509+
AI write -> publish
510+
511+
Best Saltus framing
512+
513+
I’d describe it as:
514+
515+
> Saltus can become the governance layer for AI-operated WordPress content
516+
> models: models define the content structure, context rules define how AI
517+
> should behave, MCP/Abilities expose controlled operations to external
518+
> agents, and WordPress revisions, statuses, capabilities, and audit logs keep
519+
> every change reviewable.
520+
521+
The big opportunity is that Saltus already owns the model definition. That
522+
means it can give AI agents structured knowledge of each CPT, its fields,
523+
allowed operations, and editorial policy without every plugin author
524+
rebuilding that machinery.

0 commit comments

Comments
 (0)