Skip to main content
Glama

maps

Search locations, get directions, and manage guides with Apple Maps integration. Save favorites, pin addresses, and create custom guides for efficient navigation.

Instructions

Search locations, manage guides, save favorites, and get directions using Apple Maps

Input Schema

NameRequiredDescriptionDefault
addressNoAddress of the location (required for save, pin, addToGuide)
fromAddressNoStarting address for directions (required for directions)
guideNameNoName of the guide (required for createGuide and addToGuide)
limitNoMaximum number of results to return (optional for search)
nameNoName of the location (required for save and pin)
operationYesOperation to perform with Maps
queryNoSearch query for locations (required for search)
toAddressNoDestination address for directions (required for directions)
transportTypeNoType of transport to use (optional for directions)

Input Schema (JSON Schema)

{ "properties": { "address": { "description": "Address of the location (required for save, pin, addToGuide)", "type": "string" }, "fromAddress": { "description": "Starting address for directions (required for directions)", "type": "string" }, "guideName": { "description": "Name of the guide (required for createGuide and addToGuide)", "type": "string" }, "limit": { "description": "Maximum number of results to return (optional for search)", "type": "number" }, "name": { "description": "Name of the location (required for save and pin)", "type": "string" }, "operation": { "description": "Operation to perform with Maps", "enum": [ "search", "save", "directions", "pin", "listGuides", "addToGuide", "createGuide" ], "type": "string" }, "query": { "description": "Search query for locations (required for search)", "type": "string" }, "toAddress": { "description": "Destination address for directions (required for directions)", "type": "string" }, "transportType": { "description": "Type of transport to use (optional for directions)", "enum": [ "driving", "walking", "transit" ], "type": "string" } }, "required": [ "operation" ], "type": "object" }

Implementation Reference

  • The main MCP tool handler for 'maps' tool. Loads the maps module dynamically and dispatches to specific operations like search, save, directions, etc., based on input parameters.
    case "maps": { if (!isMapsArgs(args)) { throw new Error("Invalid arguments for maps tool"); } try { const mapsModule = await loadModule("maps"); const { operation } = args; switch (operation) { case "search": { const { query, limit } = args; if (!query) { throw new Error( "Search query is required for search operation", ); } const result = await mapsModule.searchLocations(query, limit); return { content: [ { type: "text", text: result.success ? `${result.message}\n\n${result.locations .map( (location) => `Name: ${location.name}\n` + `Address: ${location.address}\n` + `${location.latitude && location.longitude ? `Coordinates: ${location.latitude}, ${location.longitude}\n` : ""}`, ) .join("\n\n")}` : `${result.message}`, }, ], isError: !result.success, }; } case "save": { const { name, address } = args; if (!name || !address) { throw new Error( "Name and address are required for save operation", ); } const result = await mapsModule.saveLocation(name, address); return { content: [ { type: "text", text: result.message, }, ], isError: !result.success, }; } case "pin": { const { name, address } = args; if (!name || !address) { throw new Error( "Name and address are required for pin operation", ); } const result = await mapsModule.dropPin(name, address); return { content: [ { type: "text", text: result.message, }, ], isError: !result.success, }; } case "directions": { const { fromAddress, toAddress, transportType } = args; if (!fromAddress || !toAddress) { throw new Error( "From and to addresses are required for directions operation", ); } const result = await mapsModule.getDirections( fromAddress, toAddress, transportType as "driving" | "walking" | "transit", ); return { content: [ { type: "text", text: result.message, }, ], isError: !result.success, }; } case "listGuides": { const result = await mapsModule.listGuides(); return { content: [ { type: "text", text: result.message, }, ], isError: !result.success, }; } case "addToGuide": { const { address, guideName } = args; if (!address || !guideName) { throw new Error( "Address and guideName are required for addToGuide operation", ); } const result = await mapsModule.addToGuide(address, guideName); return { content: [ { type: "text", text: result.message, }, ], isError: !result.success, }; } case "createGuide": { const { guideName } = args; if (!guideName) { throw new Error( "Guide name is required for createGuide operation", ); } const result = await mapsModule.createGuide(guideName); return { content: [ { type: "text", text: result.message, }, ], isError: !result.success, }; } default: throw new Error(`Unknown maps operation: ${operation}`); } } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); return { content: [ { type: "text", text: errorMessage.includes("access") ? errorMessage : `Error in maps tool: ${errorMessage}`, }, ], isError: true, }; } }
  • Input schema and metadata definition for the 'maps' MCP tool, including all supported operations and parameters.
    const MAPS_TOOL: Tool = { name: "maps", description: "Search locations, manage guides, save favorites, and get directions using Apple Maps", inputSchema: { type: "object", properties: { operation: { type: "string", description: "Operation to perform with Maps", enum: ["search", "save", "directions", "pin", "listGuides", "addToGuide", "createGuide"] }, query: { type: "string", description: "Search query for locations (required for search)" }, limit: { type: "number", description: "Maximum number of results to return (optional for search)" }, name: { type: "string", description: "Name of the location (required for save and pin)" }, address: { type: "string", description: "Address of the location (required for save, pin, addToGuide)" }, fromAddress: { type: "string", description: "Starting address for directions (required for directions)" }, toAddress: { type: "string", description: "Destination address for directions (required for directions)" }, transportType: { type: "string", description: "Type of transport to use (optional for directions)", enum: ["driving", "walking", "transit"] }, guideName: { type: "string", description: "Name of the guide (required for createGuide and addToGuide)" } }, required: ["operation"] } };
  • tools.ts:294-296 (registration)
    Registration of the 'maps' tool as part of the exported tools array used by the MCP server for tool listing.
    const tools = [CONTACTS_TOOL, NOTES_TOOL, MESSAGES_TOOL, MAIL_TOOL, REMINDERS_TOOL, CALENDAR_TOOL, MAPS_TOOL]; export default tools;
  • Core implementation module exporting all handler functions for Maps app interactions via AppleScript/JXA, including search, save, directions, etc.
    const maps = { searchLocations, saveLocation, getDirections, dropPin, listGuides, addToGuide, createGuide, requestMapsAccess }; export default maps;
  • Example helper: searchLocations function - primary implementation for searching locations in Apple Maps app using JXA scripting.
    async function searchLocations(query: string, limit: number = 5): Promise<SearchResult> { try { const accessResult = await requestMapsAccess(); if (!accessResult.hasAccess) { return { success: false, locations: [], message: accessResult.message }; } console.error(`searchLocations - Searching for: "${query}"`); // First try to use the Maps search function const locations = await run((args: { query: string, limit: number }) => { try { const Maps = Application("Maps"); // Launch Maps and search (this is needed for search to work properly) Maps.activate(); // Execute search using the URL scheme which is more reliable Maps.activate(); const encodedQuery = encodeURIComponent(args.query); Maps.openLocation(`maps://?q=${encodedQuery}`); // For backward compatibility also try the standard search method try { Maps.search(args.query); } catch (e) { // Ignore error if search is not supported } // Wait a bit for search results to populate delay(2); // 2 seconds // Try to get search results, if supported by the version of Maps const locations: MapLocation[] = []; try { // Different versions of Maps have different ways to access results // We'll need to use a different method for each version // Approach 1: Try to get locations directly // (this works on some versions of macOS) const selectedLocation = Maps.selectedLocation(); if (selectedLocation) { // If we have a selected location, use it const location: MapLocation = { id: `loc-${Date.now()}-${Math.random()}`, name: selectedLocation.name() || args.query, address: selectedLocation.formattedAddress() || "Address not available", latitude: selectedLocation.latitude(), longitude: selectedLocation.longitude(), category: selectedLocation.category ? selectedLocation.category() : null, isFavorite: false }; locations.push(location); } else { // If no selected location, use the search field value as name // and try to get coordinates by doing a UI script // Use the user entered search term for the result const location: MapLocation = { id: `loc-${Date.now()}-${Math.random()}`, name: args.query, address: "Search results - address details not available", latitude: null, longitude: null, category: null, isFavorite: false }; locations.push(location); } } catch (e) { // If the above didn't work, at least return something based on the query const location: MapLocation = { id: `loc-${Date.now()}-${Math.random()}`, name: args.query, address: "Search result - address details not available", latitude: null, longitude: null, category: null, isFavorite: false }; locations.push(location); } return locations.slice(0, args.limit); } catch (e) { return []; // Return empty array on any error } }, { query, limit }) as MapLocation[]; return { success: true, locations, message: locations.length > 0 ? `Found ${locations.length} location(s) for "${query}"` : `No locations found for "${query}"` }; } catch (error) { return { success: false, locations: [], message: `Error searching locations: ${error instanceof Error ? error.message : String(error)}` }; } }

Other Tools

Related Tools

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/supermemoryai/apple-mcp'

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