From 9e3a072a8ad14dddbde53853c3c20d806edd5475 Mon Sep 17 00:00:00 2001 From: Mahesh Murag Date: Wed, 20 Nov 2024 02:19:36 -0500 Subject: [PATCH 1/2] Add Google Maps --- src/google-maps/README.md | 65 ++++ src/google-maps/index.ts | 710 ++++++++++++++++++++++++++++++++++ src/google-maps/package.json | 29 ++ src/google-maps/tsconfig.json | 10 + 4 files changed, 814 insertions(+) create mode 100644 src/google-maps/README.md create mode 100644 src/google-maps/index.ts create mode 100644 src/google-maps/package.json create mode 100644 src/google-maps/tsconfig.json diff --git a/src/google-maps/README.md b/src/google-maps/README.md new file mode 100644 index 00000000..8af6dd24 --- /dev/null +++ b/src/google-maps/README.md @@ -0,0 +1,65 @@ +# Google Maps MCP Server + +MCP Server for the Google Maps API. + +## Tools + +1. `geocode` + - Convert address to coordinates + - Input: `address` (string) + - Returns: location, formatted_address, place_id + +2. `reverse_geocode` + - Convert coordinates to address + - Inputs: + - `latitude` (number) + - `longitude` (number) + - Returns: formatted_address, place_id, address_components + +3. `search_places` + - Search for places using text query + - Inputs: + - `query` (string) + - `location` (optional): { latitude: number, longitude: number } + - `radius` (optional): number (meters, max 50000) + - Returns: array of places with names, addresses, locations + +4. `get_place_details` + - Get detailed information about a place + - Input: `place_id` (string) + - Returns: name, address, contact info, ratings, reviews, opening hours + +5. `get_distance_matrix` + - Calculate distances and times between points + - Inputs: + - `origins` (string[]) + - `destinations` (string[]) + - `mode` (optional): "driving" | "walking" | "bicycling" | "transit" + - Returns: distances and durations matrix + +6. `get_elevation` + - Get elevation data for locations + - Input: `locations` (array of {latitude, longitude}) + - Returns: elevation data for each point + +7. `get_directions` + - Get directions between points + - Inputs: + - `origin` (string) + - `destination` (string) + - `mode` (optional): "driving" | "walking" | "bicycling" | "transit" + - Returns: route details with steps, distance, duration + +## Setup + +1. Get a Google Maps API key by following the instructions [here](https://developers.google.com/maps/documentation/javascript/get-api-key#create-api-keys). + +2. To use this with Claude Desktop, add the following to your `claude_desktop_config.json`: + ```json + "mcp-server-google-maps": { + "command": "mcp-server-google-maps", + "env": { + "GOOGLE_MAPS_API_KEY": "" + } + } + ``` diff --git a/src/google-maps/index.ts b/src/google-maps/index.ts new file mode 100644 index 00000000..937b39af --- /dev/null +++ b/src/google-maps/index.ts @@ -0,0 +1,710 @@ +#!/usr/bin/env node + +import { Server } from "@modelcontextprotocol/sdk/server/index.js"; +import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; +import { + CallToolRequestSchema, + ListToolsRequestSchema, + Tool, +} from "@modelcontextprotocol/sdk/types.js"; +import fetch from "node-fetch"; + +// Response interfaces +interface GoogleMapsResponse { + status: string; + error_message?: string; +} + +interface GeocodeResponse extends GoogleMapsResponse { + results: Array<{ + place_id: string; + formatted_address: string; + geometry: { + location: { + lat: number; + lng: number; + } + }; + address_components: Array<{ + long_name: string; + short_name: string; + types: string[]; + }>; + }>; +} + +interface PlacesSearchResponse extends GoogleMapsResponse { + results: Array<{ + name: string; + place_id: string; + formatted_address: string; + geometry: { + location: { + lat: number; + lng: number; + } + }; + rating?: number; + types: string[]; + }>; +} + +interface PlaceDetailsResponse extends GoogleMapsResponse { + result: { + name: string; + place_id: string; + formatted_address: string; + formatted_phone_number?: string; + website?: string; + rating?: number; + reviews?: Array<{ + author_name: string; + rating: number; + text: string; + time: number; + }>; + opening_hours?: { + weekday_text: string[]; + open_now: boolean; + }; + geometry: { + location: { + lat: number; + lng: number; + } + }; + }; +} + +interface DistanceMatrixResponse extends GoogleMapsResponse { + origin_addresses: string[]; + destination_addresses: string[]; + rows: Array<{ + elements: Array<{ + status: string; + duration: { + text: string; + value: number; + }; + distance: { + text: string; + value: number; + }; + }>; + }>; +} + +interface ElevationResponse extends GoogleMapsResponse { + results: Array<{ + elevation: number; + location: { + lat: number; + lng: number; + }; + resolution: number; + }>; +} + +interface DirectionsResponse extends GoogleMapsResponse { + routes: Array<{ + summary: string; + legs: Array<{ + distance: { + text: string; + value: number; + }; + duration: { + text: string; + value: number; + }; + steps: Array<{ + html_instructions: string; + distance: { + text: string; + value: number; + }; + duration: { + text: string; + value: number; + }; + travel_mode: string; + }>; + }>; + }>; +} + +function getApiKey(): string { + const apiKey = process.env.GOOGLE_MAPS_API_KEY; + if (!apiKey) { + console.error("GOOGLE_MAPS_API_KEY environment variable is not set"); + process.exit(1); + } + return apiKey; + } + +const GOOGLE_MAPS_API_KEY = getApiKey(); + +// Tool definitions +const GEOCODE_TOOL: Tool = { + name: "maps_geocode", + description: "Convert an address into geographic coordinates", + inputSchema: { + type: "object", + properties: { + address: { + type: "string", + description: "The address to geocode" + } + }, + required: ["address"] + } + }; + +const REVERSE_GEOCODE_TOOL: Tool = { + name: "maps_reverse_geocode", + description: "Convert coordinates into an address", + inputSchema: { + type: "object", + properties: { + latitude: { + type: "number", + description: "Latitude coordinate" + }, + longitude: { + type: "number", + description: "Longitude coordinate" + } + }, + required: ["latitude", "longitude"] + } +}; + +const SEARCH_PLACES_TOOL: Tool = { + name: "maps_search_places", + description: "Search for places using Google Places API", + inputSchema: { + type: "object", + properties: { + query: { + type: "string", + description: "Search query" + }, + location: { + type: "object", + properties: { + latitude: { type: "number" }, + longitude: { type: "number" } + }, + description: "Optional center point for the search" + }, + radius: { + type: "number", + description: "Search radius in meters (max 50000)" + } + }, + required: ["query"] + } +}; + +const PLACE_DETAILS_TOOL: Tool = { + name: "maps_place_details", + description: "Get detailed information about a specific place", + inputSchema: { + type: "object", + properties: { + place_id: { + type: "string", + description: "The place ID to get details for" + } + }, + required: ["place_id"] + } +}; + +const DISTANCE_MATRIX_TOOL: Tool = { + name: "maps_distance_matrix", + description: "Calculate travel distance and time for multiple origins and destinations", + inputSchema: { + type: "object", + properties: { + origins: { + type: "array", + items: { type: "string" }, + description: "Array of origin addresses or coordinates" + }, + destinations: { + type: "array", + items: { type: "string" }, + description: "Array of destination addresses or coordinates" + }, + mode: { + type: "string", + description: "Travel mode (driving, walking, bicycling, transit)", + enum: ["driving", "walking", "bicycling", "transit"] + } + }, + required: ["origins", "destinations"] + } +}; + +const ELEVATION_TOOL: Tool = { + name: "maps_elevation", + description: "Get elevation data for locations on the earth", + inputSchema: { + type: "object", + properties: { + locations: { + type: "array", + items: { + type: "object", + properties: { + latitude: { type: "number" }, + longitude: { type: "number" } + }, + required: ["latitude", "longitude"] + }, + description: "Array of locations to get elevation for" + } + }, + required: ["locations"] + } +}; + +const DIRECTIONS_TOOL: Tool = { + name: "maps_directions", + description: "Get directions between two points", + inputSchema: { + type: "object", + properties: { + origin: { + type: "string", + description: "Starting point address or coordinates" + }, + destination: { + type: "string", + description: "Ending point address or coordinates" + }, + mode: { + type: "string", + description: "Travel mode (driving, walking, bicycling, transit)", + enum: ["driving", "walking", "bicycling", "transit"] + } + }, + required: ["origin", "destination"] + } +}; + +const MAPS_TOOLS = [ + GEOCODE_TOOL, + REVERSE_GEOCODE_TOOL, + SEARCH_PLACES_TOOL, + PLACE_DETAILS_TOOL, + DISTANCE_MATRIX_TOOL, + ELEVATION_TOOL, + DIRECTIONS_TOOL, +] as const; + +// API handlers +async function handleGeocode(address: string) { + const url = new URL("https://maps.googleapis.com/maps/api/geocode/json"); + url.searchParams.append("address", address); + url.searchParams.append("key", GOOGLE_MAPS_API_KEY); + + const response = await fetch(url.toString()); + const data = await response.json() as GeocodeResponse; + + if (data.status !== "OK") { + return { + toolResult: { + content: [{ + type: "text", + text: `Geocoding failed: ${data.error_message || data.status}` + }], + isError: true + } + }; + } + + return { + toolResult: { + content: [{ + type: "text", + text: JSON.stringify({ + location: data.results[0].geometry.location, + formatted_address: data.results[0].formatted_address, + place_id: data.results[0].place_id + }, null, 2) + }], + isError: false + } + }; +} + +async function handleReverseGeocode(latitude: number, longitude: number) { + const url = new URL("https://maps.googleapis.com/maps/api/geocode/json"); + url.searchParams.append("latlng", `${latitude},${longitude}`); + url.searchParams.append("key", GOOGLE_MAPS_API_KEY); + + const response = await fetch(url.toString()); + const data = await response.json() as GeocodeResponse; + + if (data.status !== "OK") { + return { + toolResult: { + content: [{ + type: "text", + text: `Reverse geocoding failed: ${data.error_message || data.status}` + }], + isError: true + } + }; + } + + return { + toolResult: { + content: [{ + type: "text", + text: JSON.stringify({ + formatted_address: data.results[0].formatted_address, + place_id: data.results[0].place_id, + address_components: data.results[0].address_components + }, null, 2) + }], + isError: false + } + }; +} + +async function handlePlaceSearch( + query: string, + location?: { latitude: number; longitude: number }, + radius?: number +) { + const url = new URL("https://maps.googleapis.com/maps/api/place/textsearch/json"); + url.searchParams.append("query", query); + url.searchParams.append("key", GOOGLE_MAPS_API_KEY); + + if (location) { + url.searchParams.append("location", `${location.latitude},${location.longitude}`); + } + if (radius) { + url.searchParams.append("radius", radius.toString()); + } + + const response = await fetch(url.toString()); + const data = await response.json() as PlacesSearchResponse; + + if (data.status !== "OK") { + return { + toolResult: { + content: [{ + type: "text", + text: `Place search failed: ${data.error_message || data.status}` + }], + isError: true + } + }; + } + + return { + toolResult: { + content: [{ + type: "text", + text: JSON.stringify({ + places: data.results.map((place) => ({ + name: place.name, + formatted_address: place.formatted_address, + location: place.geometry.location, + place_id: place.place_id, + rating: place.rating, + types: place.types + })) + }, null, 2) + }], + isError: false + } + }; +} + +async function handlePlaceDetails(place_id: string) { + const url = new URL("https://maps.googleapis.com/maps/api/place/details/json"); + url.searchParams.append("place_id", place_id); + url.searchParams.append("key", GOOGLE_MAPS_API_KEY); + + const response = await fetch(url.toString()); + const data = await response.json() as PlaceDetailsResponse; + + if (data.status !== "OK") { + return { + toolResult: { + content: [{ + type: "text", + text: `Place details request failed: ${data.error_message || data.status}` + }], + isError: true + } + }; + } + + return { + toolResult: { + content: [{ + type: "text", + text: JSON.stringify({ + name: data.result.name, + formatted_address: data.result.formatted_address, + location: data.result.geometry.location, + formatted_phone_number: data.result.formatted_phone_number, + website: data.result.website, + rating: data.result.rating, + reviews: data.result.reviews, + opening_hours: data.result.opening_hours + }, null, 2) + }], + isError: false + } + }; +} +async function handleDistanceMatrix( + origins: string[], + destinations: string[], + mode: "driving" | "walking" | "bicycling" | "transit" = "driving" +) { + const url = new URL("https://maps.googleapis.com/maps/api/distancematrix/json"); + url.searchParams.append("origins", origins.join("|")); + url.searchParams.append("destinations", destinations.join("|")); + url.searchParams.append("mode", mode); + url.searchParams.append("key", GOOGLE_MAPS_API_KEY); + + const response = await fetch(url.toString()); + const data = await response.json() as DistanceMatrixResponse; + + if (data.status !== "OK") { + return { + toolResult: { + content: [{ + type: "text", + text: `Distance matrix request failed: ${data.error_message || data.status}` + }], + isError: true + } + }; + } + + return { + toolResult: { + content: [{ + type: "text", + text: JSON.stringify({ + origin_addresses: data.origin_addresses, + destination_addresses: data.destination_addresses, + results: data.rows.map((row) => ({ + elements: row.elements.map((element) => ({ + status: element.status, + duration: element.duration, + distance: element.distance + })) + })) + }, null, 2) + }], + isError: false + } + }; +} + +async function handleElevation(locations: Array<{ latitude: number; longitude: number }>) { + const url = new URL("https://maps.googleapis.com/maps/api/elevation/json"); + const locationString = locations + .map((loc) => `${loc.latitude},${loc.longitude}`) + .join("|"); + url.searchParams.append("locations", locationString); + url.searchParams.append("key", GOOGLE_MAPS_API_KEY); + + const response = await fetch(url.toString()); + const data = await response.json() as ElevationResponse; + + if (data.status !== "OK") { + return { + toolResult: { + content: [{ + type: "text", + text: `Elevation request failed: ${data.error_message || data.status}` + }], + isError: true + } + }; + } + + return { + toolResult: { + content: [{ + type: "text", + text: JSON.stringify({ + results: data.results.map((result) => ({ + elevation: result.elevation, + location: result.location, + resolution: result.resolution + })) + }, null, 2) + }], + isError: false + } + }; +} + +async function handleDirections( + origin: string, + destination: string, + mode: "driving" | "walking" | "bicycling" | "transit" = "driving" +) { + const url = new URL("https://maps.googleapis.com/maps/api/directions/json"); + url.searchParams.append("origin", origin); + url.searchParams.append("destination", destination); + url.searchParams.append("mode", mode); + url.searchParams.append("key", GOOGLE_MAPS_API_KEY); + + const response = await fetch(url.toString()); + const data = await response.json() as DirectionsResponse; + + if (data.status !== "OK") { + return { + toolResult: { + content: [{ + type: "text", + text: `Directions request failed: ${data.error_message || data.status}` + }], + isError: true + } + }; + } + + return { + toolResult: { + content: [{ + type: "text", + text: JSON.stringify({ + routes: data.routes.map((route) => ({ + summary: route.summary, + distance: route.legs[0].distance, + duration: route.legs[0].duration, + steps: route.legs[0].steps.map((step) => ({ + instructions: step.html_instructions, + distance: step.distance, + duration: step.duration, + travel_mode: step.travel_mode + })) + })) + }, null, 2) + }], + isError: false + } + }; +} + +// Server setup +const server = new Server( + { + name: "mcp-server/google-maps", + version: "0.1.0", + }, + { + capabilities: { + tools: {}, + }, + }, +); + +// Set up request handlers +server.setRequestHandler(ListToolsRequestSchema, async () => ({ + tools: MAPS_TOOLS, +})); + +server.setRequestHandler(CallToolRequestSchema, async (request) => { + try { + switch (request.params.name) { + case "maps_geocode": { + const { address } = request.params.arguments as { address: string }; + return await handleGeocode(address); + } + + case "maps_reverse_geocode": { + const { latitude, longitude } = request.params.arguments as { + latitude: number; + longitude: number; + }; + return await handleReverseGeocode(latitude, longitude); + } + + case "maps_search_places": { + const { query, location, radius } = request.params.arguments as { + query: string; + location?: { latitude: number; longitude: number }; + radius?: number; + }; + return await handlePlaceSearch(query, location, radius); + } + + case "maps_place_details": { + const { place_id } = request.params.arguments as { place_id: string }; + return await handlePlaceDetails(place_id); + } + + case "maps_distance_matrix": { + const { origins, destinations, mode } = request.params.arguments as { + origins: string[]; + destinations: string[]; + mode?: "driving" | "walking" | "bicycling" | "transit"; + }; + return await handleDistanceMatrix(origins, destinations, mode); + } + + case "maps_elevation": { + const { locations } = request.params.arguments as { + locations: Array<{ latitude: number; longitude: number }>; + }; + return await handleElevation(locations); + } + + case "maps_directions": { + const { origin, destination, mode } = request.params.arguments as { + origin: string; + destination: string; + mode?: "driving" | "walking" | "bicycling" | "transit"; + }; + return await handleDirections(origin, destination, mode); + } + + default: + return { + toolResult: { + content: [{ + type: "text", + text: `Unknown tool: ${request.params.name}` + }], + isError: true + } + }; + } + } catch (error) { + return { + toolResult: { + content: [{ + type: "text", + text: `Error: ${error instanceof Error ? error.message : String(error)}` + }], + isError: true + } + }; + } +}); + +async function runServer() { + const transport = new StdioServerTransport(); + await server.connect(transport); + console.error("Google Maps MCP Server running on stdio"); +} + +runServer().catch((error) => { + console.error("Fatal error running server:", error); + process.exit(1); +}); \ No newline at end of file diff --git a/src/google-maps/package.json b/src/google-maps/package.json new file mode 100644 index 00000000..0b265cd7 --- /dev/null +++ b/src/google-maps/package.json @@ -0,0 +1,29 @@ +{ + "name": "@modelcontextprotocol/server-google-maps", + "version": "0.1.0", + "description": "MCP server for using the Google Maps API", + "license": "MIT", + "author": "Anthropic, PBC (https://anthropic.com)", + "homepage": "https://modelcontextprotocol.io", + "bugs": "https://github.com/modelcontextprotocol/servers/issues", + "type": "module", + "bin": { + "mcp-server-google-maps": "dist/index.js" + }, + "files": [ + "dist" + ], + "scripts": { + "build": "tsc && shx chmod +x dist/*.js", + "prepare": "npm run build", + "watch": "tsc --watch" + }, + "dependencies": { + "@modelcontextprotocol/sdk": "0.6.0", + "puppeteer": "^23.4.0" + }, + "devDependencies": { + "shx": "^0.3.4", + "typescript": "^5.6.2" + } +} diff --git a/src/google-maps/tsconfig.json b/src/google-maps/tsconfig.json new file mode 100644 index 00000000..ec5da158 --- /dev/null +++ b/src/google-maps/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "./dist", + "rootDir": "." + }, + "include": [ + "./**/*.ts" + ] +} From f68a6316d69fb83a316f62863f0970680dc8967e Mon Sep 17 00:00:00 2001 From: Mahesh Murag Date: Wed, 20 Nov 2024 02:31:00 -0500 Subject: [PATCH 2/2] Add Google Maps --- package-lock.json | 86 ++++++++++++++++++++++++++++++++++-- src/google-maps/package.json | 2 +- 2 files changed, 84 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 977c234d..306bb3b4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -72,6 +72,10 @@ "resolved": "src/gdrive", "link": true }, + "node_modules/@modelcontextprotocol/server-google-maps": { + "resolved": "src/google-maps", + "link": true + }, "node_modules/@modelcontextprotocol/server-postgres": { "resolved": "src/postgres", "link": true @@ -190,11 +194,20 @@ "version": "22.9.0", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.9.0.tgz", "integrity": "sha512-vuyHg81vvWA1Z1ELfvLko2c8f34gyA0zaic0+Rllc5lbCnbSyuvb2Oxpm6TAUAC/2xZN3QGqxBNggD1nNR2AfQ==", - "devOptional": true, "dependencies": { "undici-types": "~6.19.8" } }, + "node_modules/@types/node-fetch": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.12.tgz", + "integrity": "sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "form-data": "^4.0.0" + } + }, "node_modules/@types/pg": { "version": "8.11.10", "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.11.10.tgz", @@ -343,6 +356,12 @@ "node": ">=4" } }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, "node_modules/b4a": { "version": "1.6.7", "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.7.tgz", @@ -589,6 +608,18 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -697,6 +728,15 @@ "node": ">= 14" } }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -973,6 +1013,20 @@ "node": ">= 0.8" } }, + "node_modules/form-data": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", + "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -2659,8 +2713,7 @@ "node_modules/undici-types": { "version": "6.19.8", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", - "devOptional": true + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==" }, "node_modules/universalify": { "version": "2.0.1", @@ -2873,6 +2926,33 @@ "typescript": "^5.6.2" } }, + "src/google-maps": { + "name": "@modelcontextprotocol/server-google-maps", + "version": "0.1.0", + "license": "MIT", + "dependencies": { + "@modelcontextprotocol/sdk": "0.6.0", + "@types/node-fetch": "^2.6.12" + }, + "bin": { + "mcp-server-google-maps": "dist/index.js" + }, + "devDependencies": { + "shx": "^0.3.4", + "typescript": "^5.6.2" + } + }, + "src/google-maps/node_modules/@modelcontextprotocol/sdk": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-0.6.0.tgz", + "integrity": "sha512-9rsDudGhDtMbvxohPoMMyAUOmEzQsOK+XFchh6gZGqo8sx9sBuZQs+CUttXqa8RZXKDaJRCN2tUtgGof7jRkkw==", + "license": "MIT", + "dependencies": { + "content-type": "^1.0.5", + "raw-body": "^3.0.0", + "zod": "^3.23.8" + } + }, "src/postgres": { "name": "@modelcontextprotocol/server-postgres", "version": "0.1.0", diff --git a/src/google-maps/package.json b/src/google-maps/package.json index 0b265cd7..b3de0649 100644 --- a/src/google-maps/package.json +++ b/src/google-maps/package.json @@ -20,7 +20,7 @@ }, "dependencies": { "@modelcontextprotocol/sdk": "0.6.0", - "puppeteer": "^23.4.0" + "@types/node-fetch": "^2.6.12" }, "devDependencies": { "shx": "^0.3.4",