KS
Killer-Skills

google-maps — Categories.community

v1.0.0
GitHub

About this Skill

Perfect for Location-Based Agents needing advanced geospatial data visualization and mapping capabilities through Google Maps integration. Manage the history of work on your fleet service equipment using secure, sharable QR codes.

Columbia-Cloudworks-LLC Columbia-Cloudworks-LLC
[0]
[0]
Updated: 3/4/2026

Quality Score

Top 5%
57
Excellent
Based on code quality & docs
Installation
SYS Universal Install (Auto-Detect)
Cursor IDE Windsurf IDE VS Code IDE
> npx killer-skills add Columbia-Cloudworks-LLC/EquipQR/google-maps

Agent Capability Analysis

The google-maps MCP Server by Columbia-Cloudworks-LLC is an open-source Categories.community integration for Claude and other AI agents, enabling seamless task automation and capability expansion.

Ideal Agent Persona

Perfect for Location-Based Agents needing advanced geospatial data visualization and mapping capabilities through Google Maps integration.

Core Value

Empowers agents to leverage Google Maps for Fleet Map visualization, Places Autocomplete address picking, and Geocoding, utilizing secure sharable QR codes and Supabase Edge Functions for seamless integration.

Capabilities Granted for google-maps MCP Server

Visualizing fleet service equipment locations on a map
Automating address suggestions using Places Autocomplete
Geocoding addresses for precise location-based services

! Prerequisites & Limits

  • Requires Google Maps API key
  • Dependent on Supabase Edge Functions for server-side integration
  • Limited to Google Maps services and features
Project
SKILL.md
8.6 KB
.cursorrules
1.2 KB
package.json
240 B
Ready
UTF-8

# Tags

[No tags]
SKILL.md
Readonly

Google Maps Integration — EquipQR

Architecture Overview

EquipQR uses Google Maps for three main features: Fleet Map visualization, Places Autocomplete address picking, and Geocoding. The integration spans frontend hooks/components and server-side Supabase Edge Functions.

Browser                                    Supabase Edge Functions
───────                                    ──────────────────────
useGoogleMapsKey ──→ public-google-maps-key ──→ GOOGLE_MAPS_BROWSER_KEY
useGoogleMapsLoader ──→ Google Maps JS API (loads <script> with browser key)
GooglePlacesAutocomplete ──→ PlaceAutocompleteElement (web component)
                         └─→ places-autocomplete edge fn (fallback) ──→ GOOGLE_MAPS_SERVER_KEY
MapView (GoogleMap) ──→ @react-google-maps/api
ClickableAddress ──→ maps.google.com deep link
geocode-location edge fn ──→ GOOGLE_MAPS_SERVER_KEY + geocoded_locations cache

API Keys

Two separate keys with different restrictions:

KeyEnv VarWhere SetUsed By
Browser keyGOOGLE_MAPS_BROWSER_KEYSupabase Edge Function secretspublic-google-maps-key → served to browser
Server keyGOOGLE_MAPS_SERVER_KEYSupabase Edge Function secretsgeocode-location, places-autocomplete

Local development: Set both in supabase/functions/.env (NOT the root .env).

Production: Set in Supabase Dashboard → Project → Settings → Edge Functions → Secrets.

Important: These are NOT Vercel env vars. Redeploying on Vercel does not affect these secrets.

Legacy key names (still supported with fallback)

Legacy NameNew Canonical Name
VITE_GOOGLE_MAPS_BROWSER_KEYGOOGLE_MAPS_BROWSER_KEY
GOOGLE_MAPS_API_KEYGOOGLE_MAPS_SERVER_KEY
VITE_GOOGLE_MAPS_API_KEYGOOGLE_MAPS_SERVER_KEY

All edge functions prefer the new name and fall back to legacy names.

Frontend Components & Hooks

useGoogleMapsKey (src/hooks/useGoogleMapsKey.ts)

Fetches the browser API key from the public-google-maps-key edge function. Returns { googleMapsKey, isLoading, error, retry }.

useGoogleMapsLoader (src/hooks/useGoogleMapsLoader.ts)

Singleton Google Maps JS API loader. Ensures the <script> tag is loaded exactly once across all components. Returns { isLoaded, loadError, googleMapsKey, isKeyLoading, keyError, retry }.

Always use this hook — never load the Maps JS API manually.

GooglePlacesAutocomplete (src/components/ui/GooglePlacesAutocomplete.tsx)

Address picker with three-tier fallback strategy:

  1. Web componentPlaceAutocompleteElement (Google's native widget)
  2. Edge functionplaces-autocomplete edge function proxy (if web component fails, e.g. Places API New not enabled)
  3. Plain text — simple text input fallback

Props: { value, onPlaceSelect, onClear, placeholder, disabled, className, isLoaded }.

Returns PlaceLocationData: { formatted_address, street, city, state, country, lat, lng }.

MapView (src/features/fleet-map/components/MapView.tsx)

Fleet map component using @react-google-maps/api (GoogleMap, MarkerF, InfoWindowF). Renders colored markers by location source (team, equipment, scan, geocoded) and star markers for team HQ locations.

ClickableAddress (src/components/ui/ClickableAddress.tsx)

Renders an address as a link that opens Google Maps.

Edge Functions

public-google-maps-key

  • Purpose: Serve the browser API key to authenticated users
  • Auth: JWT required (verify_jwt = true)
  • Key: GOOGLE_MAPS_BROWSER_KEY
  • Pattern: User-scoped client with requireUser

geocode-location

  • Purpose: Geocode addresses with caching in geocoded_locations table
  • Auth: JWT + org membership verification
  • Key: GOOGLE_MAPS_SERVER_KEY
  • Rate limit: 30 cache misses per org per minute
  • Cache: geocoded_locations table (upsert on organization_id, normalized_text)
  • Input normalization: lowercase, trim, collapse whitespace

places-autocomplete

  • Purpose: Proxy Google Places Autocomplete and Details APIs
  • Auth: JWT required
  • Key: GOOGLE_MAPS_SERVER_KEY
  • Actions: autocomplete (predictions) and details (structured address)
  • Validation: Zod discriminated union schema

Common Tasks

Adding a new map feature

  1. Use useGoogleMapsLoader to get isLoaded state
  2. Only render Google Maps components when isLoaded === true
  3. Handle loadError and keyError gracefully with error boundaries
tsx
1import { useGoogleMapsLoader } from '@/hooks/useGoogleMapsLoader'; 2 3function MyMapFeature() { 4 const { isLoaded, loadError, retry } = useGoogleMapsLoader(); 5 6 if (loadError) return <ErrorState onRetry={retry} />; 7 if (!isLoaded) return <Skeleton />; 8 9 return <GoogleMap /* ... */ />; 10}

Using the address picker

tsx
1import GooglePlacesAutocomplete, { PlaceLocationData } from '@/components/ui/GooglePlacesAutocomplete'; 2import { useGoogleMapsLoader } from '@/hooks/useGoogleMapsLoader'; 3 4function AddressField() { 5 const { isLoaded } = useGoogleMapsLoader(); 6 7 const handlePlaceSelect = (data: PlaceLocationData) => { 8 // data.formatted_address, data.street, data.city, 9 // data.state, data.country, data.lat, data.lng 10 }; 11 12 return ( 13 <GooglePlacesAutocomplete 14 isLoaded={isLoaded} 15 onPlaceSelect={handlePlaceSelect} 16 placeholder="Enter address..." 17 /> 18 ); 19}

Geocoding an address server-side

Call the geocode-location edge function:

ts
1const { data, error } = await supabase.functions.invoke('geocode-location', { 2 body: { organizationId: orgId, input: addressString } 3}); 4// data: { lat, lng, formatted_address } or { lat: null, lng: null }

Adding a new Edge Function that uses Google Maps

  1. Use the edge-function-creator skill to scaffold the function
  2. Read the server key: Deno.env.get("GOOGLE_MAPS_SERVER_KEY")
  3. Always fall back to legacy names: || Deno.env.get("GOOGLE_MAPS_API_KEY")
  4. Never expose the server key in responses — only return processed data

Debugging

"Map Configuration Error" toast

The browser key fetch failed. Check:

  1. GOOGLE_MAPS_BROWSER_KEY is set in Supabase Edge Function secrets
  2. The public-google-maps-key function is deployed
  3. The user is authenticated (JWT required)

Places autocomplete not showing results

  1. Check if web component mode failed (console: AutocompletePlaces blocked)
  2. The component auto-falls-back to edge function mode
  3. Verify GOOGLE_MAPS_SERVER_KEY is set in Supabase secrets
  4. Check the places-autocomplete edge function logs

Geocoding returns { lat: null, lng: null }

  1. Address may be unresolvable — check raw address string
  2. Rate limit may be exceeded (30/min/org) — check for 429 responses
  3. Verify GOOGLE_MAPS_SERVER_KEY is valid and has Geocoding API enabled

Fleet map markers not appearing

  1. Confirm isLoaded is true before rendering <GoogleMap>
  2. Check that equipment has valid lat/lng coordinates
  3. Verify the location source in EquipmentLocation.source field

Google Cloud Console requirements

The project requires these APIs enabled:

APIUsed By
Maps JavaScript APIFleet map, web component autocomplete
Places APIWeb component autocomplete
Places API (Legacy)places-autocomplete edge function
Geocoding APIgeocode-location edge function

Browser key restrictions should allow the app's domain(s). Server key should have no referrer restrictions (IP restrictions recommended).

Key files

FilePurpose
src/hooks/useGoogleMapsKey.tsFetch browser API key from edge function
src/hooks/useGoogleMapsLoader.tsSingleton Maps JS API loader
src/components/ui/GooglePlacesAutocomplete.tsxAddress picker component
src/components/ui/ClickableAddress.tsxAddress → Google Maps link
src/features/fleet-map/components/MapView.tsxFleet map with markers
src/features/fleet-map/pages/FleetMap.tsxFleet map page
src/features/fleet-map/components/FleetMapErrorBoundary.tsxMap error boundary
src/utils/effectiveLocation.tsLocation resolution + Maps URL builder
src/services/placesAutocompleteService.tsEdge function client for places
supabase/functions/public-google-maps-key/index.tsBrowser key edge function
supabase/functions/geocode-location/index.tsGeocoding edge function
supabase/functions/places-autocomplete/index.tsPlaces proxy edge function

Related Skills

Looking for an alternative to google-maps or building a Categories.community AI Agent? Explore these related open-source MCP Servers.

View All

widget-generator

Logo of f
f

widget-generator is an open-source AI agent skill for creating widget plugins that are injected into prompt feeds on prompts.chat. It supports two rendering modes: standard prompt widgets using default PromptCard styling and custom render widgets built as full React components.

149.6k
0
Design

chat-sdk

Logo of lobehub
lobehub

chat-sdk is a unified TypeScript SDK for building chat bots across multiple platforms, providing a single interface for deploying bot logic.

73.0k
0
Communication

zustand

Logo of lobehub
lobehub

The ultimate space for work and life — to find, build, and collaborate with agent teammates that grow with you. We are taking agent harness to the next level — enabling multi-agent collaboration, effortless agent team design, and introducing agents as the unit of work interaction.

72.8k
0
Communication

data-fetching

Logo of lobehub
lobehub

The ultimate space for work and life — to find, build, and collaborate with agent teammates that grow with you. We are taking agent harness to the next level — enabling multi-agent collaboration, effortless agent team design, and introducing agents as the unit of work interaction.

72.8k
0
Communication