Skip to content

feat: MCP permission tools + rail reorder, image cropping, faster member loading#115

Merged
krazyjakee merged 4 commits into
masterfrom
feat/mcp-permission-tools
Jun 11, 2026
Merged

feat: MCP permission tools + rail reorder, image cropping, faster member loading#115
krazyjakee merged 4 commits into
masterfrom
feat/mcp-permission-tools

Conversation

@krazyjakee

@krazyjakee krazyjakee commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Summary

Bundles the current in-flight working-tree changes across the client and accordkit.

MCP / developer tooling

  • Permission management tools in the in-app MCP client (mcp_tools.dart):
    • Read: list_roles, list_permissions (local enum of valid permission ids + descriptions)
    • Manage (privileged, off by default like moderate): create_role, update_role, delete_role, add_member_role, remove_member_role, and per-channel overwrites list_channel_permissions / set_channel_permission / delete_channel_permission
    • Surfaces the new manage permission group in settings + the developer settings page
    • Includes follow-up review fixes (reject empty-name update_role) and mcp_tools tests

Member roster loading

  • members.list gains a withUser flag — the server embeds each member's user object in one batched query, so the controller skips the per-member fetch. Older servers ignore the flag and fall back to a bounded-concurrency (8) user backfill instead of one request per member.
  • Message rendering only loads the roster when the message actually contains a mention.

Space rail

  • Drag-reorder with insertion gaps between items; reorder spaces within and across folders. moveSpaceToFolder gains a before anchor for precise placement.

Image cropping

  • New shared showImageCropDialog (crop_your_image) with a pan/zoom frame, wired into avatar (circular 1:1), space icon, and banner (16:9) editing.

Admin

  • Open a space directly in the rail via /spaces?space=<id> using the admin's own connection, rather than a public member-join.

Misc

  • Error reporting: navigation breadcrumbs driven off persisted space/channel selection (avoids a settings→reporting dependency cycle).
  • Open-tab strip: keep a tab's captured label in sync on channel rename.

Test plan

  • flutter analyze --no-fatal-infos clean on touched files
  • dart test in packages/accordkit (members withUser endpoint test added)
  • mcp_tools tests added for the new permission tools

🤖 Generated with Claude Code

krazyjakee and others added 2 commits June 11, 2026 16:20
Adds the permission surface to the in-app MCP client (mcp_tools.dart):

Read group:
- list_roles — list a space's roles with their permission sets
- list_permissions — enumerate all known permission ids + descriptions
  (local, no connection needed — lets an agent discover valid strings)

Manage group (privileged, off by default like moderate):
- create_role / update_role / delete_role
- add_member_role / remove_member_role
- list_channel_permissions / set_channel_permission /
  delete_channel_permission — per-channel role/member allow/deny overwrites
  (PUT/DELETE /channels/{id}/permissions/{target_id})

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- _updateRole: guard against empty string name being sent to the API
  when the caller passes `name: ""` explicitly; now returns an error
  instead of forwarding a blank role name
- _listPermissions: drop unnecessary async (no await) — use Future.value
  expression body consistent with other pure handlers
- Add test/features/developer/mcp_tools_test.dart covering tool
  registration groups, list_permissions output, update_role validation,
  set_channel_permission target_type validation, and not-connected
  behaviour for all network-bound manage tools

https://claude.ai/code/session_018dziXgcBzX4ppj7Fed1UY1

Copy link
Copy Markdown
Contributor Author

Code review — findings and fixes (commit 2b3900c)

All findings below have been fixed and pushed to the PR branch.


🔴 HIGH — _updateRole allows empty name to reach the API

File: lib/features/developer/services/mcp_tools.dart · _updateRole

The original code:

if (args.containsKey('name')) data['name'] = (args['name'] ?? '').toString();

If an agent passes name: "" explicitly, the empty string is forwarded to client.roles.update(...). The server would either accept a blank role name or return an opaque error. Fixed with an explicit guard:

if (args.containsKey('name')) {
  final name = (args['name'] ?? '').toString();
  if (name.isEmpty) return {'error': 'name cannot be empty'};
  data['name'] = name;
}

🟡 MEDIUM — _listPermissions unnecessarily marked async

File: lib/features/developer/services/mcp_tools.dart · _listPermissions

The handler never awaits anything but was declared async, causing an unnecessary microtask allocation on every call. Replaced with an expression body using Future.value(...), consistent with other pure handlers in the class (e.g. _openDm).


🟡 MEDIUM — No tests for new tools

File: test/features/developer/mcp_tools_test.dart (new)

No tests existed for the developer MCP layer. Added a test suite covering:

  • Tool registration: all 10 new tools exist and are placed in the correct group (read vs manage)
  • Schema validation: required-field arrays are correct (e.g. set_channel_permission requires channel_id, target_id, target_type)
  • list_permissions handler: returns ok: true, includes all AccordPermission.all() entries with non-empty descriptions
  • update_role validation: rejects name: "" and the no-fields-to-update path
  • set_channel_permission: rejects invalid and empty target_type
  • All network-bound manage tools: return Not connected when no AccordAuthLoggedIn state is present

ℹ️ LOW — Observation: _overwriteBrief skips AccordPermissionOverwrite deserialization (intentional)

channels.listOverwrites returns raw JSON without calling .deserializeArray(AccordPermissionOverwrite.fromJson). _overwriteBrief therefore reads the raw map directly. This is actually correct for round-trip consistency: AccordPermissionOverwrite.fromJson normalises the type field from "member""user" internally, but the MCP set_channel_permission tool accepts "member". By using the raw server response, list_channel_permissions output can be fed directly back into set_channel_permission. No change made, but worth documenting.


ℹ️ File size

mcp_tools.dart is now ~998 lines — just under the 1 000-line threshold. If future tool groups are added here, consider splitting the handlers into a separate _mcp_manage_handlers.dart mixin or part file.


Generated by Claude Code

… open-in-rail

Bundles the in-flight working-tree changes:

- Member roster loading: members.list gains a `withUser` flag (server embeds
  the user object in one batched query); the controller falls back to a
  bounded-concurrency (8) user backfill for older servers, and message
  rendering skips the roster load unless the message contains a mention.
- Space rail: drag-reorder with insertion gaps between items, reordering
  within and across folders (moveSpaceToFolder gains a `before` anchor).
- Image cropping: new shared showImageCropDialog (crop_your_image) with a
  pan/zoom frame; wired into avatar (circular 1:1), space icon and banner
  (16:9) editing.
- Admin: open a space directly in the rail via `/spaces?space=<id>` using the
  admin's own connection instead of a public join.
- Error reporting: navigation breadcrumbs driven off persisted space/channel
  selection (avoids a settings->reporting dependency cycle).
- Open-tab strip: keep a tab's captured label in sync on channel rename.
- Developer/MCP: surface the new `manage` permission group in settings + the
  developer settings page.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@krazyjakee krazyjakee changed the title feat(developer): MCP role & channel-permission management tools feat: MCP permission tools + rail reorder, image cropping, faster member loading Jun 11, 2026
…ch tests

create_role now reports not-connected before name validation; update_role
validates fields before the connection check.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@krazyjakee krazyjakee merged commit 2fc7685 into master Jun 11, 2026
5 checks passed
@krazyjakee krazyjakee deleted the feat/mcp-permission-tools branch June 11, 2026 17:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants