Agent Brief
Category: enhancement Summary: Agents can list the user's server folders, read a folder's messages, and move mail into a folder.
Current behavior:
The MCP tools (list_accounts, list_messages, search_messages, read_message, update_messages, send_email) only know Spark's built-in lists. list_messages takes folder from a fixed enum (inbox, new_senders, snoozed, set_aside, done, trash). Messages in MessageState::Filed (Sent, Drafts, Spam, the user's folders and Gmail labels) can't be listed, and in search results their folder is just "filed". update_messages can't file mail into a folder, although the UI can by dragging (a Patch with folder set).
Desired behavior:
- A new read tool,
list_folders, returns the server folders of the accounts shared with the agent: id, account, name, parent, role (sent, drafts, archive, trash, spam, flagged, or none), and when the folder's messages were last synced. It needs read access, like the other read tools. list_messagescan list one server folder by id, in addition to the existing built-in lists, with the same paging (limit,offset) and filters. A folder whose messages have never been synced, or not recently, says so in the result instead of looking empty. Folders the user isn't watching are only fetched when opened.- Message summaries for filed mail name the folder (its id and name) instead of only
"filed". update_messagesgets a move action that takes a folder id and files the messages there, exactly as dragging them onto that folder does in the UI. It goes through the same undo window, reaches the server the same way, and swaps labels on Gmail. It needs triage access. A folder from a different account than the message is refused with a clear error.- The tool descriptions and the README's AI agents section describe the new capabilities.
Key interfaces:
Store::folders()/Store::folder(id)and theFoldertype (role: Option<FolderRole>,synced_at): the source forlist_folders.- Folder membership (
folder_members,Store::folder_member_ids): which messages a folder holds. Patch::folder: the existing way to file a message. Archive and Trash folders become Done and Deleted. The agent move should use it, not a new path.- Access checks stay inside spark-rs, using the agent
Context's per-account access, as the existing tools do.
Acceptance criteria:
list_foldersreturns only folders of accounts the agent has at least read access to, with the fields above.list_messageswith a folder id returns that folder's messages, newest first, paged like the built-in lists. An unknown folder id, or one in an unshared account, is an error that says what's wrong.search_messagesandlist_messagesresults for filed mail include the folder's id and name.update_messageswith the move action and a folder id files the messages there, and the UI shows the same result as a drag. With read-only access it's refused, and with a folder from another account it's refused.- Unit tests cover the cases above against an in-memory store, like the existing agent tool tests.
cargo clippy --workspace --all-targets -- -D warningsandcargo test --workspacepass.
Out of scope:
- Creating, renaming or deleting folders through agents.
- Creating or editing drafts through agents.
- Smart folders (saved searches) and the sidebar's layout (pins, order, colors).
- The one-click Connect step and skills (#4).