@de-otio/epimethian-mcp 6.0.0 → 6.1.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.
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, all write tools (`create_page`, `update_page`, `update_page_section`, `delete_page`, `add_attachment`, `add_drawio_diagram`, `add_label`, `remove_label`, `create_comment`, `resolve_comment`, `delete_comment`, `set_page_status`, `remove_page_status`) return an error with a remediation command. Read tools work normally. The read-only flag is resolved at server startup — restart running servers after changing it.
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