You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Represent permissions as explicit group and access entries so MCP clients receive a machine-readable JSON Schema, while preserving Discourse's numeric map at the HTTP boundary. Treat blank parent tag placeholders as omitted to avoid unintended parent clearing during updates.
Copy file name to clipboardExpand all lines: CHANGELOG.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -11,8 +11,8 @@
11
11
- Advertise output schemas and identical JSON-text fallbacks; malformed upstream records now produce normal tool errors
12
12
13
13
* Add the dedicated opt-in `tag_groups` lifecycle toolset
14
-
- Add public Guardian-filtered search, authoritative staff list/detail, deterministic optimistic state hashes, and exact numeric permission contracts
15
-
- Add guarded create, complete-state update, and hard delete with local ID/name/hash preflights, tag-creation/replacement/cascade confirmations, non-retried writes, and authoritative post-state/absence verification
14
+
- Add public Guardian-filtered search, authoritative staff list/detail, deterministic optimistic state hashes, and explicit `{group_id, access}`permission entries that are machine-readable in MCP JSON Schema and converted to Discourse's numeric map only at the HTTP boundary
15
+
- Add guarded create, complete-state update, and hard delete with local ID/name/hash preflights, tag-creation/replacement/cascade confirmations, non-retried writes, and authoritative post-state/absence verification; tolerate blank optional `parent_tag` placeholders as omission while reserving explicit `null` for update-time clearing
16
16
- Report uncertain post-dispatch outcomes without structured success or blind-retry advice; document scoped-key, plugin-dependency, tagging-setting, and deletion-cascade limits
17
17
18
18
* Add top-level CLI metadata and cross-platform profile home expansion
Copy file name to clipboardExpand all lines: README.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -246,7 +246,7 @@ Select the dedicated `tag_groups` domain for six tools:
246
246
247
247
1.`discourse_search_tag_groups` is public, Guardian-filtered discovery. It always sends an explicit limit and reports possible truncation. Search omits tag-group IDs, parents, and permissions, so it is not authoritative inventory; case-insensitive exact group names are the correlation key. `q` and `names` combine with AND semantics, and upstream treats `%`/`_` as SQL LIKE wildcards.
248
248
2.`discourse_list_tag_groups` and `discourse_get_tag_group` require configured API credential shape plus upstream **staff** authority. The local helper cannot prove a staff role; Discourse is authoritative and privacy-preservingly returns 404 to non-staff. Reads can work when tagging is disabled.
249
-
3.`discourse_create_tag_group`, `discourse_update_tag_group`, and `discourse_delete_tag_group` additionally require effective write mode and upstream `tagging_enabled`. Permissions are complete numeric maps: `1` = full, `3` = readonly, and group ID `0` = everyone. New selector names require `allow_tag_creation=true` because persistent tags are created and normal indexing/plugin hooks run.
249
+
3.`discourse_create_tag_group`, `discourse_update_tag_group`, and `discourse_delete_tag_group` additionally require effective write mode and upstream `tagging_enabled`. MCP inputs and normalized outputs represent permissions as explicit entries, for example `[{"group_id":0,"access":"full"},{"group_id":9,"access":"readonly"}]`; group ID `0` is Discourse's built-in everyone group. The server converts these entries to Discourse's numeric permission map (`1` = full, `3` = readonly) only at the HTTP boundary. `parent_tag` is an optional `{id}` or `{name}` selector: omit it or use `null` when creating without a parent; blank client placeholders are treated as omitted. New selector names require `allow_tag_creation=true` because persistent tags are created and normal indexing/plugin hooks run.
250
250
4. Updates require a fresh `expected_state_hash`, merge omitted fields locally, and send complete tags/parent/one-per-topic/permissions because partial upstream bodies clear state. Tag/parent removals, permission replacement, and possible materialization of serializer-synthesized everyone/full legacy permissions require explicit confirmations (including `acknowledge_possible_synthetic_permission_materialization`). The hash is an MCP optimistic precondition, not an upstream atomic lock; races can still occur after preflight.
251
251
5. Deletes require exact ID/name/hash plus explicit cascade and unresolved-plugin acknowledgements. Deletion cascades memberships, permissions, and category allowed/required relationships, but does not delete tags or topic-tag rows. Plugin dependency discovery is not exhaustive. Discourse's scoped API-key action map may not authorize delete. A 200 acknowledgement is not success until a post-delete GET proves absence; uncertain post-dispatch outcomes are non-retryable `outcome_unknown` errors.
0 commit comments