一键导入
joshu-mail
Find/search mail; local cache first, deep server Gmail.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Find/search mail; local cache first, deep server Gmail.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Search Desktop files via gbrain; mail use joshu-mail.
Meeting-mail scheduling. Kanban ea-sched-*; Calendly fallback.
jMail desktop UI workflows — compose drafts, thread navigation, voice fast paths.
Daily handoff — prep yesterday carryover, interactive morning review, finalize today's time block.
Triage mail to Projects. Not drips—use ea-project-kanban.
Drips, pipelines, HITL: Kanban project boards, not todo.md.
| name | joshu-mail |
| description | Find/search mail; local cache first, deep server Gmail. |
| version | 1.3.0 |
| metadata | {"hermes":{"category":"mail","version":"1.3.0"}} |
Platform mechanics: Apps use
@joshu/platform-data(mail.search,mail.sync,connections.status). Agents use MCP tools below orPOST /joshu/api/apps/jmail/invokefor headless actions. This skill covers workflow and escalation — not REST path details. When the jMail GUI is open, loadjmail-guifirst — list/read visible inbox from GUI snapshot; usejoshu-mailonly when mail is not in the loaded list or user wants deep/live search.
General-purpose mail read/search on the Joshu box. Not triage (ea-playbook), not meeting scheduling (ea-scheduling), not multi-step campaigns (ea-project-kanban).
skill_view('joshu-mail') when the user asks to:
owner work email vs agent Nylas)Also load before Composio live Gmail — even if you already ran gbrain.
| Task | Skill |
|---|---|
Process Triage/*.stub.md into Projects | ea-playbook |
| Meeting-mail scheduling | ea-scheduling |
| Drip / Kanban / HITL project work | ea-project-kanban |
| Desktop files, journals (non-mail) | joshu-brain |
${JOSHU_FILES_ROOT}/connectors/mail/gmail/{account_key}/threads/ # owner Gmail (Composio)
${JOSHU_FILES_ROOT}/connectors/mail/nylas/threads/ # agent inbox (Nylas)
Multiple Gmail accounts → match account_key / account_email in frontmatter to the inbox the user named. Agent Nylas mail ≠ principal Gmail unless they asked for it.
| Tier | What | When |
|---|---|---|
| Local cache (fast) | Synced mirror markdown on the box + gbrain | Always start here — steps 1–4 below |
| Deep server-side search | Composio live Gmail against Google’s servers | Only when the local cache does not hit (miss after 1–4, pre-connect mail never mirrored, or user asks to search live) |
Do not treat Composio as “another local grep.” It is a remote search path — heavier, session-based, and correct when mirrors lag or never backfilled.
mcp_gbrain_query — source_id: "__all__", recency: "on", since: "90d", mail keywordsmcp_joshu_connectors_connectors_status — which accounts exist; mirror countsconnectors_sync_now (provider: "gmail") then re-query — not on every turnsearch_files / grep on connectors/mail/gmail/{account_key}/ for exact subjectreferences/composio-gmail-live.mdDetails + MCP tables: references/mail-search-order.md
When the local cache does not hit: mirrors can lag, omit pre-connect history, or simply not contain the thread yet. Deep server-side search via Composio is then correct — not more local grep or another sync loop.
Commit to the dynamic session loop (do not mix with box terminal after step 5):
COMPOSIO_SEARCH_TOOLS → session_id, plan, workbench snippets
COMPOSIO_MULTI_EXECUTE_TOOL → one precise GMAIL_FETCH_EMAILS first
→ inline preview OK? answer user
→ remote_file_info? COMPOSIO_REMOTE_BASH or COMPOSIO_REMOTE_WORKBENCH (mandatory, same session_id)
→ empty/ambiguous inline? WORKBENCH/BASH to parse JSON — not proof mail is absent
Hermes tool names: mcp_composio_COMPOSIO_*.
connectors_status → gmail.accounts[] → email, accountKey, connectedAccountIdowner work email → db_at_project_aeon_com)GMAIL_FETCH_EMAILS: always user_id: "me" — never an email address (delegation denied)connected_account_id: ca_… in SEARCH_TOOLS known_fields; scope OAuth to that account per Composio planuser_id: me hits principal mail if the Composio session is bound to another account| Path | Where | Tool |
|---|---|---|
${JOSHU_FILES_ROOT}/connectors/mail/… | Joshu box | gbrain, search_files, local terminal |
/mnt/files/… in Composio responses | Remote sandbox | COMPOSIO_REMOTE_BASH or COMPOSIO_REMOTE_WORKBENCH only |
After remote_file_info, the next tool call must be BASH or WORKBENCH — never local grep for pick.json.
Use sync_response_to_workbench: true when include_payload: true or many messages expected.
Full session steps, examples, pitfalls: references/composio-gmail-live.md
When the user asks you to send (not find) mail:
mcp_joshu_connectors_nylas_send_message from the agent Nylas mailboxnylas_get_profile for timezone / primaryWorkEmailPOST /joshu/api/nylas/messages/send (action-guard gated)Reply subjects: when replyToMessageId is set, copy the parent subject from the thread mirror exactly (only Re:/Fwd: prefix differences allowed). Decorating the subject (availability, names, task titles) returns reply_subject_mismatch and forks Gmail threading — retry with expectedSubject from the error.
Principal Gmail send/reply: owner jMail only — agent blocked.
When the user says "add X to the email I just sent" or similar:
Find your sent message — list Nylas mirror files sorted by mtime:
ls -lt ${JOSHU_FILES_ROOT}/connectors/mail/nylas/threads/ | head
Read the newest threads; look for ones where from: matches the agent mailbox and the subject/tos match.
Identify the sent message ID — read the mirror file's frontmatter for the external_id (the Nylas message id). Or use nylas_get_message() with a known message id.
Reply-all with the new person — use nylas_send_message with:
replyToMessageId: the sent message's id from step 2cc: include the original recipients PLUS the new person — replying with replyToMessageId threads into the same conversation but doesn't auto-populate the old CC list; you must re-list everyoneto: the original primary recipientPitfall: replyToMessageId only threads the reply — it does NOT preserve the previous To/CC list. You must manually repopulate the CC list with everyone for a true reply-all.
joshu-braindocs/connectors.md