[{"data":1,"prerenderedAt":2174},["ShallowReactive",2],{"navigation_docs":3,"-mcp-setup":155,"-mcp-setup-surround":2169},[4,26,47,68,93,106,127],{"title":5,"path":6,"stem":7,"children":8,"page":25},"Getting Started","\u002Fgetting-started","1.getting-started",[9,13,17,21],{"title":10,"path":11,"stem":12},"Introduction","\u002Fgetting-started\u002Fintroduction","1.getting-started\u002F1.introduction",{"title":14,"path":15,"stem":16},"Quick Start","\u002Fgetting-started\u002Fquick-start","1.getting-started\u002F2.quick-start",{"title":18,"path":19,"stem":20},"Authentication","\u002Fgetting-started\u002Fauthentication","1.getting-started\u002F3.authentication",{"title":22,"path":23,"stem":24},"Rate Limits","\u002Fgetting-started\u002Frate-limits","1.getting-started\u002F4.rate-limits",false,{"title":27,"path":28,"stem":29,"children":30,"page":25},"API Reference","\u002Fapi-reference","2.api-reference",[31,35,39,43],{"title":32,"path":33,"stem":34},"Overview","\u002Fapi-reference\u002Foverview","2.api-reference\u002F1.overview",{"title":36,"path":37,"stem":38},"REST API","\u002Fapi-reference\u002Frest-api","2.api-reference\u002F2.rest-api",{"title":40,"path":41,"stem":42},"Error Codes","\u002Fapi-reference\u002Ferror-codes","2.api-reference\u002F3.error-codes",{"title":44,"path":45,"stem":46},"Pagination","\u002Fapi-reference\u002Fpagination","2.api-reference\u002F4.pagination",{"title":48,"path":49,"stem":50,"children":51,"page":25},"Map Integration","\u002Fmap-integration","3.map-integration",[52,56,60,64],{"title":53,"path":54,"stem":55},"Embed Maps","\u002Fmap-integration\u002Fembed-maps","3.map-integration\u002F1.embed-maps",{"title":57,"path":58,"stem":59},"Custom Styles","\u002Fmap-integration\u002Fcustom-styles","3.map-integration\u002F2.custom-styles",{"title":61,"path":62,"stem":63},"Tile Rendering","\u002Fmap-integration\u002Ftile-rendering","3.map-integration\u002F3.tile-rendering",{"title":65,"path":66,"stem":67},"Static Maps","\u002Fmap-integration\u002Fstatic-maps","3.map-integration\u002F4.static-maps",{"title":69,"path":70,"stem":71,"children":72,"page":25},"Geocoding","\u002Fgeocoding","4.geocoding",[73,77,81,85,89],{"title":74,"path":75,"stem":76},"Forward Geocoding (Search)","\u002Fgeocoding\u002Fforward-geocoding","4.geocoding\u002F1.forward-geocoding",{"title":78,"path":79,"stem":80},"Reverse Geocoding","\u002Fgeocoding\u002Freverse-geocoding","4.geocoding\u002F2.reverse-geocoding",{"title":82,"path":83,"stem":84},"Autocomplete","\u002Fgeocoding\u002Fautocomplete","4.geocoding\u002F3.autocomplete",{"title":86,"path":87,"stem":88},"Place Lookup","\u002Fgeocoding\u002Fplace-lookup","4.geocoding\u002F4.place-lookup",{"title":90,"path":91,"stem":92},"Nearby Search","\u002Fgeocoding\u002Fnearby","4.geocoding\u002F5.nearby",{"title":94,"path":95,"stem":96,"children":97,"page":25},"Routing","\u002Frouting","5.routing",[98,102],{"title":99,"path":100,"stem":101},"Directions","\u002Frouting\u002Fdirections","5.routing\u002F1.directions",{"title":103,"path":104,"stem":105},"Isochrones","\u002Frouting\u002Fisochrones","5.routing\u002F2.isochrones",{"title":107,"path":108,"stem":109,"children":110,"page":25},"Auth & Security","\u002Fauth-security","6.auth-security",[111,115,119,123],{"title":112,"path":113,"stem":114},"API Keys","\u002Fauth-security\u002Fapi-keys","6.auth-security\u002F1.api-keys",{"title":116,"path":117,"stem":118},"Scopes & Permissions","\u002Fauth-security\u002Fscopes-permissions","6.auth-security\u002F2.scopes-permissions",{"title":120,"path":121,"stem":122},"Rate Limiting","\u002Fauth-security\u002Frate-limiting","6.auth-security\u002F3.rate-limiting",{"title":124,"path":125,"stem":126},"Best Practices","\u002Fauth-security\u002Fbest-practices","6.auth-security\u002F4.best-practices",{"title":128,"path":129,"stem":130,"children":131,"page":25},"Mcp","\u002Fmcp","7.mcp",[132,135,139,143,147,151],{"title":32,"path":133,"stem":134},"\u002Fmcp\u002Foverview","7.mcp\u002F1.overview",{"title":136,"path":137,"stem":138},"Setup","\u002Fmcp\u002Fsetup","7.mcp\u002F2.setup",{"title":140,"path":141,"stem":142},"Available Tools","\u002Fmcp\u002Favailable-tools","7.mcp\u002F3.available-tools",{"title":144,"path":145,"stem":146},"GIS Integration","\u002Fmcp\u002Fgis-integration","7.mcp\u002F4.gis-integration",{"title":148,"path":149,"stem":150},"Examples","\u002Fmcp\u002Fexamples","7.mcp\u002F5.examples",{"title":152,"path":153,"stem":154},"Troubleshooting","\u002Fmcp\u002Ftroubleshooting","7.mcp\u002F6.troubleshooting",{"id":156,"title":136,"body":157,"description":2163,"extension":2164,"links":2165,"meta":2166,"navigation":1267,"path":137,"seo":2167,"stem":138,"__hash__":2168},"docs\u002F7.mcp\u002F2.setup.md",{"type":158,"value":159,"toc":2134},"minimark",[160,165,169,174,177,188,191,195,198,221,224,227,231,253,257,260,313,316,320,323,327,330,335,368,373,407,413,416,432,436,465,468,470,486,490,493,653,679,687,691,694,719,722,724,740,744,747,850,856,863,867,874,878,884,903,906,1019,1030,1043,1172,1182,1185,1233,1236,1240,1247,1692,1699,1703,1706,1738,1742,1762,1766,1769,1773,1785,1845,1860,1875,1879,1882,1915,1929,1948,1984,1999,2005,2023,2035,2039,2042,2046,2049,2054,2057,2062,2065,2069,2072,2106,2109,2113,2130],[161,162,164],"h2",{"id":163},"quick-install","Quick install",[166,167,168],"p",{},"The fastest way to install is to let an AI agent do it. Humans fat-finger configs.",[170,171,173],"h3",{"id":172},"for-humans","For humans",[166,175,176],{},"Copy this prompt into your LLM agent (Claude Code, Cursor, Codex, OpenCode, etc.) and let it drive the installation:",[178,179,185],"pre",{"className":180,"code":182,"language":183,"meta":184},[181],"language-text","Install and configure the maps.guru MCP server by following the\ninstructions here: https:\u002F\u002Fdocs.maps.guru\u002Fmcp\u002Finstall.md\n","text","",[186,187,182],"code",{"__ignoreMap":184},[166,189,190],{},"The agent will ask you which client you're using, get your API key, write the config, and run a verification prompt.",[170,192,194],{"id":193},"for-llm-agents","For LLM agents",[166,196,197],{},"Fetch the installation guide and follow the steps:",[178,199,203],{"className":200,"code":201,"language":202,"meta":184,"style":184},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","curl -s https:\u002F\u002Fdocs.maps.guru\u002Fmcp\u002Finstall.md\n","bash",[186,204,205],{"__ignoreMap":184},[206,207,210,214,218],"span",{"class":208,"line":209},"line",1,[206,211,213],{"class":212},"sBMFI","curl",[206,215,217],{"class":216},"sfazB"," -s",[206,219,220],{"class":216}," https:\u002F\u002Fdocs.maps.guru\u002Fmcp\u002Finstall.md\n",[166,222,223],{},"The guide is a short, decision-tree-shaped markdown file optimized for agent consumption. It covers transport selection, API key handling, per-client config paths, and verification.",[166,225,226],{},"If you prefer to read through the full human-facing setup manually, continue below.",[161,228,230],{"id":229},"prerequisites","Prerequisites",[232,233,234,250],"ul",{},[235,236,237,238,242,243],"li",{},"A ",[239,240,241],"strong",{},"maps.guru account"," with an API key from ",[244,245,249],"a",{"href":246,"rel":247},"https:\u002F\u002Fmaps.guru\u002Fdashboard\u002Ftokens",[248],"nofollow","maps.guru\u002Fdashboard\u002Ftokens",[235,251,252],{},"An MCP-compatible client, SDK, or agent platform",[161,254,256],{"id":255},"pick-the-right-transport","Pick the right transport",[166,258,259],{},"maps.guru MCP supports two transport modes. Which one you use depends on what your client supports:",[261,262,263,279],"table",{},[264,265,266],"thead",{},[267,268,269,273,276],"tr",{},[270,271,272],"th",{},"Method",[270,274,275],{},"URL \u002F Command",[270,277,278],{},"Best for",[280,281,282,298],"tbody",{},[267,283,284,290,295],{},[285,286,287],"td",{},[239,288,289],{},"Remote",[285,291,292],{},[186,293,294],{},"https:\u002F\u002Fmcp.maps.guru\u002Fmcp",[285,296,297],{},"Claude custom connectors, ChatGPT custom connectors, xAI API \u002F SDK, Copilot Studio",[267,299,300,305,310],{},[285,301,302],{},[239,303,304],{},"Local",[285,306,307],{},[186,308,309],{},"npx @invarya\u002Fmaps-mcp",[285,311,312],{},"Claude Desktop local MCP, Cursor, Windsurf, Cline, OpenCode, Gemini SDK",[166,314,315],{},"If you're unsure, remote is the easier option whenever your client supports it — there's nothing to install and authentication happens through a standard OAuth login on maps.guru.",[161,317,319],{"id":318},"remote-mcp","Remote MCP",[166,321,322],{},"Use the hosted endpoint whenever your client can connect to a public MCP server over HTTP.",[170,324,326],{"id":325},"claude-web-and-desktop-custom-connectors","Claude web and desktop custom connectors",[166,328,329],{},"Claude supports remote MCP custom connectors across its Pro, Max, Team, and Enterprise plans.",[166,331,332],{},[239,333,334],{},"Pro and Max:",[336,337,338,344,354,359,362,365],"ol",{},[235,339,340,341],{},"Open ",[239,342,343],{},"Customize → Connectors",[235,345,346,347,350,351],{},"Click ",[239,348,349],{},"+"," then ",[239,352,353],{},"Add custom connector",[235,355,356,357],{},"Enter ",[186,358,294],{},[235,360,361],{},"Leave advanced auth settings at the defaults unless your workspace admin says otherwise",[235,363,364],{},"Finish adding the connector",[235,366,367],{},"When Claude redirects to maps.guru, sign in and authorize",[166,369,370],{},[239,371,372],{},"Team and Enterprise:",[336,374,375,381,394,398],{},[235,376,377,378],{},"An owner opens ",[239,379,380],{},"Organization settings → Connectors",[235,382,346,383,386,387,390,391],{},[239,384,385],{},"Add",", choose ",[239,388,389],{},"Custom",", then ",[239,392,393],{},"Web",[235,395,356,396],{},[186,397,294],{},[235,399,400,401,403,404],{},"Once the connector is added, each user goes to ",[239,402,343],{}," and clicks ",[239,405,406],{},"Connect",[166,408,409,410,412],{},"Enable the connector per conversation from the ",[239,411,349],{}," button in chat.",[166,414,415],{},"References:",[232,417,418,425],{},[235,419,420],{},[244,421,424],{"href":422,"rel":423},"https:\u002F\u002Fsupport.claude.com\u002Fen\u002Farticles\u002F11175166-get-started-with-custom-connectors-using-remote-mcp",[248],"Anthropic: Get started with custom connectors using remote MCP",[235,426,427],{},[244,428,431],{"href":429,"rel":430},"https:\u002F\u002Fsupport.claude.com\u002Fen\u002Farticles\u002F11176164-use-connectors-to-extend-claude-s-capabilities",[248],"Anthropic: Use connectors to extend Claude's capabilities",[170,433,435],{"id":434},"chatgpt-custom-connector","ChatGPT custom connector",[336,437,438,443,450,456,462],{},[235,439,340,440],{},[239,441,442],{},"Settings → Connectors",[235,444,445,446,449],{},"If needed, enable ",[239,447,448],{},"Developer mode"," in advanced connector settings",[235,451,452,453],{},"Add a ",[239,454,455],{},"custom connector",[235,457,458,459,461],{},"Use ",[186,460,294],{}," as the MCP server URL",[235,463,464],{},"Complete the maps.guru authorization flow when ChatGPT redirects you",[166,466,467],{},"Custom connectors are available on Plus, Pro, Business, Enterprise, and Edu plans. Some workspace permissions depend on your plan and role.",[166,469,415],{},[232,471,472,479],{},[235,473,474],{},[244,475,478],{"href":476,"rel":477},"https:\u002F\u002Fhelp.openai.com\u002Fen\u002Farticles\u002F11487775-connectors-in-chatgpt\u002F",[248],"OpenAI Help: Connectors in ChatGPT",[235,480,481],{},[244,482,485],{"href":483,"rel":484},"https:\u002F\u002Fplatform.openai.com\u002Fdocs\u002Fmcp\u002F",[248],"OpenAI Docs: Building MCP servers for ChatGPT and API integrations",[170,487,489],{"id":488},"xai-api-sdk","xAI API \u002F SDK",[166,491,492],{},"For Grok-powered tooling, use maps.guru as a remote MCP tool in the xAI Responses API:",[178,494,496],{"className":200,"code":495,"language":202,"meta":184,"style":184},"curl https:\u002F\u002Fapi.x.ai\u002Fv1\u002Fresponses \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -H \"Authorization: Bearer $XAI_API_KEY\" \\\n  -d '{\n    \"model\": \"grok-4-1-fast-reasoning\",\n    \"input\": [\n      {\n        \"role\": \"user\",\n        \"content\": \"Geocode Connaught Place in New Delhi\"\n      }\n    ],\n    \"tools\": [\n      {\n        \"type\": \"mcp\",\n        \"server_url\": \"https:\u002F\u002Fmcp.maps.guru\u002Fmcp\",\n        \"server_label\": \"maps-guru\",\n        \"authorization\": \"Bearer eyJ...your_jwt_here\"\n      }\n    ]\n  }'\n",[186,497,498,509,527,544,556,562,568,574,580,586,592,598,604,609,615,621,627,633,638,644],{"__ignoreMap":184},[206,499,500,502,505],{"class":208,"line":209},[206,501,213],{"class":212},[206,503,504],{"class":216}," https:\u002F\u002Fapi.x.ai\u002Fv1\u002Fresponses",[206,506,508],{"class":507},"sTEyZ"," \\\n",[206,510,512,515,519,522,525],{"class":208,"line":511},2,[206,513,514],{"class":216},"  -H",[206,516,518],{"class":517},"sMK4o"," \"",[206,520,521],{"class":216},"Content-Type: application\u002Fjson",[206,523,524],{"class":517},"\"",[206,526,508],{"class":507},[206,528,530,532,534,537,540,542],{"class":208,"line":529},3,[206,531,514],{"class":216},[206,533,518],{"class":517},[206,535,536],{"class":216},"Authorization: Bearer ",[206,538,539],{"class":507},"$XAI_API_KEY",[206,541,524],{"class":517},[206,543,508],{"class":507},[206,545,547,550,553],{"class":208,"line":546},4,[206,548,549],{"class":216},"  -d",[206,551,552],{"class":517}," '",[206,554,555],{"class":216},"{\n",[206,557,559],{"class":208,"line":558},5,[206,560,561],{"class":216},"    \"model\": \"grok-4-1-fast-reasoning\",\n",[206,563,565],{"class":208,"line":564},6,[206,566,567],{"class":216},"    \"input\": [\n",[206,569,571],{"class":208,"line":570},7,[206,572,573],{"class":216},"      {\n",[206,575,577],{"class":208,"line":576},8,[206,578,579],{"class":216},"        \"role\": \"user\",\n",[206,581,583],{"class":208,"line":582},9,[206,584,585],{"class":216},"        \"content\": \"Geocode Connaught Place in New Delhi\"\n",[206,587,589],{"class":208,"line":588},10,[206,590,591],{"class":216},"      }\n",[206,593,595],{"class":208,"line":594},11,[206,596,597],{"class":216},"    ],\n",[206,599,601],{"class":208,"line":600},12,[206,602,603],{"class":216},"    \"tools\": [\n",[206,605,607],{"class":208,"line":606},13,[206,608,573],{"class":216},[206,610,612],{"class":208,"line":611},14,[206,613,614],{"class":216},"        \"type\": \"mcp\",\n",[206,616,618],{"class":208,"line":617},15,[206,619,620],{"class":216},"        \"server_url\": \"https:\u002F\u002Fmcp.maps.guru\u002Fmcp\",\n",[206,622,624],{"class":208,"line":623},16,[206,625,626],{"class":216},"        \"server_label\": \"maps-guru\",\n",[206,628,630],{"class":208,"line":629},17,[206,631,632],{"class":216},"        \"authorization\": \"Bearer eyJ...your_jwt_here\"\n",[206,634,636],{"class":208,"line":635},18,[206,637,591],{"class":216},[206,639,641],{"class":208,"line":640},19,[206,642,643],{"class":216},"    ]\n",[206,645,647,650],{"class":208,"line":646},20,[206,648,649],{"class":216},"  }",[206,651,652],{"class":517},"'\n",[166,654,655,658,659,662,663,666,667,669,670,673,674,678],{},[186,656,657],{},"mcp.maps.guru\u002Fmcp"," requires an ",[239,660,661],{},"OAuth 2.1 JWT bearer token"," — not a ",[186,664,665],{},"mapx_"," API key. Long-lived ",[186,668,665],{}," keys are accepted on the public maps, tiles, and geocoding APIs (",[186,671,672],{},"maps.guru\u002Fapi\u002Fv1\u002F*","), but the MCP surface is OAuth-only. Get a JWT by completing the OAuth flow at ",[244,675,676],{"href":676,"rel":677},"https:\u002F\u002Fmaps.guru\u002F.well-known\u002Foauth-authorization-server",[248]," (most clients do this automatically on first connect).",[166,680,681,682],{},"Reference: ",[244,683,686],{"href":684,"rel":685},"https:\u002F\u002Fdocs.x.ai\u002Fdevelopers\u002Ftools\u002Fremote-mcp",[248],"xAI: Remote MCP Tools",[170,688,690],{"id":689},"microsoft-copilot-studio","Microsoft Copilot Studio",[166,692,693],{},"This flow is for Copilot Studio agents, not the consumer Copilot chat app.",[336,695,696,702,709,713,716],{},[235,697,698,699],{},"Open your agent in ",[239,700,701],{},"Copilot Studio",[235,703,704,705,708],{},"Use the ",[239,706,707],{},"MCP onboarding wizard"," to connect an existing MCP server",[235,710,356,711],{},[186,712,294],{},[235,714,715],{},"Add the connected MCP server to the agent's tools",[235,717,718],{},"Authenticate when prompted",[166,720,721],{},"Copilot Studio currently supports Streamable transport for MCP.",[166,723,415],{},[232,725,726,733],{},[235,727,728],{},[244,729,732],{"href":730,"rel":731},"https:\u002F\u002Flearn.microsoft.com\u002Fen-us\u002Fmicrosoft-copilot-studio\u002Fmcp-add-existing-server-to-agent",[248],"Microsoft Learn: Connect your agent to an existing MCP server",[235,734,735],{},[244,736,739],{"href":737,"rel":738},"https:\u002F\u002Flearn.microsoft.com\u002Fen-us\u002Fmicrosoft-copilot-studio\u002Fagent-extend-action-mcp",[248],"Microsoft Learn: Extend your agent with Model Context Protocol",[170,741,743],{"id":742},"direct-api-usage-with-openai-responses","Direct API usage with OpenAI Responses",[166,745,746],{},"If you're building your own app against the OpenAI API (instead of ChatGPT's UI), pass maps.guru as a remote MCP tool:",[178,748,750],{"className":200,"code":749,"language":202,"meta":184,"style":184},"curl https:\u002F\u002Fapi.openai.com\u002Fv1\u002Fresponses \\\n  -H \"Authorization: Bearer $OPENAI_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"model\": \"gpt-5\",\n    \"input\": \"Geocode the Eiffel Tower in Paris\",\n    \"tools\": [\n      {\n        \"type\": \"mcp\",\n        \"server_url\": \"https:\u002F\u002Fmcp.maps.guru\u002Fmcp\",\n        \"server_label\": \"maps-guru\",\n        \"authorization\": \"Bearer eyJ...your_jwt_here\",\n        \"require_approval\": \"never\"\n      }\n    ]\n  }'\n",[186,751,752,761,776,788,796,801,806,810,814,818,822,826,831,836,840,844],{"__ignoreMap":184},[206,753,754,756,759],{"class":208,"line":209},[206,755,213],{"class":212},[206,757,758],{"class":216}," https:\u002F\u002Fapi.openai.com\u002Fv1\u002Fresponses",[206,760,508],{"class":507},[206,762,763,765,767,769,772,774],{"class":208,"line":511},[206,764,514],{"class":216},[206,766,518],{"class":517},[206,768,536],{"class":216},[206,770,771],{"class":507},"$OPENAI_API_KEY",[206,773,524],{"class":517},[206,775,508],{"class":507},[206,777,778,780,782,784,786],{"class":208,"line":529},[206,779,514],{"class":216},[206,781,518],{"class":517},[206,783,521],{"class":216},[206,785,524],{"class":517},[206,787,508],{"class":507},[206,789,790,792,794],{"class":208,"line":546},[206,791,549],{"class":216},[206,793,552],{"class":517},[206,795,555],{"class":216},[206,797,798],{"class":208,"line":558},[206,799,800],{"class":216},"    \"model\": \"gpt-5\",\n",[206,802,803],{"class":208,"line":564},[206,804,805],{"class":216},"    \"input\": \"Geocode the Eiffel Tower in Paris\",\n",[206,807,808],{"class":208,"line":570},[206,809,603],{"class":216},[206,811,812],{"class":208,"line":576},[206,813,573],{"class":216},[206,815,816],{"class":208,"line":582},[206,817,614],{"class":216},[206,819,820],{"class":208,"line":588},[206,821,620],{"class":216},[206,823,824],{"class":208,"line":594},[206,825,626],{"class":216},[206,827,828],{"class":208,"line":600},[206,829,830],{"class":216},"        \"authorization\": \"Bearer eyJ...your_jwt_here\",\n",[206,832,833],{"class":208,"line":606},[206,834,835],{"class":216},"        \"require_approval\": \"never\"\n",[206,837,838],{"class":208,"line":611},[206,839,591],{"class":216},[206,841,842],{"class":208,"line":617},[206,843,643],{"class":216},[206,845,846,848],{"class":208,"line":623},[206,847,649],{"class":216},[206,849,652],{"class":517},[166,851,852,853,855],{},"Same OAuth-only rule applies: pass a Better-Auth-issued JWT, not a ",[186,854,665],{}," key. ChatGPT's custom-connector UI handles the OAuth dance for you; for direct API usage you'll need to obtain a token via the OAuth 2.1 flow first.",[166,857,681,858],{},[244,859,862],{"href":860,"rel":861},"https:\u002F\u002Fplatform.openai.com\u002Fdocs\u002Fguides\u002Ftools-remote-mcp",[248],"OpenAI Docs: Connectors and remote MCP servers",[161,864,866],{"id":865},"local-mcp","Local MCP",[166,868,869,870,873],{},"Use local mode when your client launches MCP servers as local commands over stdio. Requires ",[239,871,872],{},"Node.js 18+",".",[170,875,877],{"id":876},"claude-desktop-cursor-windsurf-cline-and-opencode","Claude Desktop, Cursor, Windsurf, Cline, and OpenCode",[166,879,880,883],{},[239,881,882],{},"Recommended (OAuth 2.1 login):"," Sign in once with the CLI, then point your client at the server. Credentials are stored in your OS keychain — no secrets in config files.",[178,885,887],{"className":200,"code":886,"language":202,"meta":184,"style":184},"npx @invarya\u002Fmaps-mcp auth login\n",[186,888,889],{"__ignoreMap":184},[206,890,891,894,897,900],{"class":208,"line":209},[206,892,893],{"class":212},"npx",[206,895,896],{"class":216}," @invarya\u002Fmaps-mcp",[206,898,899],{"class":216}," auth",[206,901,902],{"class":216}," login\n",[166,904,905],{},"The CLI opens your browser to maps.guru, waits for you to approve the requested scopes, and stores the resulting JWT + refresh token in the keychain. After that, drop this into your client's MCP config:",[178,907,911],{"className":908,"code":909,"language":910,"meta":184,"style":184},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\n  \"mcpServers\": {\n    \"maps-guru\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@invarya\u002Fmaps-mcp\"]\n    }\n  }\n}\n","json",[186,912,913,917,934,948,970,1004,1009,1014],{"__ignoreMap":184},[206,914,915],{"class":208,"line":209},[206,916,555],{"class":517},[206,918,919,922,926,928,931],{"class":208,"line":511},[206,920,921],{"class":517},"  \"",[206,923,925],{"class":924},"spNyl","mcpServers",[206,927,524],{"class":517},[206,929,930],{"class":517},":",[206,932,933],{"class":517}," {\n",[206,935,936,939,942,944,946],{"class":208,"line":529},[206,937,938],{"class":517},"    \"",[206,940,941],{"class":212},"maps-guru",[206,943,524],{"class":517},[206,945,930],{"class":517},[206,947,933],{"class":517},[206,949,950,953,957,959,961,963,965,967],{"class":208,"line":546},[206,951,952],{"class":517},"      \"",[206,954,956],{"class":955},"sbssI","command",[206,958,524],{"class":517},[206,960,930],{"class":517},[206,962,518],{"class":517},[206,964,893],{"class":216},[206,966,524],{"class":517},[206,968,969],{"class":517},",\n",[206,971,972,974,977,979,981,984,986,989,991,994,996,999,1001],{"class":208,"line":558},[206,973,952],{"class":517},[206,975,976],{"class":955},"args",[206,978,524],{"class":517},[206,980,930],{"class":517},[206,982,983],{"class":517}," [",[206,985,524],{"class":517},[206,987,988],{"class":216},"-y",[206,990,524],{"class":517},[206,992,993],{"class":517},",",[206,995,518],{"class":517},[206,997,998],{"class":216},"@invarya\u002Fmaps-mcp",[206,1000,524],{"class":517},[206,1002,1003],{"class":517},"]\n",[206,1005,1006],{"class":208,"line":564},[206,1007,1008],{"class":517},"    }\n",[206,1010,1011],{"class":208,"line":570},[206,1012,1013],{"class":517},"  }\n",[206,1015,1016],{"class":208,"line":576},[206,1017,1018],{"class":517},"}\n",[166,1020,1021,1022,1025,1026,1029],{},"The server reads JWT credentials from the keychain on every launch and auto-refreshes them 60 seconds before expiry. Run ",[186,1023,1024],{},"npx @invarya\u002Fmaps-mcp auth status"," to verify (shows your email address, scopes granted, time to expiry), or ",[186,1027,1028],{},"auth logout"," to remove stored credentials and delete the per-machine OAuth client on the server.",[166,1031,1032,1035,1036,1039,1040,930],{},[239,1033,1034],{},"Legacy (mapx_ env var):"," If you can't use the keychain (CI environments, headless servers without ",[186,1037,1038],{},"libsecret",", or you'd rather paste an API key), keep using ",[186,1041,1042],{},"MAPS_GURU_API_KEY",[178,1044,1046],{"className":908,"code":1045,"language":910,"meta":184,"style":184},"{\n  \"mcpServers\": {\n    \"maps-guru\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@invarya\u002Fmaps-mcp\"],\n      \"env\": {\n        \"MAPS_GURU_API_KEY\": \"mapx_your_api_key_here\"\n      }\n    }\n  }\n}\n",[186,1047,1048,1052,1064,1076,1094,1123,1136,1156,1160,1164,1168],{"__ignoreMap":184},[206,1049,1050],{"class":208,"line":209},[206,1051,555],{"class":517},[206,1053,1054,1056,1058,1060,1062],{"class":208,"line":511},[206,1055,921],{"class":517},[206,1057,925],{"class":924},[206,1059,524],{"class":517},[206,1061,930],{"class":517},[206,1063,933],{"class":517},[206,1065,1066,1068,1070,1072,1074],{"class":208,"line":529},[206,1067,938],{"class":517},[206,1069,941],{"class":212},[206,1071,524],{"class":517},[206,1073,930],{"class":517},[206,1075,933],{"class":517},[206,1077,1078,1080,1082,1084,1086,1088,1090,1092],{"class":208,"line":546},[206,1079,952],{"class":517},[206,1081,956],{"class":955},[206,1083,524],{"class":517},[206,1085,930],{"class":517},[206,1087,518],{"class":517},[206,1089,893],{"class":216},[206,1091,524],{"class":517},[206,1093,969],{"class":517},[206,1095,1096,1098,1100,1102,1104,1106,1108,1110,1112,1114,1116,1118,1120],{"class":208,"line":558},[206,1097,952],{"class":517},[206,1099,976],{"class":955},[206,1101,524],{"class":517},[206,1103,930],{"class":517},[206,1105,983],{"class":517},[206,1107,524],{"class":517},[206,1109,988],{"class":216},[206,1111,524],{"class":517},[206,1113,993],{"class":517},[206,1115,518],{"class":517},[206,1117,998],{"class":216},[206,1119,524],{"class":517},[206,1121,1122],{"class":517},"],\n",[206,1124,1125,1127,1130,1132,1134],{"class":208,"line":564},[206,1126,952],{"class":517},[206,1128,1129],{"class":955},"env",[206,1131,524],{"class":517},[206,1133,930],{"class":517},[206,1135,933],{"class":517},[206,1137,1138,1141,1144,1146,1148,1150,1153],{"class":208,"line":570},[206,1139,1140],{"class":517},"        \"",[206,1142,1042],{"class":1143},"swJcz",[206,1145,524],{"class":517},[206,1147,930],{"class":517},[206,1149,518],{"class":517},[206,1151,1152],{"class":216},"mapx_your_api_key_here",[206,1154,1155],{"class":517},"\"\n",[206,1157,1158],{"class":208,"line":576},[206,1159,591],{"class":517},[206,1161,1162],{"class":208,"line":582},[206,1163,1008],{"class":517},[206,1165,1166],{"class":208,"line":588},[206,1167,1013],{"class":517},[206,1169,1170],{"class":208,"line":594},[206,1171,1018],{"class":517},[166,1173,1174,1175,1178,1179,1181],{},"Both paths stay supported. The CLI checks ",[186,1176,1177],{},"MAPS_GURU_BEARER_TOKEN"," env first, then keychain, then ",[186,1180,1042],{}," env, then errors.",[166,1183,1184],{},"Config locations by client:",[232,1186,1187,1205,1215,1221,1227],{},[235,1188,1189,1192,1193,1196,1197,1200,1201,1204],{},[239,1190,1191],{},"Claude Desktop",": ",[186,1194,1195],{},"~\u002FLibrary\u002FApplication Support\u002FClaude\u002Fclaude_desktop_config.json"," on macOS, ",[186,1198,1199],{},"%APPDATA%\\Claude\\claude_desktop_config.json"," on Windows, ",[186,1202,1203],{},"~\u002F.config\u002FClaude\u002Fclaude_desktop_config.json"," on Linux",[235,1206,1207,1210,1211,1214],{},[239,1208,1209],{},"Cursor",": project ",[186,1212,1213],{},".cursor\u002Fmcp.json"," or your global Cursor MCP settings",[235,1216,1217,1220],{},[239,1218,1219],{},"Windsurf",": your Windsurf MCP settings file",[235,1222,1223,1226],{},[239,1224,1225],{},"Cline",": VS Code Cline MCP settings",[235,1228,1229,1232],{},[239,1230,1231],{},"OpenCode",": your OpenCode MCP configuration",[166,1234,1235],{},"Restart the client after saving.",[170,1237,1239],{"id":1238},"google-gemini-sdk","Google Gemini SDK",[166,1241,1242,1243,1246],{},"Google's MCP integration lives in the ",[239,1244,1245],{},"Gen AI SDK"," and is marked experimental. Here's the local stdio path in Python:",[178,1248,1252],{"className":1249,"code":1250,"language":1251,"meta":184,"style":184},"language-python shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import asyncio\n\nfrom google import genai\nfrom mcp import ClientSession, StdioServerParameters\nfrom mcp.client.stdio import stdio_client\n\nclient = genai.Client()\n\nserver_params = StdioServerParameters(\n    command=\"npx\",\n    args=[\"-y\", \"@invarya\u002Fmaps-mcp\"],\n    env={\"MAPS_GURU_API_KEY\": \"mapx_your_api_key_here\"},\n)\n\nasync def run():\n    async with stdio_client(server_params) as (read, write):\n        async with ClientSession(read, write) as session:\n            await session.initialize()\n            response = await client.aio.models.generate_content(\n                model=\"gemini-2.5-flash\",\n                contents=\"Geocode Bengaluru Palace\",\n                config=genai.types.GenerateContentConfig(\n                    tools=[session],\n                    temperature=0,\n                ),\n            )\n            print(response.text)\n\nasyncio.run(run())\n","python",[186,1253,1254,1263,1269,1282,1299,1321,1325,1345,1349,1362,1378,1402,1427,1432,1436,1450,1487,1514,1528,1558,1574,1591,1614,1627,1640,1646,1652,1669,1674],{"__ignoreMap":184},[206,1255,1256,1260],{"class":208,"line":209},[206,1257,1259],{"class":1258},"s7zQu","import",[206,1261,1262],{"class":507}," asyncio\n",[206,1264,1265],{"class":208,"line":511},[206,1266,1268],{"emptyLinePlaceholder":1267},true,"\n",[206,1270,1271,1274,1277,1279],{"class":208,"line":529},[206,1272,1273],{"class":1258},"from",[206,1275,1276],{"class":507}," google ",[206,1278,1259],{"class":1258},[206,1280,1281],{"class":507}," genai\n",[206,1283,1284,1286,1289,1291,1294,1296],{"class":208,"line":546},[206,1285,1273],{"class":1258},[206,1287,1288],{"class":507}," mcp ",[206,1290,1259],{"class":1258},[206,1292,1293],{"class":507}," ClientSession",[206,1295,993],{"class":517},[206,1297,1298],{"class":507}," StdioServerParameters\n",[206,1300,1301,1303,1306,1308,1311,1313,1316,1318],{"class":208,"line":558},[206,1302,1273],{"class":1258},[206,1304,1305],{"class":507}," mcp",[206,1307,873],{"class":517},[206,1309,1310],{"class":507},"client",[206,1312,873],{"class":517},[206,1314,1315],{"class":507},"stdio ",[206,1317,1259],{"class":1258},[206,1319,1320],{"class":507}," stdio_client\n",[206,1322,1323],{"class":208,"line":564},[206,1324,1268],{"emptyLinePlaceholder":1267},[206,1326,1327,1330,1333,1336,1338,1342],{"class":208,"line":570},[206,1328,1329],{"class":507},"client ",[206,1331,1332],{"class":517},"=",[206,1334,1335],{"class":507}," genai",[206,1337,873],{"class":517},[206,1339,1341],{"class":1340},"s2Zo4","Client",[206,1343,1344],{"class":517},"()\n",[206,1346,1347],{"class":208,"line":576},[206,1348,1268],{"emptyLinePlaceholder":1267},[206,1350,1351,1354,1356,1359],{"class":208,"line":582},[206,1352,1353],{"class":507},"server_params ",[206,1355,1332],{"class":517},[206,1357,1358],{"class":1340}," StdioServerParameters",[206,1360,1361],{"class":517},"(\n",[206,1363,1364,1368,1370,1372,1374,1376],{"class":208,"line":588},[206,1365,1367],{"class":1366},"sHdIc","    command",[206,1369,1332],{"class":517},[206,1371,524],{"class":517},[206,1373,893],{"class":216},[206,1375,524],{"class":517},[206,1377,969],{"class":517},[206,1379,1380,1383,1386,1388,1390,1392,1394,1396,1398,1400],{"class":208,"line":594},[206,1381,1382],{"class":1366},"    args",[206,1384,1385],{"class":517},"=[",[206,1387,524],{"class":517},[206,1389,988],{"class":216},[206,1391,524],{"class":517},[206,1393,993],{"class":517},[206,1395,518],{"class":517},[206,1397,998],{"class":216},[206,1399,524],{"class":517},[206,1401,1122],{"class":517},[206,1403,1404,1407,1410,1412,1414,1416,1418,1420,1422,1424],{"class":208,"line":600},[206,1405,1406],{"class":1366},"    env",[206,1408,1409],{"class":517},"={",[206,1411,524],{"class":517},[206,1413,1042],{"class":216},[206,1415,524],{"class":517},[206,1417,930],{"class":517},[206,1419,518],{"class":517},[206,1421,1152],{"class":216},[206,1423,524],{"class":517},[206,1425,1426],{"class":517},"},\n",[206,1428,1429],{"class":208,"line":606},[206,1430,1431],{"class":517},")\n",[206,1433,1434],{"class":208,"line":611},[206,1435,1268],{"emptyLinePlaceholder":1267},[206,1437,1438,1441,1444,1447],{"class":208,"line":617},[206,1439,1440],{"class":924},"async",[206,1442,1443],{"class":924}," def",[206,1445,1446],{"class":1340}," run",[206,1448,1449],{"class":517},"():\n",[206,1451,1452,1455,1458,1461,1464,1467,1470,1473,1476,1479,1481,1484],{"class":208,"line":623},[206,1453,1454],{"class":1258},"    async",[206,1456,1457],{"class":1258}," with",[206,1459,1460],{"class":1340}," stdio_client",[206,1462,1463],{"class":517},"(",[206,1465,1466],{"class":1340},"server_params",[206,1468,1469],{"class":517},")",[206,1471,1472],{"class":1258}," as",[206,1474,1475],{"class":517}," (",[206,1477,1478],{"class":507},"read",[206,1480,993],{"class":517},[206,1482,1483],{"class":507}," write",[206,1485,1486],{"class":517},"):\n",[206,1488,1489,1492,1494,1496,1498,1500,1502,1504,1506,1508,1511],{"class":208,"line":629},[206,1490,1491],{"class":1258},"        async",[206,1493,1457],{"class":1258},[206,1495,1293],{"class":1340},[206,1497,1463],{"class":517},[206,1499,1478],{"class":1340},[206,1501,993],{"class":517},[206,1503,1483],{"class":1340},[206,1505,1469],{"class":517},[206,1507,1472],{"class":1258},[206,1509,1510],{"class":507}," session",[206,1512,1513],{"class":517},":\n",[206,1515,1516,1519,1521,1523,1526],{"class":208,"line":635},[206,1517,1518],{"class":1258},"            await",[206,1520,1510],{"class":507},[206,1522,873],{"class":517},[206,1524,1525],{"class":1340},"initialize",[206,1527,1344],{"class":517},[206,1529,1530,1533,1535,1538,1541,1543,1546,1548,1551,1553,1556],{"class":208,"line":640},[206,1531,1532],{"class":507},"            response ",[206,1534,1332],{"class":517},[206,1536,1537],{"class":1258}," await",[206,1539,1540],{"class":507}," client",[206,1542,873],{"class":517},[206,1544,1545],{"class":1143},"aio",[206,1547,873],{"class":517},[206,1549,1550],{"class":1143},"models",[206,1552,873],{"class":517},[206,1554,1555],{"class":1340},"generate_content",[206,1557,1361],{"class":517},[206,1559,1560,1563,1565,1567,1570,1572],{"class":208,"line":646},[206,1561,1562],{"class":1366},"                model",[206,1564,1332],{"class":517},[206,1566,524],{"class":517},[206,1568,1569],{"class":216},"gemini-2.5-flash",[206,1571,524],{"class":517},[206,1573,969],{"class":517},[206,1575,1577,1580,1582,1584,1587,1589],{"class":208,"line":1576},21,[206,1578,1579],{"class":1366},"                contents",[206,1581,1332],{"class":517},[206,1583,524],{"class":517},[206,1585,1586],{"class":216},"Geocode Bengaluru Palace",[206,1588,524],{"class":517},[206,1590,969],{"class":517},[206,1592,1594,1597,1599,1602,1604,1607,1609,1612],{"class":208,"line":1593},22,[206,1595,1596],{"class":1366},"                config",[206,1598,1332],{"class":517},[206,1600,1601],{"class":1340},"genai",[206,1603,873],{"class":517},[206,1605,1606],{"class":1143},"types",[206,1608,873],{"class":517},[206,1610,1611],{"class":1340},"GenerateContentConfig",[206,1613,1361],{"class":517},[206,1615,1617,1620,1622,1625],{"class":208,"line":1616},23,[206,1618,1619],{"class":1366},"                    tools",[206,1621,1385],{"class":517},[206,1623,1624],{"class":1340},"session",[206,1626,1122],{"class":517},[206,1628,1630,1633,1635,1638],{"class":208,"line":1629},24,[206,1631,1632],{"class":1366},"                    temperature",[206,1634,1332],{"class":517},[206,1636,1637],{"class":955},"0",[206,1639,969],{"class":517},[206,1641,1643],{"class":208,"line":1642},25,[206,1644,1645],{"class":517},"                ),\n",[206,1647,1649],{"class":208,"line":1648},26,[206,1650,1651],{"class":517},"            )\n",[206,1653,1655,1658,1660,1663,1665,1667],{"class":208,"line":1654},27,[206,1656,1657],{"class":1340},"            print",[206,1659,1463],{"class":517},[206,1661,1662],{"class":1340},"response",[206,1664,873],{"class":517},[206,1666,183],{"class":1143},[206,1668,1431],{"class":517},[206,1670,1672],{"class":208,"line":1671},28,[206,1673,1268],{"emptyLinePlaceholder":1267},[206,1675,1677,1680,1682,1685,1687,1689],{"class":208,"line":1676},29,[206,1678,1679],{"class":507},"asyncio",[206,1681,873],{"class":517},[206,1683,1684],{"class":1340},"run",[206,1686,1463],{"class":517},[206,1688,1684],{"class":1340},[206,1690,1691],{"class":517},"())\n",[166,1693,681,1694],{},[244,1695,1698],{"href":1696,"rel":1697},"https:\u002F\u002Fgoogleapis.github.io\u002Fpython-genai\u002F",[248],"Google Gen AI SDK docs",[161,1700,1702],{"id":1701},"clients-we-dont-have-a-first-party-setup-path-for","Clients we don't have a first-party setup path for",[166,1704,1705],{},"A few products that get asked about regularly either don't support third-party MCP servers from their UI or only support MCP through an SDK\u002FAPI path we've already covered above. If one of these is what you're using, you'll want to fall back to the SDK\u002FAPI integration path:",[232,1707,1708,1714,1726,1732],{},[235,1709,1710,1713],{},[239,1711,1712],{},"Google AI Studio UI"," — Google's published MCP guidance lives in the Gemini SDK docs. Use the Python example above rather than looking for a custom-connector button in AI Studio.",[235,1715,1716,1719,1720,1725],{},[239,1717,1718],{},"Perplexity"," — Perplexity ships its own ",[244,1721,1724],{"href":1722,"rel":1723},"https:\u002F\u002Fdocs.perplexity.ai\u002Fguides\u002Fmcp-server",[248],"MCP server",", but there's no public flow for adding third-party MCP servers inside the Perplexity product UI.",[235,1727,1728,1731],{},[239,1729,1730],{},"Grok app \u002F grok.com"," — xAI's MCP support is through the API and SDK (see above), not a settings flow in the Grok web app.",[235,1733,1734,1737],{},[239,1735,1736],{},"Microsoft Copilot consumer app"," — Microsoft's MCP docs target Copilot Studio agents, not the consumer Copilot chat app.",[161,1739,1741],{"id":1740},"getting-your-api-key","Getting your API key",[336,1743,1744,1752,1757],{},[235,1745,1746,1747],{},"Sign in to ",[244,1748,1751],{"href":1749,"rel":1750},"https:\u002F\u002Fmaps.guru",[248],"maps.guru",[235,1753,340,1754],{},[244,1755,249],{"href":246,"rel":1756},[248],[235,1758,1759,1760],{},"Copy an existing key or create a new one — your key starts with ",[186,1761,665],{},[161,1763,1765],{"id":1764},"security-how-authentication-actually-works","Security: how authentication actually works",[166,1767,1768],{},"How maps.guru MCP authenticates depends on which transport you picked. The two modes have very different trust models.",[170,1770,1772],{"id":1771},"remote-mode-oauth-21-with-pkce-only-auth-method","Remote mode: OAuth 2.1 with PKCE (only auth method)",[166,1774,1775,1777,1778,1781,1782,1784],{},[186,1776,294],{}," accepts ",[239,1779,1780],{},"OAuth 2.1 access tokens, and nothing else."," ",[186,1783,665],{}," API keys are explicitly rejected on the MCP surface. The flow:",[336,1786,1787,1794,1807,1816,1829],{},[235,1788,1789,1790,1793],{},"The MCP client (Claude, ChatGPT, Copilot Studio, etc.) discovers the OAuth metadata at ",[186,1791,1792],{},"https:\u002F\u002Fmcp.maps.guru\u002F.well-known\u002Foauth-authorization-server",", which redirects to maps.guru's Better-Auth authorization server.",[235,1795,1796,1797,1800,1801,1806],{},"The client opens an authorization URL at ",[186,1798,1799],{},"maps.guru\u002Fapi\u002Fv1\u002Fauth\u002Foauth2\u002Fauthorize"," and dynamically registers itself via ",[244,1802,1805],{"href":1803,"rel":1804},"https:\u002F\u002Fdatatracker.ietf.org\u002Fdoc\u002Fhtml\u002Frfc7591",[248],"RFC 7591"," if needed.",[235,1808,1809,1810,1815],{},"You sign in to maps.guru, see the consent screen at ",[244,1811,1814],{"href":1812,"rel":1813},"https:\u002F\u002Fmaps.guru\u002Fconsent",[248],"maps.guru\u002Fconsent",", and approve the requested scopes.",[235,1817,1818,1819,1822,1823,1828],{},"maps.guru issues a short-lived JWT access token (audience ",[186,1820,1821],{},"https:\u002F\u002Fmcp.maps.guru"," per ",[244,1824,1827],{"href":1825,"rel":1826},"https:\u002F\u002Fdatatracker.ietf.org\u002Fdoc\u002Fhtml\u002Frfc8707",[248],"RFC 8707",") plus a refresh token.",[235,1830,1831,1832,1835,1836,1838,1839,1844],{},"The MCP client sends ",[186,1833,1834],{},"Authorization: Bearer \u003Cjwt>"," on every ",[186,1837,129],{}," call. mcp-worker verifies the signature against ",[244,1840,1843],{"href":1841,"rel":1842},"https:\u002F\u002Fmaps.guru\u002Fapi\u002Fv1\u002Fauth\u002Fjwks",[248],"maps.guru\u002Fapi\u002Fv1\u002Fauth\u002Fjwks"," on the edge.",[166,1846,1847,1848,1853,1854],{},"You can review and revoke any granted client at ",[244,1849,1852],{"href":1850,"rel":1851},"https:\u002F\u002Fmaps.guru\u002Fdashboard\u002Fsettings\u002Fconnected-apps",[248],"maps.guru\u002Fdashboard\u002Fsettings\u002Fconnected-apps",". Revoking a consent invalidates that client's refresh token immediately and forces a fresh OAuth flow on the next request. ",[239,1855,1856,1857,1859],{},"You never have to rotate a ",[186,1858,665],{}," key to lock out a misbehaving MCP client.",[1861,1862,1863],"blockquote",{},[166,1864,1865,1866,1868,1869,1871,1872,1874],{},"Why no ",[186,1867,665],{}," on the MCP surface? ",[186,1870,665],{}," keys are long-lived bearers — possession equals access. When a key leaks (logs, screenshots, shared configs, an LLM provider's infrastructure), the attacker fully impersonates you within that key's scopes. JWTs solve this with three properties ",[186,1873,665],{}," can't: short lifetime, per-client binding, and per-grant revocability via the dashboard.",[170,1876,1878],{"id":1877},"local-mode-oauth-21-login-recommended-or-bearer-token","Local mode: OAuth 2.1 login (recommended) or bearer token",[166,1880,1881],{},"stdio MCP runs locally on your machine and authenticates two ways:",[166,1883,1884,1887,1888,1891,1892,1895,1896,1899,1900,1903,1904,1907,1908,1911,1912,873],{},[239,1885,1886],{},"OAuth 2.1 login (recommended):"," Run ",[186,1889,1890],{},"npx @invarya\u002Fmaps-mcp auth login"," once. The CLI spins up an ephemeral localhost listener, opens your browser to the maps.guru consent screen, and waits for the authorization-code redirect. You approve the requested scopes, the browser redirects to ",[186,1893,1894],{},"http:\u002F\u002F127.0.0.1:\u003Crandom-port>\u002Fcallback",", and the CLI exchanges the code for a short-lived JWT (1 hour) plus a refresh token. Both land in your ",[239,1897,1898],{},"OS keychain"," — Keychain on macOS, Credential Manager on Windows, libsecret on Linux. The MCP server reads the JWT on every launch and refreshes it automatically 60 seconds before expiry. Your ",[186,1901,1902],{},"auth status"," shows the email address from the token (no raw ULIDs). Same UX you already know from ",[186,1905,1906],{},"gh auth login",", ",[186,1909,1910],{},"aws sso login",", and ",[186,1913,1914],{},"doctl auth init",[166,1916,1917,1918,1920,1921,1924,1925,1928],{},"If the keychain is unavailable (headless Linux without ",[186,1919,1038],{},", etc.), the CLI falls back to ",[186,1922,1923],{},"~\u002F.config\u002Fmaps-guru\u002Fcredentials.json"," with ",[186,1926,1927],{},"chmod 0600"," and prints a warning.",[166,1930,1931,1934,1935,1937,1938,1940,1941,1944,1945,1947],{},[239,1932,1933],{},"Legacy bearer token via env var:"," If you can't or won't use the keychain — CI environments, ephemeral containers, or just preference — set ",[186,1936,1042],{}," to a ",[186,1939,665],{}," key. The server picks it up and sends it as a ",[186,1942,1943],{},"Bearer"," token to ",[186,1946,672],{},". This path stays fully supported for backwards compatibility.",[166,1949,1950,1951,1954,1955,1958,1959,1962,1963,1965,1966,1971,1972,1977,1978,1907,1981,1983],{},"How the CLI does OAuth without a long-lived server: every time you run ",[186,1952,1953],{},"auth login",", the CLI binds to an ephemeral loopback port (",[186,1956,1957],{},"http:\u002F\u002F127.0.0.1:0\u002Fcallback",") and sets that exact URL as the ",[186,1960,1961],{},"redirect_uri"," on the authorization request. Your browser follows the redirect back to that listener, which receives the ",[186,1964,186],{},", completes the PKCE (",[244,1967,1970],{"href":1968,"rel":1969},"https:\u002F\u002Fdatatracker.ietf.org\u002Fdoc\u002Fhtml\u002Frfc7636",[248],"RFC 7636",") exchange, then shuts down. This is the OAuth 2.1 native-app pattern described in ",[244,1973,1976],{"href":1974,"rel":1975},"https:\u002F\u002Fdatatracker.ietf.org\u002Fdoc\u002Fhtml\u002Frfc8252#section-7.3",[248],"RFC 8252 §7.3"," — the same flow ",[186,1979,1980],{},"gcloud auth login",[186,1982,1910],{},", and every modern CLI uses.",[166,1985,1986,1987,1992,1993,1995,1996,1998],{},"Manage active CLI installs at ",[244,1988,1991],{"href":1989,"rel":1990},"https:\u002F\u002Fmaps.guru\u002Fdashboard\u002Fsettings\u002Fdevices",[248],"maps.guru\u002Fdashboard\u002Fsettings\u002Fdevices",". Each ",[186,1994,1953],{}," on a new machine shows up as its own row; revoking a device kills that machine's refresh token immediately and forces a fresh ",[186,1997,1953],{}," on the next request.",[166,2000,2001,2002,2004],{},"If you stick with the ",[186,2003,665],{}," env-var path, treat the key like a password:",[232,2006,2007,2010,2013,2020],{},[235,2008,2009],{},"Don't commit keys to source control, chat transcripts, or shared docs.",[235,2011,2012],{},"Don't paste keys into MCP clients you don't trust or haven't vetted.",[235,2014,2015,2016,2019],{},"If a key might have leaked, rotate it at ",[244,2017,249],{"href":246,"rel":2018},[248],". All existing MCP configs using that key stop working until you update them — which is the point.",[235,2021,2022],{},"Create a dedicated key per machine or per client if you want tighter blast radius. That way you can revoke one without disturbing the others.",[166,2024,2025,2027,2028,1475,2031,2034],{},[186,2026,665],{}," keys remain fully supported — and recommended — for the ",[239,2029,2030],{},"public maps, tiles, and geocoding APIs",[186,2032,2033],{},"maps.guru\u002Fapi\u002Fv1\u002Fstyles\u002Fpublic\u002F*?key=…",", embed URLs, MapTiler-style integrations). The MCP-surface deprecation is scoped: it does not affect any other product surface.",[170,2036,2038],{"id":2037},"scope-your-keys","Scope your keys",[166,2040,2041],{},"API keys on maps.guru are scoped. When creating a key specifically for MCP, you can mint one with only the scopes the MCP tools actually need and skip billing or admin scopes entirely. That way even if the key leaks, the damage is limited to what that key could already do — and you can revoke it without touching anything else.",[161,2043,2045],{"id":2044},"verifying-the-setup","Verifying the setup",[166,2047,2048],{},"After connecting, try:",[1861,2050,2051],{},[166,2052,2053],{},"\"What maps.guru tools do you have?\"",[166,2055,2056],{},"Then:",[1861,2058,2059],{},[166,2060,2061],{},"\"Geocode the Eiffel Tower in Paris\"",[166,2063,2064],{},"If the assistant lists tools and returns coordinates, you're good.",[161,2066,2068],{"id":2067},"testing-with-mcp-inspector","Testing with MCP Inspector",[166,2070,2071],{},"For local debugging:",[178,2073,2075],{"className":200,"code":2074,"language":202,"meta":184,"style":184},"MAPS_GURU_API_KEY=\"mapx_your_key\" \\\n  npx @modelcontextprotocol\u002Finspector npx @invarya\u002Fmaps-mcp\n",[186,2076,2077,2092],{"__ignoreMap":184},[206,2078,2079,2081,2083,2085,2088,2090],{"class":208,"line":209},[206,2080,1042],{"class":507},[206,2082,1332],{"class":517},[206,2084,524],{"class":517},[206,2086,2087],{"class":216},"mapx_your_key",[206,2089,524],{"class":517},[206,2091,508],{"class":212},[206,2093,2094,2097,2100,2103],{"class":208,"line":511},[206,2095,2096],{"class":216},"  npx",[206,2098,2099],{"class":216}," @modelcontextprotocol\u002Finspector",[206,2101,2102],{"class":216}," npx",[206,2104,2105],{"class":216}," @invarya\u002Fmaps-mcp\n",[166,2107,2108],{},"This opens the MCP Inspector UI — you can browse tools and invoke them manually to see raw responses.",[161,2110,2112],{"id":2111},"next-steps","Next steps",[232,2114,2115,2120,2125],{},[235,2116,2117,2119],{},[244,2118,140],{"href":141}," — full tool reference",[235,2121,2122,2124],{},[244,2123,148],{"href":149}," — real usage patterns",[235,2126,2127,2129],{},[244,2128,144],{"href":145}," — QGIS and MapLibre workflows",[2131,2132,2133],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}",{"title":184,"searchDepth":529,"depth":529,"links":2135},[2136,2140,2141,2142,2149,2153,2154,2155,2160,2161,2162],{"id":163,"depth":511,"text":164,"children":2137},[2138,2139],{"id":172,"depth":529,"text":173},{"id":193,"depth":529,"text":194},{"id":229,"depth":511,"text":230},{"id":255,"depth":511,"text":256},{"id":318,"depth":511,"text":319,"children":2143},[2144,2145,2146,2147,2148],{"id":325,"depth":529,"text":326},{"id":434,"depth":529,"text":435},{"id":488,"depth":529,"text":489},{"id":689,"depth":529,"text":690},{"id":742,"depth":529,"text":743},{"id":865,"depth":511,"text":866,"children":2150},[2151,2152],{"id":876,"depth":529,"text":877},{"id":1238,"depth":529,"text":1239},{"id":1701,"depth":511,"text":1702},{"id":1740,"depth":511,"text":1741},{"id":1764,"depth":511,"text":1765,"children":2156},[2157,2158,2159],{"id":1771,"depth":529,"text":1772},{"id":1877,"depth":529,"text":1878},{"id":2037,"depth":529,"text":2038},{"id":2044,"depth":511,"text":2045},{"id":2067,"depth":511,"text":2068},{"id":2111,"depth":511,"text":2112},"Connect maps.guru MCP using verified setup paths for Claude, ChatGPT, Copilot Studio, local MCP clients, and SDK-based workflows.","md",null,{},{"title":136,"description":2163},"_xmSrOwEprmSQmpZ5QVMrIxAybfJ_2L18gHaCZgYJrE",[2170,2172],{"title":32,"path":133,"stem":134,"description":2171,"children":-1},"Learn how the Model Context Protocol (MCP) connects maps.guru to AI assistants and GIS tools.",{"title":140,"path":141,"stem":142,"description":2173,"children":-1},"Complete reference for all 15 MCP tools provided by the maps.guru MCP server.",1777621084634]