@crypto512/jicon-mcp 1.2.0 → 2.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 (161) hide show
  1. package/README.md +73 -67
  2. package/TOOL_LIST.md +785 -133
  3. package/dist/config/constants.d.ts +18 -7
  4. package/dist/config/constants.d.ts.map +1 -1
  5. package/dist/config/constants.js +21 -8
  6. package/dist/config/constants.js.map +1 -1
  7. package/dist/config/loader.d.ts +11 -11
  8. package/dist/config/loader.d.ts.map +1 -1
  9. package/dist/config/loader.js +53 -93
  10. package/dist/config/loader.js.map +1 -1
  11. package/dist/config/types.d.ts +3 -6
  12. package/dist/config/types.d.ts.map +1 -1
  13. package/dist/config/types.js +2 -4
  14. package/dist/config/types.js.map +1 -1
  15. package/dist/confluence/formatters.js +1 -1
  16. package/dist/confluence/formatters.js.map +1 -1
  17. package/dist/confluence/tools.d.ts +8 -12
  18. package/dist/confluence/tools.d.ts.map +1 -1
  19. package/dist/confluence/tools.js +285 -233
  20. package/dist/confluence/tools.js.map +1 -1
  21. package/dist/index.js +17 -26
  22. package/dist/index.js.map +1 -1
  23. package/dist/jira/formatters.d.ts +1 -0
  24. package/dist/jira/formatters.d.ts.map +1 -1
  25. package/dist/jira/formatters.js +13 -12
  26. package/dist/jira/formatters.js.map +1 -1
  27. package/dist/jira/tools.d.ts +4 -0
  28. package/dist/jira/tools.d.ts.map +1 -1
  29. package/dist/jira/tools.js +234 -44
  30. package/dist/jira/tools.js.map +1 -1
  31. package/dist/permissions/tool-registry.d.ts +2 -2
  32. package/dist/permissions/tool-registry.d.ts.map +1 -1
  33. package/dist/permissions/tool-registry.js +4 -2
  34. package/dist/permissions/tool-registry.js.map +1 -1
  35. package/dist/permissions/write-home-validator.d.ts.map +1 -1
  36. package/dist/permissions/write-home-validator.js +13 -3
  37. package/dist/permissions/write-home-validator.js.map +1 -1
  38. package/dist/tempo/defaults.d.ts +17 -0
  39. package/dist/tempo/defaults.d.ts.map +1 -0
  40. package/dist/tempo/defaults.js +26 -0
  41. package/dist/tempo/defaults.js.map +1 -0
  42. package/dist/tempo/tools.d.ts +5 -0
  43. package/dist/tempo/tools.d.ts.map +1 -1
  44. package/dist/tempo/tools.js +161 -35
  45. package/dist/tempo/tools.js.map +1 -1
  46. package/dist/utils/buffer-pipeline/index.d.ts +30 -0
  47. package/dist/utils/buffer-pipeline/index.d.ts.map +1 -0
  48. package/dist/utils/buffer-pipeline/index.js +317 -0
  49. package/dist/utils/buffer-pipeline/index.js.map +1 -0
  50. package/dist/utils/buffer-pipeline/output/csv.d.ts +20 -0
  51. package/dist/utils/buffer-pipeline/output/csv.d.ts.map +1 -0
  52. package/dist/utils/buffer-pipeline/output/csv.js +117 -0
  53. package/dist/utils/buffer-pipeline/output/csv.js.map +1 -0
  54. package/dist/utils/buffer-pipeline/output/json.d.ts +16 -0
  55. package/dist/utils/buffer-pipeline/output/json.d.ts.map +1 -0
  56. package/dist/utils/buffer-pipeline/output/json.js +48 -0
  57. package/dist/utils/buffer-pipeline/output/json.js.map +1 -0
  58. package/dist/utils/buffer-pipeline/output/markdown.d.ts +15 -0
  59. package/dist/utils/buffer-pipeline/output/markdown.d.ts.map +1 -0
  60. package/dist/utils/buffer-pipeline/output/markdown.js +105 -0
  61. package/dist/utils/buffer-pipeline/output/markdown.js.map +1 -0
  62. package/dist/utils/buffer-pipeline/output/xhtml-list.d.ts +16 -0
  63. package/dist/utils/buffer-pipeline/output/xhtml-list.d.ts.map +1 -0
  64. package/dist/utils/buffer-pipeline/output/xhtml-list.js +81 -0
  65. package/dist/utils/buffer-pipeline/output/xhtml-list.js.map +1 -0
  66. package/dist/utils/buffer-pipeline/output/xhtml-table.d.ts +15 -0
  67. package/dist/utils/buffer-pipeline/output/xhtml-table.d.ts.map +1 -0
  68. package/dist/utils/buffer-pipeline/output/xhtml-table.js +176 -0
  69. package/dist/utils/buffer-pipeline/output/xhtml-table.js.map +1 -0
  70. package/dist/utils/buffer-pipeline/schema.d.ts +1878 -0
  71. package/dist/utils/buffer-pipeline/schema.d.ts.map +1 -0
  72. package/dist/utils/buffer-pipeline/schema.js +168 -0
  73. package/dist/utils/buffer-pipeline/schema.js.map +1 -0
  74. package/dist/utils/buffer-pipeline/stages/filter.d.ts +32 -0
  75. package/dist/utils/buffer-pipeline/stages/filter.d.ts.map +1 -0
  76. package/dist/utils/buffer-pipeline/stages/filter.js +208 -0
  77. package/dist/utils/buffer-pipeline/stages/filter.js.map +1 -0
  78. package/dist/utils/buffer-pipeline/stages/format.d.ts +45 -0
  79. package/dist/utils/buffer-pipeline/stages/format.d.ts.map +1 -0
  80. package/dist/utils/buffer-pipeline/stages/format.js +160 -0
  81. package/dist/utils/buffer-pipeline/stages/format.js.map +1 -0
  82. package/dist/utils/buffer-pipeline/stages/group-by.d.ts +25 -0
  83. package/dist/utils/buffer-pipeline/stages/group-by.d.ts.map +1 -0
  84. package/dist/utils/buffer-pipeline/stages/group-by.js +190 -0
  85. package/dist/utils/buffer-pipeline/stages/group-by.js.map +1 -0
  86. package/dist/utils/buffer-pipeline/stages/select.d.ts +54 -0
  87. package/dist/utils/buffer-pipeline/stages/select.d.ts.map +1 -0
  88. package/dist/utils/buffer-pipeline/stages/select.js +228 -0
  89. package/dist/utils/buffer-pipeline/stages/select.js.map +1 -0
  90. package/dist/utils/buffer-pipeline/stages/sort.d.ts +20 -0
  91. package/dist/utils/buffer-pipeline/stages/sort.d.ts.map +1 -0
  92. package/dist/utils/buffer-pipeline/stages/sort.js +96 -0
  93. package/dist/utils/buffer-pipeline/stages/sort.js.map +1 -0
  94. package/dist/utils/buffer-pipeline/types.d.ts +277 -0
  95. package/dist/utils/buffer-pipeline/types.d.ts.map +1 -0
  96. package/dist/utils/buffer-pipeline/types.js +8 -0
  97. package/dist/utils/buffer-pipeline/types.js.map +1 -0
  98. package/dist/utils/buffer-tools.d.ts +749 -19
  99. package/dist/utils/buffer-tools.d.ts.map +1 -1
  100. package/dist/utils/buffer-tools.js +738 -491
  101. package/dist/utils/buffer-tools.js.map +1 -1
  102. package/dist/utils/content-buffer.d.ts +55 -4
  103. package/dist/utils/content-buffer.d.ts.map +1 -1
  104. package/dist/utils/content-buffer.js +107 -9
  105. package/dist/utils/content-buffer.js.map +1 -1
  106. package/dist/utils/jicon-help.d.ts +1 -1
  107. package/dist/utils/jicon-help.d.ts.map +1 -1
  108. package/dist/utils/jicon-help.js +345 -99
  109. package/dist/utils/jicon-help.js.map +1 -1
  110. package/dist/utils/json-structure.d.ts +121 -0
  111. package/dist/utils/json-structure.d.ts.map +1 -0
  112. package/dist/utils/json-structure.js +637 -0
  113. package/dist/utils/json-structure.js.map +1 -0
  114. package/dist/utils/plantuml/include-expander.d.ts +31 -30
  115. package/dist/utils/plantuml/include-expander.d.ts.map +1 -1
  116. package/dist/utils/plantuml/include-expander.js +167 -133
  117. package/dist/utils/plantuml/include-expander.js.map +1 -1
  118. package/dist/utils/plantuml/index.d.ts +3 -3
  119. package/dist/utils/plantuml/index.d.ts.map +1 -1
  120. package/dist/utils/plantuml/index.js +4 -4
  121. package/dist/utils/plantuml/index.js.map +1 -1
  122. package/dist/utils/plantuml/service.d.ts +13 -24
  123. package/dist/utils/plantuml/service.d.ts.map +1 -1
  124. package/dist/utils/plantuml/service.js +49 -99
  125. package/dist/utils/plantuml/service.js.map +1 -1
  126. package/dist/utils/plantuml/tools.d.ts.map +1 -1
  127. package/dist/utils/plantuml/tools.js +33 -72
  128. package/dist/utils/plantuml/tools.js.map +1 -1
  129. package/dist/utils/plantuml/types.d.ts +1 -35
  130. package/dist/utils/plantuml/types.d.ts.map +1 -1
  131. package/dist/utils/plantuml/types.js +1 -11
  132. package/dist/utils/plantuml/types.js.map +1 -1
  133. package/dist/utils/plantuml/validation-helper.d.ts +1 -1
  134. package/dist/utils/plantuml/validation-helper.js +12 -12
  135. package/dist/utils/plantuml/validation-helper.js.map +1 -1
  136. package/dist/utils/response-formatter.d.ts +68 -0
  137. package/dist/utils/response-formatter.d.ts.map +1 -1
  138. package/dist/utils/response-formatter.js +186 -78
  139. package/dist/utils/response-formatter.js.map +1 -1
  140. package/dist/utils/url-tools.d.ts.map +1 -1
  141. package/dist/utils/url-tools.js +22 -0
  142. package/dist/utils/url-tools.js.map +1 -1
  143. package/dist/utils/xhtml/error-locator.js +2 -2
  144. package/dist/utils/xhtml/error-locator.js.map +1 -1
  145. package/dist/utils/xhtml/index.d.ts +1 -1
  146. package/dist/utils/xhtml/index.d.ts.map +1 -1
  147. package/dist/utils/xhtml/index.js +1 -1
  148. package/dist/utils/xhtml/index.js.map +1 -1
  149. package/dist/utils/xhtml/parser.d.ts +34 -5
  150. package/dist/utils/xhtml/parser.d.ts.map +1 -1
  151. package/dist/utils/xhtml/parser.js +66 -11
  152. package/dist/utils/xhtml/parser.js.map +1 -1
  153. package/dist/utils/xhtml/plantuml.d.ts.map +1 -1
  154. package/dist/utils/xhtml/plantuml.js +5 -3
  155. package/dist/utils/xhtml/plantuml.js.map +1 -1
  156. package/dist/utils/xhtml/serializer.d.ts.map +1 -1
  157. package/dist/utils/xhtml/serializer.js +12 -15
  158. package/dist/utils/xhtml/serializer.js.map +1 -1
  159. package/dist/utils/xhtml/types.d.ts +1 -0
  160. package/dist/utils/xhtml/types.d.ts.map +1 -1
  161. package/package.json +12 -4
package/TOOL_LIST.md CHANGED
@@ -5,17 +5,136 @@ This document provides a comprehensive reference of all available tools in the J
5
5
 
6
6
  ## Summary
7
7
 
8
- **Total Tools**: 69
8
+ **Total Tools**: 70
9
9
  - **Jira Tools**: 18 (13 read + 5 write)
10
10
  - **Confluence Tools**: 21 (13 read + 8 write)
11
11
  - **Tempo Tools**: 12 (9 read + 3 write)
12
- - **Buffer Tools**: 10
12
+ - **Buffer Tools**: 11
13
13
  - **Workload Tools**: 2
14
14
  - **URL Tools**: 2
15
15
  - **Jicon Help Tools**: 1
16
16
  - **PlantUML Tools**: 3
17
17
 
18
- **Note**: Tools that return large content use in-memory buffering with pagination support. See the Buffer Tools section for content retrieval.
18
+ **Note**: All data-heavy tools (search, list, get) **always** return buffered responses with metadata for origin tracking:
19
+ - **JSON arrays**: Use `buffer_get_items` for complete items, `buffer_pipeline` for reports
20
+ - **XHTML**: Use `buffer_get_element` for element-based access
21
+ - **Search**: Use `buffer_grep` to search within any buffer
22
+
23
+ **Important**: `buffer_get_chunk` is blocked for JSON arrays and XHTML. Use the appropriate tool above.
24
+
25
+ ---
26
+
27
+ ## Agentic Workflow Patterns
28
+
29
+ ### Tool Description Pattern
30
+
31
+ All tools follow a consistent description pattern for easy discovery:
32
+
33
+ ```
34
+ <Primary purpose - one line>
35
+
36
+ REQUIRES: <Prerequisites or dependencies>
37
+ RETURNS: <Key return values and buffer content>
38
+ NEXT: <Typical next tools in workflow>
39
+
40
+ TIP: <Usage hints>
41
+ WARNING: <Important caveats>
42
+ ```
43
+
44
+ ### Suggested Next Tools
45
+
46
+ JSON responses include `suggestedNextTools` based on context:
47
+
48
+ ```json
49
+ {
50
+ "bufferId": "buf_xxx",
51
+ "structure": { "type": "array", "itemCount": 500 },
52
+ "suggestedNextTools": [
53
+ { "tool": "buffer_pipeline", "description": "Transform to table/report (98% token reduction)", "condition": "for Confluence reports" },
54
+ { "tool": "buffer_get_items", "description": "Get complete items for AI analysis", "condition": "for detailed analysis" },
55
+ { "tool": "buffer_grep", "description": "Search within results" }
56
+ ]
57
+ }
58
+ ```
59
+
60
+ ### Error Recovery Patterns
61
+
62
+ #### 409 Conflict Handling (Optimistic Locking)
63
+
64
+ Write operations may fail with HTTP 409 when the resource was modified since it was last read. Use `autoRetry=true` for automatic recovery:
65
+
66
+ ```typescript
67
+ // Manual retry pattern
68
+ jira_update_issue({ issueKey: "PROJ-123", fields: {...} })
69
+ // If 409 error → re-fetch issue → retry update
70
+
71
+ // Auto-retry pattern (RECOMMENDED for agents)
72
+ jira_update_issue({ issueKey: "PROJ-123", fields: {...}, autoRetry: true })
73
+ // Automatically: re-fetches → retries once → returns success or final error
74
+ ```
75
+
76
+ **Tools supporting autoRetry:**
77
+ - `jira_update_issue` - Auto-retries on 409 (refetches issue)
78
+ - `confluence_review_publish` - Auto-retries on 409 (refetches page version)
79
+ - `tempo_update_worklog` - Auto-retries on 409 (refetches worklog)
80
+
81
+ **Response on successful retry:**
82
+ ```json
83
+ {
84
+ "success": true,
85
+ "issueKey": "PROJ-123",
86
+ "retriedAfterConflict": true
87
+ }
88
+ ```
89
+
90
+ #### XHTML Validation Errors
91
+
92
+ When XHTML validation fails, the response includes element ID and suggested actions:
93
+
94
+ ```json
95
+ {
96
+ "error": true,
97
+ "message": "XHTML parsing error at line 45",
98
+ "errorContext": {
99
+ "elementId": 12,
100
+ "bufferId": "buf_xxx"
101
+ },
102
+ "suggestedActions": {
103
+ "inspect": "buffer_get_element(bufferId=\"buf_xxx\", elementId=12)",
104
+ "fix": "buffer_edit(bufferId=\"buf_xxx\", replace=12, content=\"<corrected>\")",
105
+ "validate": "buffer_validate_xhtml(bufferId=\"buf_xxx\")"
106
+ }
107
+ }
108
+ ```
109
+
110
+ ### Common Agentic Workflows
111
+
112
+ #### Jira Search → Confluence Report
113
+ ```
114
+ 1. jira_search_issues(jql) → bufferId, suggestedNextTools
115
+ 2. buffer_pipeline(bufferId, pipeline) → tableBufferId (98% token reduction)
116
+ 3. confluence_edit(pageId) → pageBufferId, structure
117
+ 4. buffer_edit(pageBufferId, after=ID, fromBufferId=tableBufferId)
118
+ 5. confluence_draft_create(pageId, pageBufferId, autoRetry=true) → draft URL
119
+ ```
120
+
121
+ #### Tempo Time Report
122
+ ```
123
+ 1. tempo_get_user_info() → workerKey
124
+ 2. tempo_get_worklogs(dateFrom, dateTo, workerKey) → bufferId, suggestedNextTools
125
+ 3. buffer_pipeline(bufferId, groupBy=project, sum=hours) → summaryBufferId
126
+ 4. Use in report or display directly
127
+ ```
128
+
129
+ #### Edit Existing Page with Error Recovery
130
+ ```
131
+ 1. confluence_edit(input) → bufferId, pageId, structure
132
+ 2. buffer_edit(bufferId, after=ID, content) → updated structure
133
+ 3. buffer_validate_xhtml(bufferId) → check before publish
134
+ - If errors: buffer_get_element(elementId) → inspect → buffer_edit(replace=ID) → retry
135
+ 4. confluence_draft_create(pageId, bufferId) → draft for review
136
+ 5. confluence_review_publish(reviewDraftId, autoRetry=true) → published
137
+ ```
19
138
 
20
139
  ---
21
140
 
@@ -30,7 +149,26 @@ This document provides a comprehensive reference of all available tools in the J
30
149
  | jql | string | ✓ | JQL query string |
31
150
  | fields | string[] | ✗ | Specific fields to return |
32
151
 
33
- Large responses are automatically buffered - use `buffer_get_chunk` or `buffer_grep` to access.
152
+ **Response Fields (Important!):**
153
+ | Field | Description |
154
+ |-------|-------------|
155
+ | `returnedItems` | Items available in buffer - **USE THIS** for actual count |
156
+ | `jiraTotalMatching` | Total matching in Jira (may exceed returnedItems) |
157
+ | `apiLimit` | Maximum items per search (5000 cap) |
158
+ | `note` | Explanation when results are truncated |
159
+
160
+ **Example Response** (when JQL matches 9998 issues):
161
+ ```json
162
+ {
163
+ "bufferId": "buf_xxx",
164
+ "returnedItems": 5000,
165
+ "jiraTotalMatching": 9998,
166
+ "apiLimit": 5000,
167
+ "note": "9998 issues match query, 5000 returned (API limit)"
168
+ }
169
+ ```
170
+
171
+ **Returns**: `bufferId` with issues. Use `buffer_pipeline` for tables, `buffer_get_items` for AI analysis.
34
172
 
35
173
  ---
36
174
 
@@ -44,7 +182,7 @@ Large responses are automatically buffered - use `buffer_get_chunk` or `buffer_g
44
182
  | fields | string[] | ✗ | Specific fields to return |
45
183
  | expand | string[] | ✗ | Additional data (e.g., "changelog", "renderedFields") |
46
184
 
47
- Large responses are automatically buffered - use `buffer_get_chunk` or `buffer_grep` to access.
185
+ **Returns**: `bufferId` with metadata `{resourceType: "jira_issue", title: "PROJ-123: Summary", issueId, projectKey}`. Use `buffer_get_chunk` to read, `buffer_grep` to search.
48
186
 
49
187
  ---
50
188
 
@@ -75,6 +213,9 @@ Large responses are automatically buffered - use `buffer_get_chunk` or `buffer_g
75
213
  | issueKey | string | ✓ | Issue key |
76
214
  | fields | object | ✓ | Fields to update |
77
215
  | notifyUsers | boolean | ✗ | Send notifications (default: true) |
216
+ | autoRetry | boolean | ✗ | Auto-retry once on 409 conflict (refetches current state) |
217
+
218
+ **Error Recovery**: Use `autoRetry: true` for automatic 409 conflict handling. Response includes `retriedAfterConflict: true` if retry was needed.
78
219
 
79
220
  ---
80
221
 
@@ -112,7 +253,7 @@ Large responses are automatically buffered - use `buffer_get_chunk` or `buffer_g
112
253
  | issueKey | string | ✓ | Issue key |
113
254
  | orderBy | string | ✗ | Sort order ("created" or "-created") |
114
255
 
115
- Large responses are automatically buffered - use `buffer_get_chunk` or `buffer_grep` to access.
256
+ **Returns**: `bufferId` with metadata `{resourceType: "jira_comments", title: "PROJ-123 comments", issueKey}`. Use `buffer_get_chunk` to read, `buffer_grep` to search.
116
257
 
117
258
  ---
118
259
 
@@ -125,6 +266,8 @@ Large responses are automatically buffered - use `buffer_get_chunk` or `buffer_g
125
266
  | recent | boolean | ✗ | Only recent projects |
126
267
  | expand | string[] | ✗ | Additional data to expand |
127
268
 
269
+ **Returns**: `bufferId` with metadata `{resourceType: "jira_projects", title: "All Projects"}`. Use `buffer_get_chunk` to read, `buffer_grep` to search.
270
+
128
271
  ---
129
272
 
130
273
  ### 9. jira_get_project
@@ -136,6 +279,8 @@ Large responses are automatically buffered - use `buffer_get_chunk` or `buffer_g
136
279
  | projectKey | string | ✓ | Project key |
137
280
  | expand | string[] | ✗ | Additional data to expand |
138
281
 
282
+ **Returns**: `bufferId` with metadata `{resourceType: "jira_project", title: "Project Name", projectKey}`. Use `buffer_get_chunk` to read, `buffer_grep` to search.
283
+
139
284
  ---
140
285
 
141
286
  ### 10. jira_get_issue_types
@@ -181,6 +326,8 @@ Large responses are automatically buffered - use `buffer_get_chunk` or `buffer_g
181
326
  |-----------|------|----------|-------------|
182
327
  | boardId | number | ✓ | Board ID |
183
328
 
329
+ **Returns**: `bufferId` with metadata `{resourceType: "jira_board", title: "Board Name", boardId}`. Use `buffer_get_chunk` to read, `buffer_grep` to search.
330
+
184
331
  ---
185
332
 
186
333
  ### 14. jira_get_sprints
@@ -192,7 +339,7 @@ Large responses are automatically buffered - use `buffer_get_chunk` or `buffer_g
192
339
  | boardId | number | ✓ | Board ID |
193
340
  | state | string | ✗ | Sprint state ("active", "future", "closed") |
194
341
 
195
- Large responses are automatically buffered - use `buffer_get_chunk` or `buffer_grep` to access.
342
+ **Returns**: `bufferId` with metadata `{resourceType: "jira_sprints", title: "Board #123 sprints", boardId}`. Use `buffer_get_chunk` to read, `buffer_grep` to search.
196
343
 
197
344
  ---
198
345
 
@@ -204,7 +351,7 @@ Large responses are automatically buffered - use `buffer_get_chunk` or `buffer_g
204
351
  |-----------|------|----------|-------------|
205
352
  | sprintId | number | ✓ | Sprint ID |
206
353
 
207
- Large responses are automatically buffered - use `buffer_get_chunk` or `buffer_grep` to access.
354
+ **Returns**: `bufferId` with metadata `{resourceType: "jira_sprint_issues", title: "Sprint #456 issues", sprintId}`. Use `buffer_get_chunk` to read, `buffer_grep` to search.
208
355
 
209
356
  ---
210
357
 
@@ -226,9 +373,7 @@ Large responses are automatically buffered - use `buffer_get_chunk` or `buffer_g
226
373
  |-----------|------|----------|-------------|
227
374
  | issueKey | string | ✓ | Issue key (e.g., PROJ-123) |
228
375
 
229
- **Response includes**: `worklogCount`, `totalTimeSpentSeconds`, `totalTimeSpent`, `worklogs`
230
-
231
- Large responses are automatically buffered - use `buffer_get_chunk` or `buffer_grep` to access.
376
+ **Returns**: `bufferId` with metadata `{resourceType: "jira_worklogs", title: "PROJ-123 worklogs", issueKey}`. Includes `worklogCount`, `totalTimeSpentSeconds`, `totalTimeSpent`, `worklogs`. Use `buffer_get_chunk` to read, `buffer_grep` to search.
232
377
 
233
378
  ---
234
379
 
@@ -240,17 +385,14 @@ Large responses are automatically buffered - use `buffer_get_chunk` or `buffer_g
240
385
  |-----------|------|----------|-------------|
241
386
  | issueKey | string | ✓ | Issue key (e.g., PROJ-123) |
242
387
 
243
- **Response includes**: Breakdown by issue and grand total including:
244
- - The specified issue
245
- - All sub-tasks
246
- - All issues in the Epic (if the issue is an Epic)
388
+ **Returns**: `bufferId` with metadata `{resourceType: "jira_worklogs_total", title: "PROJ-123 total worklogs (recursive)", issueKey}`. Includes breakdown by issue and grand total for the issue, sub-tasks, and Epic children.
247
389
 
248
390
  ---
249
391
 
250
392
  ## Confluence Tools (21)
251
393
 
252
394
  ### 1. confluence_search_content
253
- **Description**: Search Confluence content using CQL. Auto-fetches all results (up to 5000).
395
+ **Description**: Search Confluence content using CQL. Auto-fetches all results.
254
396
  **Use Cases**: Find pages, search by keyword, filter by space
255
397
 
256
398
  | Parameter | Type | Required | Description |
@@ -258,7 +400,7 @@ Large responses are automatically buffered - use `buffer_get_chunk` or `buffer_g
258
400
  | cql | string | ✓ | CQL query string |
259
401
  | expand | string[] | ✗ | Additional data to expand |
260
402
 
261
- Large responses are automatically buffered - use `buffer_get_chunk` or `buffer_grep` to access.
403
+ **Returns**: `bufferId` with metadata `{resourceType: "confluence_search", title: "CQL: ..."}`. Use `buffer_get_chunk` to read, `buffer_grep` to search.
262
404
 
263
405
  ---
264
406
 
@@ -336,9 +478,10 @@ buffer_edit(bufferId=pageBuffer, after=5, fromBufferId=newContentBuffer)
336
478
 
337
479
  > **Note**: All page content changes go through the draft workflow.
338
480
  > AI creates/edits drafts; user publishes manually via Confluence UI:
339
- > - **Edit existing**: `confluence_edit(input)` → `buffer_edit(bufferId, after=ID, content/plantuml/fromBufferId)` → `confluence_draft_create(pageId, bufferId)` → user publishes
340
- > - **Create new**: `confluence_draft_create(spaceKey, title, content)` → user review → user publishes
481
+ > - **Edit existing**: `confluence_edit(input)` → `buffer_edit(bufferId, ...)` → `buffer_validate_xhtml(bufferId)` → `confluence_draft_create(pageId, bufferId)` → user publishes
482
+ > - **Create new**: `buffer_create(content, contentType="xhtml")` → `buffer_validate_xhtml(bufferId)` → `confluence_draft_create(spaceKey, title, bufferId)` → user publishes
341
483
  > - **After publish**: Draft ID becomes invalid; use `confluence_edit("SPACE/Title")` to edit again
484
+ > - **XHTML syntax**: Call `help(topic="storage")` for HTML vs XHTML differences
342
485
 
343
486
  ---
344
487
 
@@ -360,7 +503,7 @@ buffer_edit(bufferId=pageBuffer, after=5, fromBufferId=newContentBuffer)
360
503
  |-----------|------|----------|-------------|
361
504
  | type | string | ✗ | Space type filter ("global" or "personal") |
362
505
 
363
- Large responses are automatically buffered - use `buffer_get_chunk` or `buffer_grep` to access.
506
+ **Returns**: `bufferId` with metadata `{resourceType: "confluence_spaces", title: "All Spaces"}`. Use `buffer_get_chunk` to read, `buffer_grep` to search.
364
507
 
365
508
  ---
366
509
 
@@ -373,6 +516,8 @@ Large responses are automatically buffered - use `buffer_get_chunk` or `buffer_g
373
516
  | spaceKey | string | ✓ | Space key |
374
517
  | expand | string[] | ✗ | Additional data to expand |
375
518
 
519
+ **Returns**: `bufferId` with metadata `{resourceType: "confluence_space", title: "Space Name", spaceKey}`. Use `buffer_get_chunk` to read, `buffer_grep` to search.
520
+
376
521
  ---
377
522
 
378
523
  ### 8. confluence_get_page_children
@@ -384,7 +529,7 @@ Large responses are automatically buffered - use `buffer_get_chunk` or `buffer_g
384
529
  | pageId | string | ✓ | Parent page ID (accepts string or number) |
385
530
  | expand | string[] | ✗ | Additional data to expand |
386
531
 
387
- Large responses are automatically buffered - use `buffer_get_chunk` or `buffer_grep` to access.
532
+ **Returns**: `bufferId` with metadata `{resourceType: "confluence_page_children", title: "Page 123 children", pageId}`. Use `buffer_get_chunk` to read, `buffer_grep` to search.
388
533
 
389
534
  ---
390
535
 
@@ -407,7 +552,7 @@ Large responses are automatically buffered - use `buffer_get_chunk` or `buffer_g
407
552
  |-----------|------|----------|-------------|
408
553
  | pageId | string | ✓ | Page ID (accepts string or number) |
409
554
 
410
- Large responses are automatically buffered - use `buffer_get_chunk` or `buffer_grep` to access.
555
+ **Returns**: `bufferId` with metadata `{resourceType: "confluence_comments", title: "Page 123 comments", pageId}`. Use `buffer_get_chunk` to read, `buffer_grep` to search.
411
556
 
412
557
  ---
413
558
 
@@ -431,7 +576,7 @@ Large responses are automatically buffered - use `buffer_get_chunk` or `buffer_g
431
576
  |-----------|------|----------|-------------|
432
577
  | pageId | string | ✓ | Page ID (accepts string or number) |
433
578
 
434
- Large responses are automatically buffered - use `buffer_get_chunk` or `buffer_grep` to access.
579
+ **Returns**: `bufferId` with metadata `{resourceType: "confluence_attachments", title: "Page 123 attachments", pageId}`. Use `buffer_get_chunk` to read, `buffer_grep` to search.
435
580
 
436
581
  ---
437
582
 
@@ -456,9 +601,8 @@ Large responses are automatically buffered - use `buffer_get_chunk` or `buffer_g
456
601
  | Parameter | Type | Required | Description |
457
602
  |-----------|------|----------|-------------|
458
603
  | spaceKey | string | ✗ | Filter by space key |
459
- | limit | number | ✗ | Maximum results (default: 25) |
460
604
 
461
- **Response includes**: `drafts` array with `draftId`, `title`, `spaceKey`, `spaceName`, `created`, `url`
605
+ **Returns**: `bufferId` with metadata `{resourceType: "confluence_drafts", title: "All Drafts"}`. Includes `drafts` array with `draftId`, `title`, `spaceKey`, `spaceName`, `created`, `url`. Use `buffer_get_chunk` to read, `buffer_grep` to search.
462
606
 
463
607
  ---
464
608
 
@@ -480,6 +624,8 @@ Large responses are automatically buffered - use `buffer_get_chunk` or `buffer_g
480
624
  **Description**: Create a draft for user review - either a new page or as an edit to an existing page
481
625
  **Use Cases**: Start new page as draft, edit existing page through draft workflow
482
626
 
627
+ **REQUIRES `bufferId`** - content must be in a buffer for validation and error recovery.
628
+
483
629
  **Two Modes:**
484
630
 
485
631
  1. **NEW PAGE**: Create a standalone draft
@@ -487,40 +633,53 @@ Large responses are automatically buffered - use `buffer_get_chunk` or `buffer_g
487
633
  |-----------|------|----------|-------------|
488
634
  | spaceKey | string | ✓ | Space key |
489
635
  | title | string | ✓ | Draft title |
490
- | content/bufferId | string | ✓ | Content (storage format) or buffer ID |
636
+ | bufferId | string | ✓ | Buffer ID from `buffer_create(contentType="xhtml")` |
491
637
  | parentId | string | ✗ | Parent page ID |
492
638
  | labels | string[] | ✗ | Array of labels |
493
639
 
494
640
  2. **EDIT EXISTING PAGE**: Create a draft to edit an existing page
495
641
  | Parameter | Type | Required | Description |
496
642
  |-----------|------|----------|-------------|
497
- | pageId | string | ✓ | Existing page ID to edit |
643
+ | pageId | string | ✓ | Existing PAGE ID (NOT a draft ID) |
498
644
  | bufferId | string | ✓ | Buffer ID from `confluence_get_page(pageId)` or `confluence_edit(pageId)` |
499
645
  | title | string | ✗ | Optional new title (defaults to original) |
500
646
 
501
647
  **Important**: When `pageId` is provided, `bufferId` must originate from that page (validated). Space, title, and parent are auto-populated from the original page.
502
648
 
649
+ **WARNING**: `pageId` must be a real page ID, NOT a draft ID. If you pass a draft ID, you'll get an error suggesting `confluence_draft_open` instead.
650
+
503
651
  **Response includes**: `draftId`, `bufferId`, `structure` (element IDs), `title`, `spaceKey`, `version`, `url` (clickable to preview), `contentSummary`, `editingExistingPage` (when editing)
504
652
 
653
+ **On validation error**: Returns `bufferId`, `errorElementId`, and `errorContext` for surgical fix with `buffer_edit`.
654
+
505
655
  **PlantUML**: Raw @startuml blocks are not supported. Use `buffer_edit` with `plantuml` parameter.
506
656
 
507
- **Workflow for editing existing page**:
657
+ **Workflow for new page (buffer-first)**:
508
658
  ```
509
- 1. confluence_get_page(pageId) → bufferId, structure
510
- 2. buffer_edit(bufferId, ...) modify content
511
- 3. confluence_draft_create(pageId=..., bufferId=...) → draft for review
512
- 4. User reviews and publishes in Confluence UI (updates original page)
659
+ 1. buffer_create(content="<h1>Title</h1><p>Content</p>", contentType="xhtml")
660
+ bufferId, structure (element IDs)
661
+ 2. buffer_validate_xhtml(bufferId)
662
+ If errors: buffer_edit(bufferId, replace=errorElementId, content="<fixed>")
663
+ 3. confluence_draft_create(spaceKey, title, bufferId)
664
+ → draftId, url for preview
665
+ 4. User reviews and publishes via Confluence UI
513
666
  ```
514
667
 
515
- **Workflow for new page**:
668
+ **Workflow for editing existing page**:
516
669
  ```
517
- 1. confluence_draft_create(spaceKey, title, content) → draftId, bufferId, url
518
- 2. User clicks URL to preview
519
- 3. buffer_edit(bufferId, ...) → modify if needed
520
- 4. confluence_draft_save(draftId, bufferId) → checkpoint
521
- 5. User publishes via Confluence UI
670
+ 1. confluence_get_page(pageId) or confluence_edit(input)
671
+ bufferId, structure
672
+ 2. buffer_edit(bufferId, after=ID, content/plantuml)
673
+ modify content
674
+ 3. buffer_validate_xhtml(bufferId)
675
+ → check for errors
676
+ 4. confluence_draft_create(pageId=..., bufferId=...)
677
+ → draft for review
678
+ 5. User reviews and publishes in Confluence UI (updates original page)
522
679
  ```
523
680
 
681
+ **Why buffer-first?** Enables validation with element IDs for surgical error fixing. Call `help(topic="storage")` for XHTML syntax (HTML vs XHTML differences).
682
+
524
683
  ---
525
684
 
526
685
  ### 17. confluence_draft_save
@@ -574,6 +733,9 @@ Large responses are automatically buffered - use `buffer_get_chunk` or `buffer_g
574
733
  | Parameter | Type | Required | Description |
575
734
  |-----------|------|----------|-------------|
576
735
  | reviewDraftId | string | ✓ | ID of the [jicon-mcp REVIEW] draft to publish |
736
+ | autoRetry | boolean | ✗ | Auto-retry once on 409 conflict (refetches page version) |
737
+
738
+ **Error Recovery**: Use `autoRetry: true` for automatic 409 conflict handling when the original page was modified. Response includes `retriedAfterConflict: true` if retry was needed.
577
739
 
578
740
  **Workflow**:
579
741
  1. Validates the draft is a "[jicon-mcp REVIEW]" draft with proper label
@@ -610,7 +772,7 @@ Large responses are automatically buffered - use `buffer_get_chunk` or `buffer_g
610
772
  project = PROJ AND type = Bug AND status = Open AND assignee = currentUser()
611
773
 
612
774
  # Issues updated in the last 7 days
613
- updatedDate >= -7d
775
+ updated >= startOfDay(-7)
614
776
 
615
777
  # High priority issues in multiple projects
616
778
  project in (PROJ1, PROJ2) AND priority = High
@@ -717,7 +879,9 @@ AND lastModified >= now("-30d")
717
879
  | issueKey | string | ✗ | Filter by issue key (e.g., PROJ-123) |
718
880
  | workerKey | string | ✗ | Filter by worker username (get from tempo_get_user_info). Leave empty for ALL worklogs. |
719
881
 
720
- **WARNING**: No workerKey = returns ALL worklogs. Large responses are buffered.
882
+ **WARNING**: No workerKey = returns ALL worklogs.
883
+
884
+ **Returns**: `bufferId` with metadata `{resourceType: "tempo_worklogs", title: "Worklogs 2024-01-01 to 2024-01-31"}`. Use `buffer_get_chunk` to read, `buffer_grep` to search.
721
885
 
722
886
  ---
723
887
 
@@ -729,6 +893,8 @@ AND lastModified >= now("-30d")
729
893
  |-----------|------|----------|-------------|
730
894
  | worklogId | number | ✓ | Tempo worklog ID |
731
895
 
896
+ **Returns**: `bufferId` with metadata `{resourceType: "tempo_worklog", title: "PROJ-123 worklog #456", resourceId, issueKey}`. Use `buffer_get_chunk` to read, `buffer_grep` to search.
897
+
732
898
  ---
733
899
 
734
900
  ### 3. tempo_log_work
@@ -756,6 +922,9 @@ AND lastModified >= now("-30d")
756
922
  | hours | number | ✗ | New hours (decimal) |
757
923
  | description | string | ✗ | New description |
758
924
  | date | string | ✗ | New date (YYYY-MM-DD) |
925
+ | autoRetry | boolean | ✗ | Auto-retry once on 409 conflict (refetches current state) |
926
+
927
+ **Error Recovery**: Use `autoRetry: true` for automatic 409 conflict handling. Response includes `retriedAfterConflict: true` if retry was needed.
759
928
 
760
929
  ---
761
930
 
@@ -777,6 +946,8 @@ AND lastModified >= now("-30d")
777
946
  |-----------|------|----------|-------------|
778
947
  | (none) | | | |
779
948
 
949
+ **Returns**: `bufferId` with metadata `{resourceType: "tempo_accounts", title: "All Tempo Accounts"}`. Use `buffer_get_chunk` to read, `buffer_grep` to search.
950
+
780
951
  ---
781
952
 
782
953
  ### 7. tempo_get_account
@@ -787,6 +958,8 @@ AND lastModified >= now("-30d")
787
958
  |-----------|------|----------|-------------|
788
959
  | accountKey | string | ✓ | Account key |
789
960
 
961
+ **Returns**: `bufferId` with metadata `{resourceType: "tempo_account", title: "Account Name", accountKey}`. Use `buffer_get_chunk` to read, `buffer_grep` to search.
962
+
790
963
  ---
791
964
 
792
965
  ### 8. tempo_get_teams
@@ -797,6 +970,8 @@ AND lastModified >= now("-30d")
797
970
  |-----------|------|----------|-------------|
798
971
  | (none) | | | |
799
972
 
973
+ **Returns**: `bufferId` with metadata `{resourceType: "tempo_teams", title: "All Tempo Teams"}`. Use `buffer_get_chunk` to read, `buffer_grep` to search.
974
+
800
975
  ---
801
976
 
802
977
  ### 9. tempo_get_team
@@ -807,6 +982,8 @@ AND lastModified >= now("-30d")
807
982
  |-----------|------|----------|-------------|
808
983
  | teamId | number | ✓ | Team ID |
809
984
 
985
+ **Returns**: `bufferId` with metadata `{resourceType: "tempo_team", title: "Team Name", teamId}`. Use `buffer_get_chunk` to read, `buffer_grep` to search.
986
+
810
987
  ---
811
988
 
812
989
  ### 10. tempo_get_team_worklogs
@@ -819,7 +996,7 @@ AND lastModified >= now("-30d")
819
996
  | dateFrom | string | ✓ | Start date (YYYY-MM-DD) |
820
997
  | dateTo | string | ✓ | End date (YYYY-MM-DD) |
821
998
 
822
- Large responses are buffered - use `buffer_get_chunk` or `buffer_grep` to access.
999
+ **Returns**: `bufferId` with metadata `{resourceType: "tempo_team_worklogs", title: "Team #123 worklogs 2024-01-01 to 2024-01-31", teamId}`. Use `buffer_get_chunk` to read, `buffer_grep` to search.
823
1000
 
824
1001
  ---
825
1002
 
@@ -845,31 +1022,48 @@ Large responses are buffered - use `buffer_get_chunk` or `buffer_grep` to access
845
1022
  | dateFrom | string | ✗ | Start date filter (YYYY-MM-DD) |
846
1023
  | dateTo | string | ✗ | End date filter (YYYY-MM-DD) |
847
1024
 
848
- **Response includes**: `totalTimeSpent`, `totalWorklogCount`, `issueCount`, breakdown by issue, and full worklog list.
849
-
850
- More efficient than `jira_get_total_worklogs` for Tempo instances. Large responses are buffered.
1025
+ **Returns**: `bufferId` with metadata `{resourceType: "tempo_epic_worklogs", title: "PROJ-100 epic worklogs", epicKey}`. Includes `totalTimeSpent`, `totalWorklogCount`, `issueCount`, breakdown by issue, and full worklog list. Use `buffer_get_chunk` to read, `buffer_grep` to search. More efficient than `jira_get_total_worklogs` for Tempo instances.
851
1026
 
852
1027
  ---
853
1028
 
854
- ## Buffer Tools (10)
1029
+ ## Buffer Tools (11)
855
1030
 
856
1031
  Buffer tools are used for local content management. All buffer operations are in-memory - write enforcement is on Jira/Confluence/Tempo tools.
857
1032
 
858
1033
  **XHTML Editing**: `buffer_edit` uses element IDs for precise positioning in XHTML content. Each element gets a unique ID when loaded - use `buffer_get_structure` to see them. `buffer_validate_xhtml` validates Confluence storage format. XHTML validation is also automatically applied before any Confluence write operation.
859
1034
 
1035
+ **Data Pipelines**: `buffer_pipeline` transforms JSON buffers (from Jira/Tempo searches) with server-side filtering, grouping, sorting, and output generation - minimizing token usage.
1036
+
860
1037
  ### 1. buffer_create
861
- **Description**: Create a new buffer with initial content. For XHTML, returns element structure with IDs.
862
- **Use Cases**: Draft new Confluence pages, prepare content before persisting
1038
+ **Description**: Create a new buffer with initial content. Returns bufferId and structure.
1039
+
1040
+ **TIP**: Call `help(topic="storage")` for XHTML syntax. Call `help(topic="plantuml")` for diagram syntax.
1041
+
1042
+ **Content types**:
1043
+ - **xhtml**: Confluence storage format. Returns element IDs for `buffer_edit`.
1044
+ - **json**: JSON data (array or object). Use `buffer_pipeline` to filter, aggregate, and transform.
1045
+ - **plain**: Raw text content.
1046
+
1047
+ **Use Cases**: Draft new Confluence pages, prepare content before persisting, create JSON arrays for aggregation
863
1048
 
864
1049
  | Parameter | Type | Required | Description |
865
1050
  |-----------|------|----------|-------------|
866
- | content | string | ✓ | Initial content for the buffer |
1051
+ | content | string \| object \| array | ✓ | Content: string for all types, or object/array for json (auto-stringified) |
867
1052
  | contentType | enum | ✓ | Content type: `"xhtml"` for Confluence, `"plain"` for text, `"json"` for data |
868
1053
  | metadata | object | ✗ | Optional metadata to attach to the buffer |
869
1054
 
870
- **Response for XHTML includes**: `bufferId`, `structure` (element IDs), `nextId`, `contentType`, `totalSize`
1055
+ **Auto-stringify for JSON**: When `contentType: "json"`, you can pass native objects/arrays directly instead of JSON strings:
1056
+ ```typescript
1057
+ // Both work:
1058
+ buffer_create({ content: '[{"key":"PROJ-1"}]', contentType: "json" }) // String
1059
+ buffer_create({ content: [{"key":"PROJ-1"}], contentType: "json" }) // Native array (auto-stringified)
1060
+ ```
1061
+
1062
+ **Response for XHTML includes**: `bufferId`, `structure` (element IDs), `nextId`, `contentType`, `bufferSizeBytes`
1063
+
1064
+ **Response for JSON includes**: `bufferId`, `contentType`, `bufferSizeBytes`, `structure` (type, itemCount/keys, preview), `hint` (suggested next tool)
871
1065
 
872
- **Response for plain/json includes**: `bufferId`, `contentType`, `totalSize`, `createdAt`, `expiresAt`
1066
+ **Response for plain includes**: `bufferId`, `contentType`, `bufferSizeBytes`, `createdAt`, `expiresAt`
873
1067
 
874
1068
  **CDATA Detection**: For XHTML content, the tool detects if content is incorrectly wrapped in `<![CDATA[...]]>` and returns a clear error. CDATA should only be used inside `<ac:plain-text-body>` elements (for code blocks and PlantUML), never around the entire content.
875
1069
 
@@ -898,8 +1092,12 @@ Buffer tools are used for local content management. All buffer operations are in
898
1092
  ---
899
1093
 
900
1094
  ### 2. buffer_get_chunk
901
- **Description**: Retrieve a chunk of buffered content by buffer ID
902
- **Use Cases**: Get remaining content from large responses, retrieve edited content
1095
+ **Description**: Retrieve raw character chunks from a buffer. Returns raw content by character offset.
1096
+ **Use Cases**: Plain text buffers only, raw character access
1097
+
1098
+ **BLOCKED FOR**: JSON arrays and XHTML content. Use instead:
1099
+ - JSON arrays: `buffer_get_items` - returns complete items
1100
+ - XHTML: `buffer_get_element` - returns element content
903
1101
 
904
1102
  | Parameter | Type | Required | Description |
905
1103
  |-----------|------|----------|-------------|
@@ -909,9 +1107,58 @@ Buffer tools are used for local content management. All buffer operations are in
909
1107
 
910
1108
  **Response includes**: `bufferId`, `content`, `offset`, `limit`, `totalSize`, `hasMore`, `metadata`
911
1109
 
1110
+ **Error on JSON/XHTML**: Returns error with guidance to use correct tool
1111
+
912
1112
  ---
913
1113
 
914
- ### 3. buffer_get_element
1114
+ ### 3. buffer_get_items
1115
+ **Description**: Retrieve complete JSON array items from a buffer. Unlike `buffer_get_chunk` which may truncate mid-item, this returns whole items.
1116
+ **Use Cases**: Iterate through search results, process items in batches, inspect specific items
1117
+
1118
+ | Parameter | Type | Required | Description |
1119
+ |-----------|------|----------|-------------|
1120
+ | bufferId | string | ✓ | Buffer ID containing JSON array |
1121
+ | start | number | ✗ | Starting index (0-based, default: 0) |
1122
+ | count | number | ✗ | Number of items to return (default: 10, max: 100) |
1123
+
1124
+ **Type Requirement**: Buffer must have `contentType: "json"`. Returns error if buffer is XHTML or plain text.
1125
+
1126
+ **Response includes**: `bufferId`, `items` (array of parsed objects), `start`, `count`, `totalItems`, `hasMore`, `itemSchema` (field names in items)
1127
+
1128
+ **Example - Get first 10 items:**
1129
+ ```typescript
1130
+ buffer_get_items({
1131
+ bufferId: "buf_xxx",
1132
+ start: 0,
1133
+ count: 10
1134
+ })
1135
+ // Returns: {
1136
+ // items: [{key: "PROJ-1", ...}, {key: "PROJ-2", ...}, ...],
1137
+ // start: 0,
1138
+ // count: 10,
1139
+ // totalItems: 578,
1140
+ // hasMore: true,
1141
+ // itemSchema: ["key", "summary", "status", "priority", ...]
1142
+ // }
1143
+ ```
1144
+
1145
+ **Example - Page through results:**
1146
+ ```typescript
1147
+ // Page 1
1148
+ buffer_get_items({ bufferId: "buf_xxx", start: 0, count: 50 })
1149
+ // Page 2
1150
+ buffer_get_items({ bufferId: "buf_xxx", start: 50, count: 50 })
1151
+ // Page 3
1152
+ buffer_get_items({ bufferId: "buf_xxx", start: 100, count: 50 })
1153
+ ```
1154
+
1155
+ **When to use `buffer_get_items` vs `buffer_get_chunk`:**
1156
+ - Use `buffer_get_items` for JSON array buffers when you need complete items
1157
+ - Use `buffer_get_chunk` for XHTML/plain text or when you need raw character access
1158
+
1159
+ ---
1160
+
1161
+ ### 4. buffer_get_element
915
1162
  **Description**: Get the raw XHTML content of a specific element by ID. Use to inspect problematic elements when fixing XHTML parsing errors.
916
1163
  **Use Cases**: Debug XHTML validation errors, inspect element content before editing, targeted error recovery
917
1164
 
@@ -920,6 +1167,8 @@ Buffer tools are used for local content management. All buffer operations are in
920
1167
  | bufferId | string | ✓ | Buffer ID containing XHTML content |
921
1168
  | elementId | number | ✓ | Element ID from buffer structure |
922
1169
 
1170
+ **Type Requirement**: Buffer must have `contentType: "xhtml"`. Returns error if buffer is JSON or plain text.
1171
+
923
1172
  **Response includes**: `bufferId`, `elementId`, `elementType`, `lineCount`, `content`
924
1173
 
925
1174
  **Example - Inspect problematic element after XHTML error:**
@@ -942,7 +1191,7 @@ buffer_get_element({
942
1191
 
943
1192
  ---
944
1193
 
945
- ### 4. buffer_list
1194
+ ### 5. buffer_list
946
1195
  **Description**: List all active buffers with their metadata
947
1196
  **Use Cases**: View active buffers, check expiration times
948
1197
 
@@ -954,7 +1203,7 @@ buffer_get_element({
954
1203
 
955
1204
  ---
956
1205
 
957
- ### 5. buffer_clear
1206
+ ### 6. buffer_clear
958
1207
  **Description**: Clear a specific buffer or all buffers
959
1208
  **Use Cases**: Free up memory, clean up after processing
960
1209
 
@@ -966,8 +1215,8 @@ buffer_get_element({
966
1215
 
967
1216
  ---
968
1217
 
969
- ### 6. buffer_grep
970
- **Description**: Search buffered content for patterns (regex supported)
1218
+ ### 7. buffer_grep
1219
+ **Description**: Search buffered content for patterns. Supports regex, context lines (-A/-B/-C), and case-insensitive (-i). Large results are buffered.
971
1220
  **Use Cases**: Find specific content in large responses, locate text for editing
972
1221
 
973
1222
  | Parameter | Type | Required | Description |
@@ -976,17 +1225,288 @@ buffer_get_element({
976
1225
  | pattern | string | ✓ | Regex pattern to search for |
977
1226
  | -A | number | ✗ | Lines to show after each match |
978
1227
  | -B | number | ✗ | Lines to show before each match |
979
- | -C | number | ✗ | Lines to show before AND after |
1228
+ | -C | number | ✗ | Lines to show before AND after (overrides -A/-B) |
980
1229
  | -i | boolean | ✗ | Case insensitive search |
981
1230
  | -n | boolean | ✗ | Show line numbers (default: true) |
982
- | output_mode | string | ✗ | "content" or "count" |
1231
+ | output_mode | string | ✗ | "content" shows matching lines, "count" shows match count |
1232
+ | multiline | boolean | ✗ | Enable multiline mode where `.` matches newlines |
1233
+ | head_limit | number | ✗ | Limit to first N matches |
1234
+ | offset | number | ✗ | Skip first N matches |
983
1235
 
984
1236
  **Response includes**: `totalMatches`, `matches` with line numbers and context
985
1237
 
986
1238
  ---
987
1239
 
988
- ### 7. buffer_edit
989
- **Description**: Edit buffer content. For XHTML: use element IDs (single or batch). For plain/json: use string replacement.
1240
+ ### 8. buffer_pipeline
1241
+ **Description**: Transform JSON buffer data with a declarative pipeline: select fields, filter, group/aggregate, sort, format, and output to various formats.
1242
+ **Use Cases**: Server-side data transformation to minimize token usage, generate XHTML tables for Confluence, export to CSV/Markdown, aggregate statistics
1243
+
1244
+ **Token Efficiency**: A pipeline that filters, sorts, and outputs a table executes in **1 tool call** instead of iterating through items. For pure data transforms, this achieves **98% token reduction**.
1245
+
1246
+ **Schema Quick Reference:**
1247
+ ```json
1248
+ {
1249
+ "sourceBufferId": "buf_xxx",
1250
+ "pipeline": {
1251
+ "select": { "fields": [...] },
1252
+ "filter": [...],
1253
+ "groupBy": { "field": "...", "aggregations": [...] },
1254
+ "sort": [...],
1255
+ "limit": 10,
1256
+ "format": [...],
1257
+ "output": { "type": "xhtml_table", "table": {...} }
1258
+ }
1259
+ }
1260
+ ```
1261
+
1262
+ **Common Mistakes:**
1263
+
1264
+ | Wrong | Correct | Why |
1265
+ |-------|---------|-----|
1266
+ | `sortBy: [...]` | `sort: [...]` | Key name is "sort" not "sortBy" |
1267
+ | `transform: "map"` | `transform: "date"` | Valid: uppercase, lowercase, date, number, boolean, string |
1268
+ | No `output` | `output: {...}` | Required field - pipeline must have output |
1269
+ | `pipeline: "{...}"` | `pipeline: {...}` | Must be object, not JSON string |
1270
+ | After select: `sort: [{field: "issueType"}]` | `sort: [{field: "Type"}]` | After `select` renames "issueType" to "Type", use NEW name |
1271
+
1272
+ | Parameter | Type | Required | Description |
1273
+ |-----------|------|----------|-------------|
1274
+ | bufferId | string | ✓ | Source buffer ID containing JSON array |
1275
+ | pipeline | object | ✓ | Pipeline definition (see below) |
1276
+
1277
+ **Type Requirement**: Buffer must have `contentType: "json"`. Returns error if buffer is XHTML or plain text.
1278
+
1279
+ **Pipeline Definition:**
1280
+
1281
+ ```typescript
1282
+ {
1283
+ // Stage 1: Select specific fields (optional)
1284
+ select?: {
1285
+ fields: [
1286
+ { from: "key" }, // Keep field as-is
1287
+ { from: "priority.name", as: "Priority" }, // Rename field
1288
+ { from: "created", transform: "date" } // Transform value
1289
+ ]
1290
+ },
1291
+
1292
+ // Stage 2: Filter items (optional, AND logic between conditions)
1293
+ filter?: [
1294
+ { field: "status.name", operator: "ne", value: "Done" },
1295
+ { field: "priority.name", operator: "in", value: ["High", "Critical"] }
1296
+ ],
1297
+
1298
+ // Stage 3: Group and aggregate (optional)
1299
+ groupBy?: {
1300
+ field: "assignee.displayName",
1301
+ aggregations: [
1302
+ { function: "count", as: "totalIssues" },
1303
+ { function: "sum", field: "timeSpent", as: "totalTime" },
1304
+ { function: "list", field: "key", as: "issueKeys" }
1305
+ ]
1306
+ },
1307
+
1308
+ // Stage 4: Sort results (optional)
1309
+ sort?: [
1310
+ { field: "priority.name", direction: "asc" },
1311
+ { field: "key", direction: "desc" }
1312
+ ],
1313
+
1314
+ // Stage 5: Limit results (optional)
1315
+ limit?: 50,
1316
+
1317
+ // Stage 6: Conditional formatting (optional)
1318
+ format?: [
1319
+ {
1320
+ condition: { field: "priority.name", operator: "eq", value: "High" },
1321
+ style: { color: "#dc3545", bold: true }
1322
+ },
1323
+ {
1324
+ condition: { field: "status.name", operator: "eq", value: "Done" },
1325
+ style: { color: "#28a745", icon: "✓" }
1326
+ }
1327
+ ],
1328
+
1329
+ // Stage 7: Output configuration (REQUIRED)
1330
+ output: {
1331
+ type: "xhtml_table", // or "xhtml_list", "json", "csv", "markdown"
1332
+ table: {
1333
+ title: "Open Issues",
1334
+ columns: [
1335
+ { field: "key", header: "Issue", link: { type: "jira" } },
1336
+ { field: "summary", header: "Summary" },
1337
+ { field: "priority.name", header: "Priority" }
1338
+ ]
1339
+ }
1340
+ }
1341
+ }
1342
+ ```
1343
+
1344
+ **Filter Operators:**
1345
+
1346
+ | Operator | Description | Example |
1347
+ |----------|-------------|---------|
1348
+ | `eq` | Equals | `{ field: "status.name", operator: "eq", value: "Open" }` |
1349
+ | `ne` | Not equals | `{ field: "status.name", operator: "ne", value: "Done" }` |
1350
+ | `gt`, `lt`, `gte`, `lte` | Numeric comparison | `{ field: "priority.id", operator: "gt", value: 2 }` |
1351
+ | `contains` | Substring match (case-insensitive) | `{ field: "summary", operator: "contains", value: "bug" }` |
1352
+ | `startsWith`, `endsWith` | String prefix/suffix | `{ field: "key", operator: "startsWith", value: "PROJ-" }` |
1353
+ | `in`, `notIn` | Value in array | `{ field: "priority.name", operator: "in", value: ["High", "Critical"] }` |
1354
+ | `exists`, `notExists` | Field presence | `{ field: "assignee", operator: "exists" }` |
1355
+ | `empty`, `notEmpty` | Empty string/array/null | `{ field: "labels", operator: "notEmpty" }` |
1356
+ | `regex` | Regular expression | `{ field: "summary", operator: "regex", value: "^\\[BUG\\]" }` |
1357
+
1358
+ **Aggregation Functions:**
1359
+
1360
+ | Function | Description | Requires `field` |
1361
+ |----------|-------------|------------------|
1362
+ | `count` | Count items in group | No |
1363
+ | `sum` | Sum numeric values | Yes |
1364
+ | `avg` | Average numeric values | Yes |
1365
+ | `min`, `max` | Min/max numeric values | Yes |
1366
+ | `first`, `last` | First/last value | Yes |
1367
+ | `list` | Collect all values | Yes |
1368
+ | `unique` | Unique values | Yes |
1369
+
1370
+ **Output Types:**
1371
+
1372
+ | Type | Description | Config |
1373
+ |------|-------------|--------|
1374
+ | `xhtml_table` | Confluence-compatible table | `table: { title?, columns: [...], showRowNumbers? }` |
1375
+ | `xhtml_list` | Confluence-compatible list | `list: { title?, template: "{{key}}: {{summary}}", style?: "bullet"|"numbered"|"none" }` |
1376
+ | `json` | Clean JSON array | `includeMetadata?: boolean` |
1377
+ | `csv` | CSV with headers | `table: { columns: [...] }` |
1378
+ | `markdown` | Markdown table | `table: { columns: [...] }` |
1379
+
1380
+ **Column Configuration:**
1381
+
1382
+ ```typescript
1383
+ {
1384
+ field: "key", // Field path (dot notation)
1385
+ header: "Issue", // Column header text
1386
+ link?: { type: "jira" }, // Auto-link (jira, confluence, url)
1387
+ width?: "100px", // Column width
1388
+ align?: "left" | "center" | "right"
1389
+ }
1390
+ ```
1391
+
1392
+ **Response includes**: `bufferId` (new output buffer), `inputItems`, `outputItems`, `pipelineStages`, `outputType`, `preview`, `bufferSizeBytes`, `structure` (for XHTML), `hint`
1393
+
1394
+ **Example - Filter and output table:**
1395
+ ```typescript
1396
+ // Search returns bufferId with 500 issues
1397
+ jira_search_issues({ jql: "project = PROJ" })
1398
+ // -> { bufferId: "buf_issues", structure: { itemCount: 500 } }
1399
+
1400
+ // Transform in ONE call (instead of iterating 500 items)
1401
+ buffer_pipeline({
1402
+ bufferId: "buf_issues",
1403
+ pipeline: {
1404
+ filter: [
1405
+ { field: "issuetype.name", operator: "eq", value: "Bug" },
1406
+ { field: "status.name", operator: "ne", value: "Done" }
1407
+ ],
1408
+ sort: [{ field: "priority.name", direction: "asc" }],
1409
+ limit: 20,
1410
+ format: [
1411
+ { condition: { field: "priority.name", operator: "eq", value: "High" },
1412
+ style: { color: "#dc3545", bold: true } }
1413
+ ],
1414
+ output: {
1415
+ type: "xhtml_table",
1416
+ table: {
1417
+ title: "Top 20 Open Bugs",
1418
+ columns: [
1419
+ { field: "key", header: "Issue", link: { type: "jira" } },
1420
+ { field: "summary", header: "Summary" },
1421
+ { field: "priority.name", header: "Priority" },
1422
+ { field: "assignee.displayName", header: "Assignee" }
1423
+ ]
1424
+ }
1425
+ }
1426
+ }
1427
+ })
1428
+ // -> { bufferId: "buf_result", outputItems: 15, preview: "<table>...", structure: [...] }
1429
+ ```
1430
+
1431
+ **Example - Group by assignee with aggregations:**
1432
+ ```typescript
1433
+ buffer_pipeline({
1434
+ bufferId: "buf_issues",
1435
+ pipeline: {
1436
+ filter: [{ field: "status.name", operator: "ne", value: "Done" }],
1437
+ groupBy: {
1438
+ field: "assignee.displayName",
1439
+ aggregations: [
1440
+ { function: "count", as: "issueCount" },
1441
+ { function: "list", field: "key", as: "issues" }
1442
+ ]
1443
+ },
1444
+ sort: [{ field: "issueCount", direction: "desc" }],
1445
+ output: {
1446
+ type: "xhtml_table",
1447
+ table: {
1448
+ title: "Issues by Assignee",
1449
+ columns: [
1450
+ { field: "displayName", header: "Assignee" },
1451
+ { field: "issueCount", header: "Count" },
1452
+ { field: "issues", header: "Issues" }
1453
+ ]
1454
+ }
1455
+ }
1456
+ }
1457
+ })
1458
+ ```
1459
+
1460
+ **Example - Export to CSV:**
1461
+ ```typescript
1462
+ buffer_pipeline({
1463
+ bufferId: "buf_issues",
1464
+ pipeline: {
1465
+ select: {
1466
+ fields: [
1467
+ { from: "key" },
1468
+ { from: "summary" },
1469
+ { from: "status.name", as: "Status" },
1470
+ { from: "created", transform: "date" }
1471
+ ]
1472
+ },
1473
+ output: {
1474
+ type: "csv",
1475
+ table: {
1476
+ columns: [
1477
+ { field: "key", header: "Issue" },
1478
+ { field: "summary", header: "Summary" },
1479
+ { field: "Status", header: "Status" },
1480
+ { field: "created", header: "Created" }
1481
+ ]
1482
+ }
1483
+ }
1484
+ }
1485
+ })
1486
+ // -> { bufferId: "buf_csv", output: "Issue,Summary,Status,Created\nPROJ-1,..." }
1487
+ ```
1488
+
1489
+ **Common Jira Fields:**
1490
+ - `key`, `summary`, `description`
1491
+ - `status.name`, `priority.name`, `issuetype.name`
1492
+ - `assignee.displayName`, `reporter.displayName`
1493
+ - `created`, `updated`, `resolutiondate`
1494
+ - `labels` (array), `components[].name`
1495
+ - `timeoriginalestimate`, `timeestimate`, `timespent`
1496
+
1497
+ **Workflow - Jira to Confluence table:**
1498
+ ```
1499
+ 1. jira_search_issues(jql) → bufferId with JSON
1500
+ 2. buffer_pipeline(bufferId, pipeline) → bufferId with XHTML table
1501
+ 3. confluence_edit(pageId) → page bufferId
1502
+ 4. buffer_edit(pageBufferId, after=ID, fromBufferId=tableBufferId)
1503
+ 5. confluence_draft_create(pageId, pageBufferId) → draft for review
1504
+ ```
1505
+
1506
+ ---
1507
+
1508
+ ### 9. buffer_edit
1509
+ **Description**: Edit buffer content. For XHTML: use element IDs (single or batch). For plain/json: use string replacement or append.
990
1510
  **Use Cases**: Insert/replace/remove elements in Confluence pages, modify Jira/Tempo content, compose content from multiple buffers
991
1511
 
992
1512
  **XHTML Parameters (single operation):**
@@ -1023,6 +1543,14 @@ buffer_get_element({
1023
1543
  | new_string | string | ✓ | Replacement text |
1024
1544
  | replace_all | boolean | ✗ | Replace all occurrences (default: false) |
1025
1545
 
1546
+ **Plain/JSON Parameters (append):**
1547
+
1548
+ | Parameter | Type | Required | Description |
1549
+ |-----------|------|----------|-------------|
1550
+ | bufferId | string | ✓ | Buffer ID to modify |
1551
+ | append | boolean | ✓ | Must be `true` |
1552
+ | content | string | ✓ | Text to append at end of buffer |
1553
+
1026
1554
  **Key Feature - Stable Element IDs**: Element IDs never change when content is inserted or deleted. After inserting between elements 2 and 3, element 3 keeps its ID - only the new element gets a new ID.
1027
1555
 
1028
1556
  **XHTML Response includes**: `success`, `operationsCompleted`, `structure`, `nextId`, `insertedIds`, `diagramTypes`
@@ -1109,7 +1637,7 @@ confluence_draft_create({ pageId: "123", bufferId: "buf_A" })
1109
1637
 
1110
1638
  ---
1111
1639
 
1112
- ### 8. buffer_get_structure
1640
+ ### 10. buffer_get_structure
1113
1641
  **Description**: Get current element structure for an XHTML buffer
1114
1642
  **Use Cases**: View element IDs for editing, understand document structure
1115
1643
 
@@ -1117,6 +1645,8 @@ confluence_draft_create({ pageId: "123", bufferId: "buf_A" })
1117
1645
  |-----------|------|----------|-------------|
1118
1646
  | bufferId | string | ✓ | Buffer ID to get structure for |
1119
1647
 
1648
+ **Type Requirement**: Buffer must have `contentType: "xhtml"`. Returns error if buffer is JSON or plain text.
1649
+
1120
1650
  **Response includes**: `bufferId`, `structure`, `nextId`
1121
1651
 
1122
1652
  **Structure Format**:
@@ -1141,19 +1671,27 @@ buffer_get_structure({ bufferId: "buf_xxx" })
1141
1671
 
1142
1672
  ---
1143
1673
 
1144
- ### 9. buffer_validate_xhtml
1674
+ ### 11. buffer_validate_xhtml
1145
1675
  **Description**: Validate buffered content as Confluence storage format (XHTML)
1146
1676
  **Use Cases**: Check content validity before writing, debug validation errors
1147
1677
 
1148
1678
  | Parameter | Type | Required | Description |
1149
1679
  |-----------|------|----------|-------------|
1150
1680
  | bufferId | string | ✓ | Buffer ID containing XHTML content |
1681
+ | validatePlantUml | boolean | ✗ | Validate PlantUML syntax via Docker service (default: true) |
1682
+
1683
+ **Type Requirement**: Buffer must have `contentType: "xhtml"`. Returns error if buffer is JSON or plain text.
1151
1684
 
1152
1685
  **Validation Checks**:
1153
1686
  - XML well-formedness (balanced tags, proper nesting)
1154
1687
  - Required attributes on Confluence elements (ac:name, ri:space-key, etc.)
1155
1688
  - Valid layout section types (single, two_equal, etc.)
1156
1689
  - Known macro names (warns for unknown macros)
1690
+ - PlantUML syntax (via Docker service, if running)
1691
+
1692
+ **PlantUML validation**:
1693
+ - If Docker service is running, validates all PlantUML macros
1694
+ - If not running, adds warning (use `plantuml_validate` to start the service)
1157
1695
 
1158
1696
  **Response includes**: `valid`, `errorCount`, `warningCount`, `errors`, `warnings`
1159
1697
 
@@ -1161,40 +1699,6 @@ buffer_get_structure({ bufferId: "buf_xxx" })
1161
1699
 
1162
1700
  ---
1163
1701
 
1164
- ### 10. buffer_save_to_file
1165
- **Description**: Save buffer content to a file within the project directory
1166
- **Use Cases**: Export rendered PlantUML diagrams (PNG/EPS), save edited content locally
1167
-
1168
- | Parameter | Type | Required | Description |
1169
- |-----------|------|----------|-------------|
1170
- | bufferId | string | ✓ | Buffer ID containing content to save |
1171
- | outputPath | string | ✓ | Output file path (must be within project directory) |
1172
- | decodeBase64 | boolean | ✗ | Decode base64 content before saving (auto-detected for PNG/EPS) |
1173
-
1174
- **Security**: Files can only be saved within the project directory (must contain `.jicon.json`).
1175
-
1176
- **Binary Content**: Base64-encoded content (e.g., from `plantuml_render` with PNG/EPS format) is automatically decoded when `decodeBase64` is true or when the output path ends with `.png` or `.eps`.
1177
-
1178
- **Response includes**: `success`, `path`, `size`, `message`
1179
-
1180
- **Example - Save PlantUML render**:
1181
- ```typescript
1182
- // 1. Render diagram to PNG
1183
- const result = plantuml_render({
1184
- code: "@startuml\nA -> B\n@enduml",
1185
- format: "png"
1186
- })
1187
- // Returns: { bufferId: "buf_xxx", ... }
1188
-
1189
- // 2. Save to file
1190
- buffer_save_to_file({
1191
- bufferId: "buf_xxx",
1192
- outputPath: "./diagrams/sequence.png"
1193
- })
1194
- ```
1195
-
1196
- ---
1197
-
1198
1702
  ## Workload Tools (2)
1199
1703
 
1200
1704
  Utility tools for time calculations. Always available with any Jira, Confluence, or Tempo action.
@@ -1276,11 +1780,13 @@ fullurl("/display/DOCS/Home") // → https://confluence.example.com/display/DOCS
1276
1780
  | `https://confluence.example.com/display/SPACE/Page+Title` | `{type: "confluence_space_path", spaceKey: "SPACE", title: "Page Title"}` |
1277
1781
  | `https://confluence.example.com/spaces/SPACE/pages/123/Title` | `{type: "confluence_page", pageId: "123", spaceKey: "SPACE", title: "Title"}` |
1278
1782
 
1279
- **Response includes**: `url`, `type`, and extracted fields (`issueKey`, `pageId`, `draftId`, `spaceKey`, `title`)
1783
+ **Response includes**: `url`, `type`, extracted fields (`issueKey`, `pageId`, `draftId`, `spaceKey`, `title`), and `warning` if domain mismatch
1784
+
1785
+ **Domain Validation**: If the URL domain doesn't match the configured JIRA_URL or CONFLUENCE_URL, a warning is included suggesting the correct domain.
1280
1786
 
1281
1787
  **Workflow**:
1282
1788
  ```
1283
- 1. parseurl(url) → extract identifier
1789
+ 1. parseurl(url) → extract identifier (check for warning)
1284
1790
  2. Use extracted ID with appropriate tool (jira_get_issue, confluence_get_page, confluence_edit, etc.)
1285
1791
  ```
1286
1792
 
@@ -1375,7 +1881,7 @@ Include expansion is enabled by default. Whitelisted URLs: `plantuml-stdlib/*`,
1375
1881
 
1376
1882
  **Response includes**: `bufferId` (for large outputs), `content` (for small outputs), `format`, `size`
1377
1883
 
1378
- **Binary Formats**: PNG and EPS outputs are base64-encoded. Use `buffer_save_to_file` to decode and save to disk.
1884
+ **Binary Formats**: PNG and EPS outputs are base64-encoded in the buffer.
1379
1885
 
1380
1886
  **Example - ASCII preview**:
1381
1887
  ```typescript
@@ -1387,18 +1893,6 @@ plantuml_render({
1387
1893
  // Returns ASCII art directly in response
1388
1894
  ```
1389
1895
 
1390
- **Example - Save PNG**:
1391
- ```typescript
1392
- const result = plantuml_render({
1393
- code: "@startuml\nA -> B\n@enduml",
1394
- format: "png"
1395
- })
1396
- buffer_save_to_file({
1397
- bufferId: result.bufferId,
1398
- outputPath: "./diagram.png"
1399
- })
1400
- ```
1401
-
1402
1896
  ---
1403
1897
 
1404
1898
  ### 3. plantuml_status
@@ -1425,25 +1919,45 @@ When using Jicon with AI assistants (Claude, GPT, etc.), follow these patterns f
1425
1919
 
1426
1920
  ### Content Buffering
1427
1921
 
1428
- Tools that return large content (Confluence pages, Jira issues, Tempo worklogs) use an in-memory buffering system for efficient content pagination.
1922
+ All data-heavy tools (search, list, get) **always** return buffered responses with metadata for origin tracking.
1923
+
1924
+ **Response Format (JSON arrays from Jira/Tempo):**
1925
+ ```json
1926
+ {
1927
+ "bufferId": "buf_abc123",
1928
+ "contentType": "json",
1929
+ "structure": { "type": "array", "itemCount": 578 },
1930
+ "metadata": {
1931
+ "resourceType": "jira_search",
1932
+ "title": "JQL: project = PROJ"
1933
+ },
1934
+ "accessors": {
1935
+ "pipeline": { "tool": "buffer_pipeline", "description": "Transform to table/CSV/list" },
1936
+ "get_items": { "tool": "buffer_get_items", "description": "Get complete items for analysis" },
1937
+ "search": { "tool": "buffer_grep", "description": "Search within buffer" }
1938
+ }
1939
+ }
1940
+ ```
1941
+
1942
+ **Metadata Fields:**
1943
+ - `resourceType`: Type of resource (e.g., `jira_issue`, `confluence_page`, `tempo_worklogs`)
1944
+ - `title`: Human-readable description of the buffered content origin
1945
+ - `contentType`: Buffer type (`json`, `xhtml`, `plain`)
1429
1946
 
1430
- **How It Works:**
1431
- 1. **Initial Call**: When you call a tool like `confluence_get_page`, it fetches the full content and stores it in a buffer
1432
- 2. **Chunked Response**: The response includes a `bufferId`, the first chunk of content (default 5000 chars), and pagination info
1433
- 3. **Retrieve More**: Use `buffer_get_chunk` with the `bufferId` to get subsequent chunks
1947
+ **Working with JSON Buffers (Jira/Tempo):**
1948
+ - `buffer_pipeline(bufferId, pipeline)` - Transform to table/CSV/list (98% token reduction)
1949
+ - `buffer_get_items(bufferId, start, count)` - Get complete items for AI analysis
1950
+ - `buffer_grep(bufferId, pattern)` - Search within buffered data
1434
1951
 
1435
- **Buffered Response Format:**
1436
- - `bufferId`: Unique identifier for retrieving more content
1437
- - `content`: The current chunk of content
1438
- - `offset`: Starting position of this chunk
1439
- - `limit`: Maximum characters returned
1440
- - `totalSize`: Total size of buffered content
1441
- - `hasMore`: Whether more content is available
1952
+ **Working with XHTML Buffers (Confluence):**
1953
+ - `buffer_get_structure(bufferId)` - View element IDs for editing
1954
+ - `buffer_edit(bufferId, after=ID, content)` - Edit using element IDs
1955
+ - `buffer_grep(bufferId, pattern)` - Search within buffered data
1442
1956
 
1443
- **Auto-Buffered Tools:**
1444
- - `confluence_get_page`, `confluence_get_page_by_title`
1445
- - `jira_get_issue`, `jira_search_issues`
1446
- - `tempo_get_worklogs`, `tempo_get_team_worklogs`
1957
+ **Always-Buffered Tools:**
1958
+ - **Jira**: `jira_search_issues`, `jira_get_issue`, `jira_list_projects`, `jira_get_project`, `jira_get_board`, `jira_get_sprints`, `jira_get_sprint_issues`, `jira_get_issue_comments`, `jira_get_issue_worklogs`, `jira_get_total_worklogs`
1959
+ - **Confluence**: `confluence_search_content`, `confluence_list_spaces`, `confluence_get_space`, `confluence_get_page_children`, `confluence_get_comments`, `confluence_list_attachments`, `confluence_draft_list`
1960
+ - **Tempo**: `tempo_get_worklogs`, `tempo_get_worklog`, `tempo_get_accounts`, `tempo_get_account`, `tempo_get_teams`, `tempo_get_team`, `tempo_get_team_worklogs`, `tempo_get_epic_worklogs`
1447
1961
 
1448
1962
  **Buffer Management:**
1449
1963
  - **TTL**: Buffers expire after 1 hour by default; edited buffers reset to 1 day TTL
@@ -1476,11 +1990,6 @@ If you created content in a separate buffer and need to insert it into a page:
1476
1990
  3. `buffer_edit(bufferId=bufferId_A, after=5, fromBufferId=bufferId_B)` → merges B into A
1477
1991
  4. `confluence_draft_create(pageId, bufferId=bufferId_A)` → works because bufferId_A originated from pageId
1478
1992
 
1479
- **Saving buffer content to files:**
1480
- - `buffer_save_to_file(bufferId, outputPath)` - Save buffer content to a local file
1481
- - Security: Files can only be saved within project directory (must contain `.jicon.json`)
1482
- - Binary content (PNG/EPS from `plantuml_render`) is auto-decoded from base64
1483
-
1484
1993
  ### Buffer Content Types
1485
1994
 
1486
1995
  **Buffer types determine editing mode:**
@@ -1497,6 +2006,56 @@ If you created content in a separate buffer and need to insert it into a page:
1497
2006
  - Use `buffer_get_structure` to view current element IDs
1498
2007
  - Element IDs are **stable** - they never change when content is inserted/deleted
1499
2008
 
2009
+ ### Buffer Type Requirements
2010
+
2011
+ Tools enforce type-safe buffer access - each tool only accepts buffers of the type it understands. This prevents errors and provides clear guidance.
2012
+
2013
+ | Buffer Type | Tools That REQUIRE This Type |
2014
+ |-------------|------------------------------|
2015
+ | **json** | `buffer_pipeline`, `buffer_get_items` |
2016
+ | **xhtml** | `buffer_get_structure`, `buffer_get_element`, `buffer_validate_xhtml`, `confluence_draft_create` (with bufferId), `confluence_draft_save` |
2017
+ | **any** | `buffer_grep`, `buffer_get_chunk`, `buffer_list`, `buffer_clear`, `buffer_edit` (string mode) |
2018
+
2019
+ **Error Messages**: When you use a tool with the wrong buffer type, you get a helpful error:
2020
+ ```
2021
+ buffer_pipeline requires json buffer, but got: xhtml.
2022
+ For XHTML content, use buffer_edit or buffer_get_structure instead.
2023
+ ```
2024
+
2025
+ **Key Principle**: If you have a JSON buffer (from Jira/Tempo search), use JSON-aware tools (`buffer_pipeline`, `buffer_get_items`). If you have an XHTML buffer (from Confluence), use XHTML-aware tools (`buffer_get_structure`, `buffer_edit` with element IDs).
2026
+
2027
+ ### Large Dataset Patterns
2028
+
2029
+ **Simple table (no AI analysis):**
2030
+ Use `buffer_pipeline` - generates complete table in ONE tool call:
2031
+ ```typescript
2032
+ jira_search_issues({ jql: "project=PROJ" }) // → bufferId (500+ items)
2033
+ buffer_pipeline({ bufferId, pipeline: { output: { type: "xhtml_table", ... } } }) // → complete table!
2034
+ ```
2035
+
2036
+ **Table with AI-enhanced columns (complexity, impact):**
2037
+ Use batch accumulation workflow - analyze items in batches, compose results:
2038
+ ```typescript
2039
+ // 1. Search Jira
2040
+ jira_search_issues({ jql: "..." }) // → sourceBufferId (N items)
2041
+
2042
+ // 2. Create accumulator table
2043
+ buffer_create({
2044
+ content: "<table><thead>...</thead><tbody></tbody></table>",
2045
+ contentType: "xhtml"
2046
+ }) // → accumulatorBufferId, structure (note tbody element ID)
2047
+
2048
+ // 3. For each batch of items:
2049
+ buffer_get_items({ bufferId: sourceBufferId, start: X, count: 50 }) // → items[]
2050
+ // AI analyzes items, builds XHTML rows with AI columns
2051
+ buffer_create({ content: rowsXHTML, contentType: "xhtml" }) // → batchBufferId
2052
+ buffer_edit({ bufferId: accumulatorBufferId, after: lastRowId, fromBufferId: batchBufferId })
2053
+
2054
+ // 4. Insert into page and create draft
2055
+ buffer_edit({ bufferId: pageBufferId, after: ID, fromBufferId: accumulatorBufferId })
2056
+ confluence_draft_create({ pageId, bufferId: pageBufferId }) // → draft for review
2057
+ ```
2058
+
1500
2059
  ### XHTML Structure Editing
1501
2060
 
1502
2061
  Use `buffer_edit` with element IDs for precise editing of Confluence storage format content. Each element gets a unique ID when loaded, which remains stable across edits.
@@ -1608,6 +2167,99 @@ buffer_validate_xhtml({
1608
2167
  **Automatic Validation:**
1609
2168
  XHTML content is automatically validated before Confluence writes (`confluence_draft_create`, `confluence_draft_save`).
1610
2169
 
2170
+ ### JSON Pipeline Workflows
2171
+
2172
+ Use `buffer_pipeline` for efficient server-side data transformation. This eliminates the need to iterate through items in the LLM context.
2173
+
2174
+ **Workflow - Search to Table (98% token reduction):**
2175
+ ```
2176
+ 1. jira_search_issues(jql) → bufferId with JSON array
2177
+ 2. buffer_pipeline(bufferId, pipeline) → bufferId with XHTML/CSV/Markdown
2178
+ 3. Use result directly or insert into Confluence page
2179
+ ```
2180
+
2181
+ **Workflow - Jira Report to Confluence:**
2182
+ ```typescript
2183
+ // 1. Search Jira
2184
+ jira_search_issues({ jql: "project = PROJ AND type = Bug" })
2185
+ // → { bufferId: "buf_issues", structure: { itemCount: 150 } }
2186
+
2187
+ // 2. Transform to table with one call (NOT iterating 150 items!)
2188
+ buffer_pipeline({
2189
+ bufferId: "buf_issues",
2190
+ pipeline: {
2191
+ filter: [{ field: "status.name", operator: "ne", value: "Done" }],
2192
+ sort: [{ field: "priority.name", direction: "asc" }],
2193
+ format: [
2194
+ { condition: { field: "priority.name", operator: "eq", value: "High" },
2195
+ style: { color: "#dc3545", bold: true } }
2196
+ ],
2197
+ output: {
2198
+ type: "xhtml_table",
2199
+ table: {
2200
+ title: "Open Bugs",
2201
+ columns: [
2202
+ { field: "key", header: "Issue", link: { type: "jira" } },
2203
+ { field: "summary", header: "Summary" },
2204
+ { field: "priority.name", header: "Priority" }
2205
+ ]
2206
+ }
2207
+ }
2208
+ }
2209
+ })
2210
+ // → { bufferId: "buf_table", outputItems: 45, preview: "<table>..." }
2211
+
2212
+ // 3. Insert into Confluence page
2213
+ confluence_edit("DOCS/Bug Report")
2214
+ // → { bufferId: "buf_page", pageId: "123", structure: [...] }
2215
+
2216
+ buffer_edit({ bufferId: "buf_page", after: 5, fromBufferId: "buf_table" })
2217
+ confluence_draft_create({ pageId: "123", bufferId: "buf_page" })
2218
+ // → Draft for user review
2219
+ ```
2220
+
2221
+ **Workflow - Statistics Dashboard:**
2222
+ ```typescript
2223
+ // Group issues by assignee with counts
2224
+ buffer_pipeline({
2225
+ bufferId: "buf_issues",
2226
+ pipeline: {
2227
+ filter: [{ field: "status.name", operator: "ne", value: "Done" }],
2228
+ groupBy: {
2229
+ field: "assignee.displayName",
2230
+ aggregations: [
2231
+ { function: "count", as: "total" },
2232
+ { function: "list", field: "key", as: "issues" }
2233
+ ]
2234
+ },
2235
+ sort: [{ field: "total", direction: "desc" }],
2236
+ output: {
2237
+ type: "xhtml_table",
2238
+ table: {
2239
+ title: "Work Distribution",
2240
+ columns: [
2241
+ { field: "displayName", header: "Assignee" },
2242
+ { field: "total", header: "Open Issues" },
2243
+ { field: "issues", header: "Issue Keys" }
2244
+ ]
2245
+ }
2246
+ }
2247
+ }
2248
+ })
2249
+ ```
2250
+
2251
+ **When to Use `buffer_pipeline`:**
2252
+ - Generating tables/lists for Confluence from Jira/Tempo data
2253
+ - Creating CSV/Markdown exports
2254
+ - Aggregating statistics (count by status, sum time by project, etc.)
2255
+ - Filtering and sorting large result sets server-side
2256
+ - Any data transformation that doesn't require LLM reasoning
2257
+
2258
+ **When NOT to Use `buffer_pipeline`:**
2259
+ - When you need to read and understand each item's content
2260
+ - When decisions require LLM judgment (e.g., categorizing by sentiment)
2261
+ - When output format depends on item content analysis
2262
+
1611
2263
  ### Buffer Lifecycle & Staleness Prevention
1612
2264
 
1613
2265
  **Automatic Invalidation**: When write operations succeed (`confluence_draft_save`, `jira_update_issue`, `tempo_update_worklog`, etc.), any cached buffers for that resource are automatically invalidated.