Skip to content

Commit 032006c

Browse files
authored
Add voice SSE endpoint and thread summary tool to MCP agent (#1884)
# READ CAREFULLY THEN REMOVE Remove bullet points that are not relevant. PLEASE REFRAIN FROM USING AI TO WRITE YOUR CODE AND PR DESCRIPTION. IF YOU DO USE AI TO WRITE YOUR CODE PLEASE PROVIDE A DESCRIPTION AND REVIEW IT CAREFULLY. MAKE SURE YOU UNDERSTAND THE CODE YOU ARE SUBMITTING USING AI. - Pull requests that do not follow these guidelines will be closed without review or comment. - If you use AI to write your PR description your pr will be close without review or comment. - If you are unsure about anything, feel free to ask for clarification. ## Description Please provide a clear description of your changes. --- ## Type of Change Please delete options that are not relevant. - [ ] 🐛 Bug fix (non-breaking change which fixes an issue) - [ ] ✨ New feature (non-breaking change which adds functionality) - [ ] 💥 Breaking change (fix or feature with breaking changes) - [ ] 📝 Documentation update - [ ] 🎨 UI/UX improvement - [ ] 🔒 Security enhancement - [ ] ⚡ Performance improvement ## Areas Affected Please check all that apply: - [ ] Email Integration (Gmail, IMAP, etc.) - [ ] User Interface/Experience - [ ] Authentication/Authorization - [ ] Data Storage/Management - [ ] API Endpoints - [ ] Documentation - [ ] Testing Infrastructure - [ ] Development Workflow - [ ] Deployment/Infrastructure ## Testing Done Describe the tests you've done: - [ ] Unit tests added/updated - [ ] Integration tests added/updated - [ ] Manual testing performed - [ ] Cross-browser testing (if UI changes) - [ ] Mobile responsiveness verified (if UI changes) ## Security Considerations For changes involving data or authentication: - [ ] No sensitive data is exposed - [ ] Authentication checks are in place - [ ] Input validation is implemented - [ ] Rate limiting is considered (if applicable) ## Checklist - [ ] I have read the [CONTRIBUTING](https://github.com/Mail-0/Zero/blob/staging/.github/CONTRIBUTING.md) document - [ ] My code follows the project's style guidelines - [ ] I have performed a self-review of my code - [ ] I have commented my code, particularly in complex areas - [ ] I have updated the documentation - [ ] My changes generate no new warnings - [ ] I have added tests that prove my fix/feature works - [ ] All tests pass locally - [ ] Any dependent changes are merged and published ## Additional Notes Add any other context about the pull request here. ## Screenshots/Recordings Add screenshots or recordings here if applicable. --- _By submitting this pull request, I confirm that my contribution is made under the terms of the project's license._ <!-- This is an auto-generated description by cubic. --> --- ## Summary by cubic Added a new voice SSE endpoint for authenticated callers and a thread summary tool to the MCP agent for summarizing email threads. - **New Features** - Added /vsse SSE endpoint with authentication for voice integrations. - Added getThreadSummary tool to MCP agent to return concise summaries of email threads. <!-- End of auto-generated description by cubic. --> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added a new endpoint at `/vsse` with enhanced multi-step authorization and user verification. * Introduced a tool to generate AI-powered summaries of email threads, providing concise overviews along with key thread details. * **Improvements** * Updated thread listings to display sender information in the format: name <email>. * Improved thread retrieval logic for more accurate results. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent 9a22f39 commit 032006c

File tree

2 files changed

+101
-2
lines changed

2 files changed

+101
-2
lines changed

apps/server/src/main.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -668,6 +668,36 @@ const app = new Hono<HonoContext>()
668668
},
669669
{ replaceRequest: false },
670670
)
671+
.mount(
672+
'/vsse',
673+
async (request, env, ctx) => {
674+
const authBearer = request.headers.get('Authorization');
675+
const callerId = request.headers.get('X-Caller');
676+
if (!callerId) {
677+
return new Response('Unauthorized', { status: 401 });
678+
}
679+
if (!authBearer) {
680+
console.log('No auth provided');
681+
return new Response('Unauthorized', { status: 401 });
682+
}
683+
if (authBearer !== env.VOICE_SECRET) {
684+
return new Response('Unauthorized', { status: 401 });
685+
}
686+
const { db, conn } = createDb(env.HYPERDRIVE.connectionString);
687+
const foundUser = await db.query.user.findFirst({
688+
where: and(eq(user.phoneNumber, callerId), eq(user.phoneNumberVerified, true)),
689+
});
690+
await conn.end();
691+
if (!foundUser) {
692+
return new Response('Unauthorized', { status: 401 });
693+
}
694+
ctx.props = {
695+
userId: foundUser.id,
696+
};
697+
return ZeroMCP.serveSSE('/vsse', { binding: 'ZERO_MCP' }).fetch(request, env, ctx);
698+
},
699+
{ replaceRequest: false },
700+
)
671701
.mount(
672702
'/mcp/thinking/sse',
673703
async (request, env, ctx) => {

apps/server/src/routes/agent/mcp.ts

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,75 @@ export class ZeroMCP extends McpAgent<typeof env, Record<string, unknown>, { use
6464
},
6565
);
6666

67+
this.server.registerTool(
68+
'getThreadSummary',
69+
{
70+
description: 'Get the summary of a specific email thread',
71+
inputSchema: {
72+
id: z.string(),
73+
},
74+
},
75+
async (s) => {
76+
if (!this.activeConnectionId) {
77+
return {
78+
content: [
79+
{
80+
type: 'text' as const,
81+
text: 'No active connection',
82+
},
83+
],
84+
};
85+
}
86+
const response = await env.VECTORIZE.getByIds([s.id]);
87+
const driver = await getZeroAgent(this.activeConnectionId);
88+
const thread = await driver.getThread(s.id);
89+
if (response.length && response?.[0]?.metadata?.['summary'] && thread?.latest?.subject) {
90+
const result = response[0].metadata as { summary: string; connection: string };
91+
if (result.connection !== this.activeConnectionId) {
92+
return {
93+
content: [
94+
{
95+
type: 'text' as const,
96+
text: 'No summary found for this connection',
97+
},
98+
],
99+
};
100+
}
101+
const shortResponse = await env.AI.run('@cf/facebook/bart-large-cnn', {
102+
input_text: result.summary,
103+
});
104+
return {
105+
content: [
106+
{
107+
type: 'text' as const,
108+
text: shortResponse.summary as string,
109+
},
110+
{
111+
type: 'text' as const,
112+
text: `Subject: ${thread.latest?.subject}`,
113+
},
114+
{
115+
type: 'text' as const,
116+
text: `Sender: ${thread.latest?.sender.name} <${thread.latest?.sender.email}>`,
117+
},
118+
{
119+
type: 'text' as const,
120+
text: `Date: ${thread.latest?.receivedOn}`,
121+
},
122+
],
123+
};
124+
}
125+
return {
126+
content: [
127+
{
128+
type: 'text' as const,
129+
text: 'No summary found',
130+
},
131+
],
132+
};
133+
},
134+
);
135+
67136
this.server.registerTool(
68137
'getActiveConnection',
69138
{
@@ -249,7 +318,7 @@ export class ZeroMCP extends McpAgent<typeof env, Record<string, unknown>, { use
249318
},
250319
},
251320
async (s) => {
252-
const result = await agent.listThreads({
321+
const result = await agent.rawListThreads({
253322
folder: s.folder,
254323
query: s.query,
255324
maxResults: s.maxResults,
@@ -266,7 +335,7 @@ export class ZeroMCP extends McpAgent<typeof env, Record<string, unknown>, { use
266335
},
267336
{
268337
type: 'text' as const,
269-
text: `Latest Message Sender: ${loadedThread.latest?.sender}`,
338+
text: `Latest Message Sender: ${thread.latest?.sender.name} <${thread.latest?.sender.email}>`,
270339
},
271340
];
272341
}),

0 commit comments

Comments
 (0)