Skip to main content
Glama
by ricleedo
index.tsβ€’6.49 kB
#!/usr/bin/env node import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import * as dotenv from "dotenv"; import { airportsSearchSchema, searchAirports } from "./airports.js"; import { createEvent, createEventSchema, deleteEvent, deleteEventSchema, getEvent, getEventSchema, initializeCalendarData, listCalendars, listCalendarsSchema, listEvents, listEventsSchema, updateEvent, updateEventSchema, } from "./calendar.js"; import { financeSearchSchema, searchFinance } from "./finance.js"; import { getEmail, getEmailSchema, getLabels, readEmails, readEmailsSchema, sendEmail, sendEmailSchema, } from "./gmail.js"; import { directionsSchema, distanceMatrix, distanceMatrixSchema, geocode, geocodeSchema, getDirections, placeDetails, placeDetailsSchema, placesSearch, placesSearchSchema, reverseGeocode, reverseGeocodeSchema, } from "./maps.js"; // Temporarily redirect stdout to prevent dotenv logging const originalWrite = process.stdout.write; process.stdout.write = () => true; dotenv.config({ path: ".env.local" }); process.stdout.write = originalWrite; // Create the MCP server const server = new McpServer({ name: "google-mcp", version: "1.0.0", }); // Geocoding tool server.tool( "geocode", "Convert an address to coordinates", geocodeSchema.shape, async (params) => { return await geocode(params); } ); // Reverse geocoding tool server.tool( "reverse-geocode", "Convert coordinates to an address", reverseGeocodeSchema.shape, async (params) => { return await reverseGeocode(params); } ); // Places search tool server.tool( "places-search", "Search for places using text query", placesSearchSchema.shape, async (params) => { return await placesSearch(params); } ); // Directions tool server.tool( "get-directions", "Get directions between two locations", directionsSchema.shape, async (params) => { return await getDirections(params); } ); // Distance matrix tool server.tool( "distance-matrix", "Calculate travel distance and time between multiple origins and destinations", distanceMatrixSchema.shape, async (params) => { return await distanceMatrix(params); } ); // Place details tool server.tool( "place-details", "Get detailed information about a specific place", placeDetailsSchema.shape, async (params) => { return await placeDetails(params); } ); // Finance search tool server.tool( "finance-search", "Search for stocks, indices, mutual funds, currencies, and futures using Google Finance. Use format 'SYMBOL:EXCHANGE'. Stocks: 'AAPL:NASDAQ', 'TSLA:NASDAQ'. ETFs/Index funds: 'SPY:NYSEARCA', 'VTI:NYSEARCA', 'QQQ:NASDAQ', 'VOO:NYSEARCA'. Crypto: 'BTC-USD', 'ETH-USD'. Note: Query 'SPY' (no exchange) returns market overview with S&P 500 related ETFs.", financeSearchSchema.shape, async (params) => { try { const result = await searchFinance(params); return { content: [ { type: "text", text: result, }, ], }; } catch (error) { return { content: [ { type: "text", text: `Error searching finance data: ${ error instanceof Error ? error.message : String(error) }`, }, ], }; } } ); // Airports search tool server.tool( "airports-search", "Search for airport and flight information using Google Flights", airportsSearchSchema.shape, async (params) => { try { const result = await searchAirports(params); return { content: [ { type: "text", text: result, }, ], }; } catch (error) { return { content: [ { type: "text", text: `Error searching airports data: ${ error instanceof Error ? error.message : String(error) }`, }, ], }; } } ); // Gmail tools server.tool( "gmail-send-email", "Send an email using Gmail", sendEmailSchema.shape, async (params) => { return await sendEmail(params); } ); server.tool( "gmail-read-emails", "Read/list emails from Gmail with optional search query", readEmailsSchema.shape, async (params) => { return await readEmails(params); } ); server.tool( "gmail-get-email", "Get a specific email by message ID", getEmailSchema.shape, async (params) => { return await getEmail(params); } ); server.tool("gmail-get-labels", "Get all Gmail labels", {}, async () => { return await getLabels(); }); // Calendar tools will be registered after initialization function registerCalendarTools() { server.tool( "calendar-create-event", "Create a new calendar event. Current time: " + new Date().toLocaleString(), createEventSchema().shape, async (params) => { return await createEvent(params); } ); server.tool( "calendar-list-events", "List calendar events with optional filters", listEventsSchema().shape, async (params) => { return await listEvents(params); } ); server.tool( "calendar-get-event", "Get a specific calendar event by ID", getEventSchema().shape, async (params) => { return await getEvent(params); } ); server.tool( "calendar-update-event", "Update an existing calendar event", updateEventSchema().shape, async (params) => { return await updateEvent(params); } ); server.tool( "calendar-delete-event", "Delete a calendar event", deleteEventSchema().shape, async (params) => { return await deleteEvent(params); } ); server.tool( "calendar-list-calendars", "List all available calendars", listCalendarsSchema().shape, async (params) => { return await listCalendars(params); } ); } // Start the server async function main() { try { // Initialize calendar data on server start await initializeCalendarData(); // Register calendar tools after initialization registerCalendarTools(); const transport = new StdioServerTransport(); await server.connect(transport); console.error("Google MCP Server running..."); } catch (error) { console.error("Error starting server:", error); process.exit(1); } } main().catch(console.error);

Implementation Reference

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ricleedo/Google-Service-MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server