@de-otio/epimethian-mcp 6.0.1 → 6.1.1
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.
- package/README.md +115 -1
- package/dist/cli/index.js +681 -81
- package/dist/cli/index.js.map +4 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -93,7 +93,121 @@ epimethian-mcp profiles --set-read-write globex
|
|
|
93
93
|
|
|
94
94
|
New profiles default to **read-only**. The `setup` command prompts "Enable writes for this profile? [y/N]" or accepts `--read-write` for non-interactive use.
|
|
95
95
|
|
|
96
|
-
When a profile is read-only,
|
|
96
|
+
When a profile is read-only, write tools are **not registered** at all — the agent's tool list is truthful and contains only read tools plus `check_permissions`. The posture is resolved at server startup — restart running servers after changing it.
|
|
97
|
+
|
|
98
|
+
## Read-Only Mode
|
|
99
|
+
|
|
100
|
+
**Read-only is the recommended posture for most users.** It provides defense-in-depth: even if the underlying API token has write access, the MCP will not expose write tools to the agent. This protects against prompt-injection attacks, accidental mutations during exploratory sessions, and misconfigured agents.
|
|
101
|
+
|
|
102
|
+
### Configuring posture
|
|
103
|
+
|
|
104
|
+
Set `posture` in the profile settings (preferred):
|
|
105
|
+
|
|
106
|
+
```jsonc
|
|
107
|
+
// ~/.config/epimethian-mcp/profiles.json
|
|
108
|
+
{
|
|
109
|
+
"profiles": {
|
|
110
|
+
"my-profile": {
|
|
111
|
+
"posture": "read-only"
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Or use the legacy environment variable (still supported):
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
CONFLUENCE_READ_ONLY=true
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
The `posture` setting is a tri-state:
|
|
124
|
+
|
|
125
|
+
| Value | Behavior |
|
|
126
|
+
|---|---|
|
|
127
|
+
| `"read-only"` | Write tools are never registered, regardless of what the token can do. |
|
|
128
|
+
| `"read-write"` | Write tools are always registered. Writes that fail at the API level return remediation messages. |
|
|
129
|
+
| `"detect"` (default) | A startup probe infers the effective posture from the token's actual permissions. |
|
|
130
|
+
|
|
131
|
+
The legacy `readOnly: boolean` profile key remains supported as an alias and is resolved to `posture: "read-only"` / `"read-write"`. Users should migrate to `posture` directly.
|
|
132
|
+
|
|
133
|
+
### MCP posture is independent of token capability
|
|
134
|
+
|
|
135
|
+
You can pin the MCP to read-only even when the API token has full write access. This is the "belt and suspenders" case: the Confluence permission boundary enforces one layer, and the MCP profile enforces another. The `check_permissions` tool makes the distinction visible — it reports both the configured posture and what the probe determined the token can actually do.
|
|
136
|
+
|
|
137
|
+
### Startup probe (posture: "detect")
|
|
138
|
+
|
|
139
|
+
When posture is `"detect"`, Epimethian runs a lightweight probe at startup to determine whether the token can write. The probe queries the Confluence permissions endpoint for the first available space and, if that is unavailable, falls back to a dry-run write attempt. The result is logged as a startup banner and drives which tools are registered for the session.
|
|
140
|
+
|
|
141
|
+
Probe outcomes:
|
|
142
|
+
|
|
143
|
+
- Token can write → effective posture is `read-write`; all tools registered.
|
|
144
|
+
- Token is read-only → effective posture is `read-only`; write tools not registered.
|
|
145
|
+
- Probe inconclusive → effective posture defaults to `read-write` with a visible warning.
|
|
146
|
+
|
|
147
|
+
### Checking permissions
|
|
148
|
+
|
|
149
|
+
The `check_permissions` tool is always registered, in every posture. Call it from the agent to inspect the configured posture, effective posture, probe result, and token capability. For operator diagnostics from the CLI:
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
CONFLUENCE_PROFILE=my-profile epimethian-mcp permissions my-profile
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
For the full posture resolution matrix and error remediation design, see [doc/design/14-api-permission-handling.md](doc/design/14-api-permission-handling.md).
|
|
156
|
+
|
|
157
|
+
## Provenance: AI-Edited Badge
|
|
158
|
+
|
|
159
|
+
Any page **created or modified** by this MCP is automatically tagged with a yellow "AI-edited" content-status badge. The badge appears as a colored pill in the Confluence page view and space index, signaling that the page has been touched by an AI agent and has not yet been reviewed by a human. A human can clear it in one click after review.
|
|
160
|
+
|
|
161
|
+
The badge is re-applied on every body-modifying tool call (idempotent: skipped when the page already carries an equivalent badge in any supported locale, to avoid version spam). If a subsequent AI edit is made after the human clears the badge, it reappears.
|
|
162
|
+
|
|
163
|
+
### Default badge
|
|
164
|
+
|
|
165
|
+
- Label: `"AI-edited"` (English default)
|
|
166
|
+
- Color: `#FFC400` (yellow — reads as *attention needed*)
|
|
167
|
+
|
|
168
|
+
### Configuration
|
|
169
|
+
|
|
170
|
+
| Setting | Default | Purpose |
|
|
171
|
+
|---|---|---|
|
|
172
|
+
| `unverifiedStatus` | `true` | Master toggle. Set to `false` to disable the badge entirely. |
|
|
173
|
+
| `unverifiedStatusLocale` | system locale → `en` | Language for the badge label. |
|
|
174
|
+
| `unverifiedStatusName` | *(unset)* | Full label override (bypasses locale lookup). Must be ≤20 chars. |
|
|
175
|
+
| `unverifiedStatusColor` | `#FFC400` | Color override. One of five Confluence-allowed values: `#FFC400`, `#2684FF`, `#57D9A3`, `#FF7452`, `#8777D9`. |
|
|
176
|
+
|
|
177
|
+
Environment variable equivalents: `CONFLUENCE_UNVERIFIED_STATUS=false`, `CONFLUENCE_UNVERIFIED_STATUS_LOCALE=fr`.
|
|
178
|
+
|
|
179
|
+
Disable the badge for a profile:
|
|
180
|
+
|
|
181
|
+
```jsonc
|
|
182
|
+
{ "posture": "read-write", "unverifiedStatus": false }
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Custom label (e.g., for compliance workflows):
|
|
186
|
+
|
|
187
|
+
```jsonc
|
|
188
|
+
{ "unverifiedStatusName": "Needs legal review", "unverifiedStatusColor": "#FF7452" }
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Supported locales
|
|
192
|
+
|
|
193
|
+
| Locale | Label |
|
|
194
|
+
|---|---|
|
|
195
|
+
| `en` (default) | AI-edited |
|
|
196
|
+
| `fr` | Modifié par IA |
|
|
197
|
+
| `de` | KI-bearbeitet |
|
|
198
|
+
| `es` | Editado por IA |
|
|
199
|
+
| `pt` | Editado por IA |
|
|
200
|
+
| `it` | Modificato da IA |
|
|
201
|
+
| `nl` | AI-bewerkt |
|
|
202
|
+
| `ja` | AI編集済み |
|
|
203
|
+
| `zh` | AI已编辑 |
|
|
204
|
+
| `ko` | AI 편집됨 |
|
|
205
|
+
|
|
206
|
+
The locale is resolved from (in order): `unverifiedStatusLocale` profile setting → `CONFLUENCE_UNVERIFIED_STATUS_LOCALE` env var → system locale (`Intl.DateTimeFormat`) → `"en"`.
|
|
207
|
+
|
|
208
|
+
When the badge cannot be applied (e.g., the token lacks content-state permission), the tool call still succeeds and a warning is surfaced in the tool response instead of failing silently.
|
|
209
|
+
|
|
210
|
+
For the full design — idempotency behavior, version-bump math, lifecycle diagram, and security considerations — see [doc/design/13-unverified-status.md](doc/design/13-unverified-status.md).
|
|
97
211
|
|
|
98
212
|
## Token Efficiency
|
|
99
213
|
|