@de-otio/epimethian-mcp 5.4.1 → 5.5.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
@@ -12,8 +12,8 @@ The official [Atlassian MCP server](https://github.com/atlassian/atlassian-mcp-s
12
12
 
13
13
  - **OS keychain credential storage** — API tokens are stored in macOS Keychain or Linux libsecret, never in plaintext config files. Setup uses masked input so tokens don't leak into terminal scrollback.
14
14
  - **Multi-tenant profile isolation** — Each Atlassian tenant gets its own named profile with fully separate credentials and keychain entries. No risk of cross-tenant writes when switching between clients.
15
- - **Tenant-aware write safety** — Write operations echo the target tenant so the AI agent (and you) always see where changes are going before they land.
16
- - **draw.io diagram support** — Create and embed draw.io diagrams directly in Confluence pages, something the official server doesn't expose.
15
+ - **Tenant-aware write safety** — Write operations echo the target tenant so the AI agent (and you) always see where changes are going.
16
+ - **draw.io diagram support** — Create and embed draw.io diagrams directly in Confluence pages (assuming the tenant has draw.io installed), something the official server doesn't expose.
17
17
  - **Attribution tracking** — Edited pages are labelled `epimethian-edited` for easy discovery. Confluence version messages include the MCP client name (e.g. "Updated by Claude Code (via Epimethian v5.2.0)") so you can trace which AI-assisted edits touched which content.
18
18
 
19
19
  If you don't need any of the above, the official Atlassian server is a fine choice.
@@ -108,40 +108,40 @@ Confluence pages are verbose — storage format HTML with macro markup can easil
108
108
 
109
109
  ## Tools
110
110
 
111
- | Tool | Description |
112
- | -------------------- | -------------------------- |
113
- | `create_page` | Create a new page |
114
- | `get_page` | Read a page by ID (`headings_only`, `section`, `max_length`, `format`) |
115
- | `get_page_by_title` | Look up a page by title (same options as `get_page`) |
116
- | `update_page` | Update an existing page |
117
- | `update_page_section`| Update a single section by heading name |
118
- | `delete_page` | Delete a page |
119
- | `list_pages` | List pages in a space |
120
- | `get_page_children` | Get child pages |
121
- | `search_pages` | Search via CQL (includes content excerpts) |
122
- | `get_spaces` | List available spaces |
123
- | `add_attachment` | Upload a file attachment |
124
- | `get_attachments` | List attachments on a page |
125
- | `add_drawio_diagram` | Add a draw.io diagram |
126
- | `get_labels` | Get all labels on a page |
127
- | `add_label` | Add one or more labels to a page |
128
- | `remove_label` | Remove a label from a page |
129
- | `get_comments` | Read page comments (footer and inline) |
130
- | `create_comment` | Add a comment to a page |
131
- | `resolve_comment` | Resolve or reopen an inline comment |
132
- | `delete_comment` | Delete a comment |
133
- | `get_page_status` | Get the content status badge on a page |
134
- | `set_page_status` | Set the content status badge on a page |
135
- | `remove_page_status` | Remove the content status badge from a page |
136
- | `get_page_versions` | List version history for a page |
137
- | `get_page_version` | Get page content at a specific historical version (read-only markdown) |
138
- | `diff_page_versions` | Compare two versions of a page |
139
- | `prepend_to_page` | Insert content at the beginning of a page (additive, safe) |
140
- | `append_to_page` | Insert content at the end of a page (additive, safe) |
141
- | `revert_page` | Revert a page to a previous version (lossless) |
142
- | `lookup_user` | Search for Atlassian users by name or email |
143
- | `resolve_page_link` | Resolve a page title + space key to a stable page ID and URL |
144
- | `get_version` | Return the server version |
111
+ | Tool | Description |
112
+ | --------------------- | ---------------------------------------------------------------------- |
113
+ | `create_page` | Create a new page |
114
+ | `get_page` | Read a page by ID (`headings_only`, `section`, `max_length`, `format`) |
115
+ | `get_page_by_title` | Look up a page by title (same options as `get_page`) |
116
+ | `update_page` | Update an existing page |
117
+ | `update_page_section` | Update a single section by heading name |
118
+ | `delete_page` | Delete a page |
119
+ | `list_pages` | List pages in a space |
120
+ | `get_page_children` | Get child pages |
121
+ | `search_pages` | Search via CQL (includes content excerpts) |
122
+ | `get_spaces` | List available spaces |
123
+ | `add_attachment` | Upload a file attachment |
124
+ | `get_attachments` | List attachments on a page |
125
+ | `add_drawio_diagram` | Add a draw.io diagram |
126
+ | `get_labels` | Get all labels on a page |
127
+ | `add_label` | Add one or more labels to a page |
128
+ | `remove_label` | Remove a label from a page |
129
+ | `get_comments` | Read page comments (footer and inline) |
130
+ | `create_comment` | Add a comment to a page |
131
+ | `resolve_comment` | Resolve or reopen an inline comment |
132
+ | `delete_comment` | Delete a comment |
133
+ | `get_page_status` | Get the content status badge on a page |
134
+ | `set_page_status` | Set the content status badge on a page |
135
+ | `remove_page_status` | Remove the content status badge from a page |
136
+ | `get_page_versions` | List version history for a page |
137
+ | `get_page_version` | Get page content at a specific historical version (read-only markdown) |
138
+ | `diff_page_versions` | Compare two versions of a page |
139
+ | `prepend_to_page` | Insert content at the beginning of a page (additive, safe) |
140
+ | `append_to_page` | Insert content at the end of a page (additive, safe) |
141
+ | `revert_page` | Revert a page to a previous version (lossless) |
142
+ | `lookup_user` | Search for Atlassian users by name or email |
143
+ | `resolve_page_link` | Resolve a page title + space key to a stable page ID and URL |
144
+ | `get_version` | Return the server version |
145
145
 
146
146
  ## Content Safety
147
147
 
@@ -160,9 +160,12 @@ Write operations are protected by layered safety guards to prevent accidental co
160
160
  - URL, email, and API token are stored as an atomic unit — no mixing across profiles
161
161
  - Tokens are never written to disk in plaintext
162
162
  - The `setup` command uses masked input so tokens don't appear in terminal scrollback
163
- - Startup validation verifies credentials and tenant identity before accepting tool calls
163
+ - Startup validation verifies credentials, tenant identity (email), and tenant seal (cloudId) before accepting tool calls. Sealed profiles fail closed if the tenant-id endpoint is unreachable.
164
164
  - Write operations include a tenant echo so the target is always visible
165
165
  - For CI/headless environments, set all three env vars (`CONFLUENCE_URL`, `CONFLUENCE_EMAIL`, `CONFLUENCE_API_TOKEN`) — partial combinations are rejected
166
+ - Updates are **check-and-notify** by default. Run `epimethian-mcp upgrade` to install — the CLI verifies the npm provenance attestation first and refuses to install without it. Set `EPIMETHIAN_AUTO_UPGRADE=patches` to opt in to automatic patch installs (same integrity check).
167
+
168
+ For a full security & safety evaluation — threat model, defence-in-depth mechanisms, known limitations — see [doc/design/security/](doc/design/security/README.md).
166
169
 
167
170
  ## Development
168
171
 
@@ -174,6 +177,34 @@ npm run build
174
177
  npm test
175
178
  ```
176
179
 
180
+ ## Architecture
181
+
182
+ ```mermaid
183
+ flowchart LR
184
+ Agent["AI Agent<br/>(Claude Code, Cursor, ...)"]
185
+
186
+ subgraph Local["Local machine"]
187
+ MCP["Epimethian MCP Server"]
188
+ Keychain["OS Keychain<br/>(macOS Keychain / libsecret)"]
189
+ Registry["Tenant Profile Registry<br/>(~/.config/epimethian-mcp/profiles.json)"]
190
+ end
191
+
192
+ subgraph Atlassian["Atlassian Cloud"]
193
+ TenantA["Tenant A<br/>(e.g. globex)"]
194
+ TenantB["Tenant B<br/>(e.g. acme-corp)"]
195
+ end
196
+
197
+ Agent -- "stdio (MCP)" --> MCP
198
+ MCP -- "list / select profile" --> Registry
199
+ MCP -- "read credentials for profile" --> Keychain
200
+ MCP -- "HTTPS + API token<br/>(tenant A)" --> TenantA
201
+ MCP -- "HTTPS + API token<br/>(tenant B)" --> TenantB
202
+
203
+ Registry -. "names + read-only flags<br/>(no secrets)" .- Keychain
204
+ ```
205
+
206
+ The MCP server resolves the active profile from `CONFLUENCE_PROFILE`, loads its URL/email/token from the keychain, and talks directly to the matching Atlassian tenant. The profile registry stores only non-secret metadata (profile names, read-only flags); tokens never leave the keychain in plaintext.
207
+
177
208
  ## License
178
209
 
179
210
  [MIT](LICENSE)