hey_pop_bubble
Remove an email from the bubble view, returning it to the inbox without deleting or archiving it.
Instructions
Pop (dismiss) a bubbled-up email so it sinks back into the Imbox. The email is not deleted or archived — it just stops being pinned at the top.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| posting_id | Yes | The posting ID to pop/unbubble |
Implementation Reference
- src/index.ts:938-952 (registration)Tool registration for 'hey_pop_bubble' in the tools array with name 'hey_pop_bubble', description and inputSchema requiring posting_id.
{ name: "hey_pop_bubble", description: "Pop (dismiss) a bubbled-up email so it sinks back into the Imbox. The email is not deleted or archived — it just stops being pinned at the top.", inputSchema: { type: "object" as const, properties: { posting_id: { type: "string", description: "The posting ID to pop/unbubble", }, }, required: ["posting_id"], }, }, - src/index.ts:1743-1758 (handler)Switch-case handler in CallToolRequestSchema that validates posting_id and calls popBubble(postingId).
case "hey_pop_bubble": { const postingId = validateId(args?.posting_id) if (!postingId) { return { content: [ { type: "text", text: "Error: posting_id is required and must be valid", }, ], isError: true, } } result = await popBubble(postingId) break } - src/tools/organise.ts:473-491 (handler)Core handler function popBubble that performs a DELETE request to /postings/bubble_up endpoint with the posting ID and invalidates cache on success.
/** * Pop (dismiss) a bubbled-up email so it sinks back into the Imbox. */ export async function popBubble(postingId: string): Promise<OrganiseResult> { if (!postingId) { return { success: false, error: "Posting ID is required" } } try { const endpoint = `/postings/bubble_up?posting_ids[]=${postingId}` const response = await withCsrfRetry(() => heyClient.delete(endpoint)) return organiseResponseToResult(response, () => invalidateForAction("bubble_up", postingId), ) } catch (err) { return { success: false, error: toUserError(err) } } } - src/index.ts:942-951 (schema)Input schema for hey_pop_bubble tool requiring posting_id (string).
inputSchema: { type: "object" as const, properties: { posting_id: { type: "string", description: "The posting ID to pop/unbubble", }, }, required: ["posting_id"], }, - src/tools/organise.ts:476-497 (helper)Cache invalidation via invalidateForAction('bubble_up', postingId) after successful pop.
export async function popBubble(postingId: string): Promise<OrganiseResult> { if (!postingId) { return { success: false, error: "Posting ID is required" } } try { const endpoint = `/postings/bubble_up?posting_ids[]=${postingId}` const response = await withCsrfRetry(() => heyClient.delete(endpoint)) return organiseResponseToResult(response, () => invalidateForAction("bubble_up", postingId), ) } catch (err) { return { success: false, error: toUserError(err) } } } /** * Schedule an email to bubble up ONLY if there's no reply by a specific date. */ export async function bubbleUpIfNoReply( postingId: string,