MCPcopy Create free account
hub / github.com/Mnexa-AI/e2a / registerReviewTools

Function registerReviewTools

mcp/src/tools/review.ts:7–121  ·  view source on GitHub ↗
(server: McpServer, client: McpClient)

Source from the content-addressed store, hash-verified

5import { attachmentsArraySchema } from "./attachments.js";
6
7export function registerReviewTools(server: McpServer, client: McpClient): void {
8 server.registerTool(
9 "list_pending_messages",
10 {
11 title: "List outbound messages awaiting approval",
12 annotations: { readOnlyHint: true },
13 description:
14 "Use when the user asks what's awaiting approval, or after a `send_message`/`reply_to_message` returned `pending_review` and they want to see the queue. Lists held **outbound** messages (held by the agent's outbound policy or content scan) sorted by soonest-expiring first. Body content is summary-only — call `get_pending_message` for the full draft of one. Read-only; cheap, but don't poll it on a loop. Note: this lists OUTBOUND holds only — a held **inbound** message (screening review) is surfaced by the `email.pending_review` webhook (with its `message_id`), not here, and is resolved with the same `approve_message`/`reject_message` tools.",
15 inputSchema: strictInputSchema({}),
16 },
17 async () => runTool(async () => ({ messages: await client.listPendingMessages() })),
18 );
19
20 server.registerTool(
21 "get_pending_message",
22 {
23 title: "Get a pending-approval message",
24 annotations: { readOnlyHint: true },
25 description:
26 "Fetch the full draft (subject, recipients, body, attachments) of one outbound message awaiting human approval. Body content is only present while the message is `pending_review` — after a terminal transition the server scrubs it.",
27 inputSchema: strictInputSchema({
28 message_id: z.string().describe("The pending message ID (msg_…)."),
29 }),
30 },
31 async (args) => runTool(() => client.getPendingMessage(args.message_id)),
32 );
33
34 // Map the snake_case approve override args to the SDK's ApproveRequest
35 // (camelCase body fields). An explicitly-passed empty attachments array
36 // must survive as a strip override, so map by key-presence.
37 const mapOverrides = (overrides: {
38 subject?: string;
39 body_text?: string;
40 body_html?: string;
41 to?: string[];
42 cc?: string[];
43 bcc?: string[];
44 attachments?: Array<{ filename: string; content_type: string; data: string }>;
45 }) => ({
46 ...(overrides.subject !== undefined ? { subject: overrides.subject } : {}),
47 ...(overrides.body_text !== undefined ? { body: overrides.body_text } : {}),
48 ...(overrides.body_html !== undefined ? { htmlBody: overrides.body_html } : {}),
49 ...(overrides.to !== undefined ? { to: overrides.to } : {}),
50 ...(overrides.cc !== undefined ? { cc: overrides.cc } : {}),
51 ...(overrides.bcc !== undefined ? { bcc: overrides.bcc } : {}),
52 ...(overrides.attachments !== undefined
53 ? {
54 attachments: overrides.attachments.map((a) => ({
55 filename: a.filename,
56 contentType: a.content_type,
57 data: a.data,
58 })),
59 }
60 : {}),
61 });
62
63 server.registerTool(
64 "approve_message",

Callers 2

buildServerFunction · 0.85
tools.test.tsFile · 0.85

Calls 7

strictInputSchemaFunction · 0.85
runToolFunction · 0.85
mapOverridesFunction · 0.85
listPendingMessagesMethod · 0.80
getPendingMessageMethod · 0.80
approveMessageMethod · 0.45
rejectMessageMethod · 0.45

Tested by

no test coverage detected