Skip to content

Commit

Permalink
mcp server that makes api calls
Browse files Browse the repository at this point in the history
  • Loading branch information
elie222 committed Feb 28, 2025
1 parent 4400921 commit 9dc9564
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 25 deletions.
10 changes: 10 additions & 0 deletions apps/mcp-server/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
# Inbox Zero MCP Server

An MCP server to manage your inbox efficiently. Use it within Cursor, Windsurf, or Claude desktop to interact with your Inbox Zero personal assistant.

## Run it locally

From this directory:

```
pnpm run build
```

Then use the MCP at path `apps/mcp-server/build/index.js` in Cursor or Claude Desktop. Note, use the full path.
103 changes: 78 additions & 25 deletions apps/mcp-server/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,16 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

// const INBOX_ZERO_API_BASE = "https://getinboxzero.com/api/v1";
const INBOX_ZERO_API_BASE = "http://localhost:3000/api/v1";
const API_KEY = "";
// Configuration
const INBOX_ZERO_API_BASE =
process.env.INBOX_ZERO_API_BASE || "http://localhost:3000/api/v1";
const API_KEY = process.env.INBOX_ZERO_API_KEY || "";

if (!API_KEY) {
console.warn(
"Warning: INBOX_ZERO_API_KEY environment variable is not set. API requests may fail.",
);
}

// Create server instance
const server = new McpServer({
Expand All @@ -13,7 +20,10 @@ const server = new McpServer({
});

async function makeIZRequest<T>(url: string): Promise<T | null> {
const headers = {};
const headers = {
"API-Key": API_KEY,
"Content-Type": "application/json",
};

try {
const response = await fetch(url, { headers });
Expand All @@ -22,50 +32,93 @@ async function makeIZRequest<T>(url: string): Promise<T | null> {
}
return (await response.json()) as T;
} catch (error) {
console.error("Error making NWS request:", error);
console.error("Error making Inbox Zero API request:", error);
return null;
}
}

// Define types based on the validation schemas
type ReplyTrackerResponse = {
emails: Array<{
threadId: string;
subject: string;
from: string;
date: string;
snippet: string;
}>;
count: number;
};

// Helper functions for formatting email data
function formatReplyTrackerEmail(email: ReplyTrackerResponse["emails"][0]) {
return `- From: ${email.from}\n Subject: ${email.subject}\n Date: ${email.date}\n Snippet: ${email.snippet}`;
}

// Helper function to create a formatted response
function createTextResponse(text: string) {
return {
content: [
{
type: "text" as const,
text,
},
],
};
}

// Register tools
server.tool(
"get-emails-needing-reply",
"Get emails needing reply",
{},
async () => {
return {
content: [
{
type: "text",
text: "Not implemented",
},
],
};
{
olderThan: z
.enum(["3d", "1w", "2w", "1m"])
.describe("Time range to look back"),
},
async ({ olderThan }) => {
const url = `${INBOX_ZERO_API_BASE}/reply-tracker?type=needs-reply&timeRange=${olderThan}`;
const data = await makeIZRequest<ReplyTrackerResponse>(url);

if (!data) {
return createTextResponse("Failed to fetch emails needing reply.");
}

const emailList = data.emails.map(formatReplyTrackerEmail).join("\n\n");
return createTextResponse(
`Found ${data.count} emails needing reply:\n\n${emailList}`,
);
},
);

server.tool(
"get-emails-needing-follow-up",
"Get emails needing follow-up",
{
olderThan: z.number().describe("Number of days to look back"),
olderThan: z
.enum(["3d", "1w", "2w", "1m"])
.describe("Time range to look back"),
},
async ({ olderThan }) => {
return {
content: [
{
type: "text",
text: `Not implemented (olderThan: ${olderThan})`,
},
],
};
const url = `${INBOX_ZERO_API_BASE}/reply-tracker?type=needs-follow-up&timeRange=${olderThan}`;
const data = await makeIZRequest<ReplyTrackerResponse>(url);

if (!data) {
return createTextResponse(
`Failed to fetch emails needing follow-up older than ${olderThan} days.`,
);
}

const emailList = data.emails.map(formatReplyTrackerEmail).join("\n\n");
return createTextResponse(
`Found ${data.count} emails needing follow-up:\n\n${emailList}`,
);
},
);

async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
console.error("Weather MCP Server running on stdio");
console.error("Inbox Zero MCP Server running on stdio");
}

main().catch((error) => {
Expand Down

0 comments on commit 9dc9564

Please sign in to comment.