Skip to content

Commit ea4f76d

Browse files
cablateclaude
andauthored
feat: add exec CLI subcommand + agent skill definition (#33)
* feat: add exec CLI subcommand + agent skill definition Add standalone `exec` mode so tools can be invoked directly without running the MCP server — enabling use as an AI agent skill. - Add `exec <tool> [params]` yargs subcommand with all 8 tools - Add agent skill definition (skills/google-maps/) following agentskill-expertise design patterns - Add exec mode tests (10 assertions) to smoke test suite - Update README with CLI exec usage section - Remove unused express/path imports from cli.ts Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: trim README exec section, fix skill per agentskill-expertise review - Shorten README CLI Exec Mode to essentials - Move chaining patterns from SKILL.md to references/tools-api.md - Add "When to Update" section to SKILL.md - Add update trigger to description frontmatter Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: lead README with agent skill + MCP dual-mode intro Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: suppress stderr leak in exec unknown-tool test Add stdio: ['pipe', 'pipe', 'pipe'] to prevent child process stderr from leaking into test output. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 9f4422e commit ea4f76d

5 files changed

Lines changed: 534 additions & 52 deletions

File tree

README.md

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,18 @@
1616
1717
---
1818

19-
A Model Context Protocol (MCP) server providing comprehensive Google Maps API integration with streamable HTTP transport support and multi-session capabilities.
19+
Google Maps tools for AI agents — use as an **MCP server** or as a standalone **Agent Skill** via CLI.
20+
21+
```bash
22+
# Agent Skill — no server needed
23+
npx @cablate/mcp-google-map exec geocode '{"address":"Tokyo Tower"}'
24+
npx @cablate/mcp-google-map exec search-places '{"query":"ramen in Tokyo"}'
25+
26+
# MCP Server
27+
npx @cablate/mcp-google-map --port 3000 --apikey "YOUR_API_KEY"
28+
```
29+
30+
All 8 tools available in both modes. See [`skills/google-maps/`](./skills/google-maps/) for the full agent skill definition.
2031

2132
## Special Thanks
2233

@@ -108,6 +119,17 @@ GOOGLE_MAPS_API_KEY=YOUR_API_KEY npx @cablate/mcp-google-map
108119
- **Transport**: Streamable HTTP (not stdio)
109120
- **Tools**: 8 Google Maps tools
110121

122+
### CLI Exec Mode (Agent Skill)
123+
124+
Use tools directly without running the MCP server:
125+
126+
```bash
127+
npx @cablate/mcp-google-map exec geocode '{"address":"Tokyo Tower"}'
128+
npx @cablate/mcp-google-map exec search-places '{"query":"ramen in Tokyo"}'
129+
```
130+
131+
All 8 tools available: `geocode`, `reverse-geocode`, `search-nearby`, `search-places`, `place-details`, `directions`, `distance-matrix`, `elevation`. See [`skills/google-maps/`](./skills/google-maps/) for the agent skill definition and full parameter docs.
132+
111133
### API Key Configuration
112134

113135
API keys can be provided in three ways (priority order):
@@ -202,6 +224,11 @@ src/
202224
└── requestContext.ts # Per-request context (API key isolation)
203225
tests/
204226
└── smoke.test.ts # Smoke + E2E test suite
227+
skills/
228+
└── google-maps/
229+
├── SKILL.md # Agent skill definition
230+
└── references/
231+
└── tools-api.md # Tool parameter reference
205232
```
206233

207234
## Tech Stack

skills/google-maps/SKILL.md

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
---
2+
name: google-maps
3+
description: Geospatial query capabilities — geocoding, nearby search, routing, place details, elevation. Trigger when the user mentions locations, addresses, coordinates, navigation, "what's nearby", "how to get there", distance/duration, or any question that inherently involves geographic information — even if they don't explicitly say "map". Update when new tools are added or tool parameters change.
4+
---
5+
6+
# Google Maps - Geospatial Query Capabilities
7+
8+
## Overview
9+
10+
Gives an AI Agent the ability to reason about physical space — understand locations, distances, routes, and elevation, and naturally weave that information into conversation.
11+
12+
Without this Skill, the agent can only guess or refuse when asked "how do I get from Taipei 101 to the National Palace Museum?". With it, the agent returns exact coordinates, step-by-step routes, and travel times.
13+
14+
---
15+
16+
## Core Principles
17+
18+
| Principle | Explanation |
19+
|-----------|-------------|
20+
| Chain over single-shot | Most geo questions require chaining: geocode → search-nearby → place-details. Think about the full pipeline when planning queries. |
21+
| Precise input saves trouble | Use coordinates over address strings when available. Use place_id over name search. More precise input = more reliable output. |
22+
| Output is structured | Every tool returns JSON. Use it directly for downstream computation or comparison — no extra parsing needed. |
23+
24+
---
25+
26+
## Tool Map
27+
28+
8 tools in three categories — pick by scenario:
29+
30+
### Place Discovery
31+
| Tool | When to use | Example |
32+
|------|-------------|---------|
33+
| `geocode` | Have an address/landmark, need coordinates | "What are the coordinates of Tokyo Tower?" |
34+
| `reverse-geocode` | Have coordinates, need an address | "What's at 35.65, 139.74?" |
35+
| `search-nearby` | Know a location, find nearby places by type | "Coffee shops near my hotel" |
36+
| `search-places` | Natural language place search | "Best ramen in Tokyo" |
37+
| `place-details` | Have a place_id, need full info | "Opening hours and reviews for this restaurant?" |
38+
39+
### Routing & Distance
40+
| Tool | When to use | Example |
41+
|------|-------------|---------|
42+
| `directions` | How to get from A to B | "Route from Taipei Main Station to the airport" |
43+
| `distance-matrix` | Compare distances across multiple points | "Which of these 3 hotels is closest to the airport?" |
44+
45+
### Terrain
46+
| Tool | When to use | Example |
47+
|------|-------------|---------|
48+
| `elevation` | Query altitude | "Elevation profile along this hiking trail" |
49+
50+
---
51+
52+
## Invocation
53+
54+
```bash
55+
npx @cablate/mcp-google-map exec <tool> '<json_params>' [-k API_KEY]
56+
```
57+
58+
- **API Key**: `-k` flag or `GOOGLE_MAPS_API_KEY` environment variable
59+
- **Output**: JSON to stdout, errors to stderr
60+
- **Stateless**: each call is independent
61+
62+
---
63+
64+
## When to Update This Skill
65+
66+
| Trigger | What to update |
67+
|---------|----------------|
68+
| New tool added to the package | Tool Map table + references/tools-api.md |
69+
| Tool parameters changed | references/tools-api.md |
70+
| New chaining pattern discovered in practice | references/tools-api.md chaining section |
71+
72+
---
73+
74+
## Reference
75+
76+
| File | Content | When to read |
77+
|------|---------|--------------|
78+
| `references/tools-api.md` | Full parameter specs, response formats, and chaining patterns for all 8 tools | When you need exact parameter names, types, response shapes, or multi-tool workflows |
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
# Google Maps Tools - Parameter & Response Reference
2+
3+
## geocode
4+
5+
Convert an address or landmark name to GPS coordinates.
6+
7+
```bash
8+
exec geocode '{"address": "Tokyo Tower"}'
9+
```
10+
11+
| Param | Type | Required | Description |
12+
|-------|------|----------|-------------|
13+
| address | string | yes | Address or landmark name |
14+
15+
Response:
16+
```json
17+
{
18+
"success": true,
19+
"data": {
20+
"location": { "lat": 35.6585805, "lng": 139.7454329 },
21+
"formatted_address": "4-chome-2-8 Shibakoen, Minato City, Tokyo 105-0011, Japan",
22+
"place_id": "ChIJCewJkL2LGGAR3Qmk0vCTGkg"
23+
}
24+
}
25+
```
26+
27+
---
28+
29+
## reverse-geocode
30+
31+
Convert GPS coordinates to a street address.
32+
33+
```bash
34+
exec reverse-geocode '{"latitude": 35.6586, "longitude": 139.7454}'
35+
```
36+
37+
| Param | Type | Required | Description |
38+
|-------|------|----------|-------------|
39+
| latitude | number | yes | Latitude |
40+
| longitude | number | yes | Longitude |
41+
42+
Response:
43+
```json
44+
{
45+
"success": true,
46+
"data": {
47+
"formatted_address": "...",
48+
"place_id": "ChIJ...",
49+
"address_components": [...]
50+
}
51+
}
52+
```
53+
54+
---
55+
56+
## search-nearby
57+
58+
Find places near a location by type.
59+
60+
```bash
61+
exec search-nearby '{"center": {"value": "35.6586,139.7454", "isCoordinates": true}, "keyword": "restaurant", "radius": 500}'
62+
```
63+
64+
| Param | Type | Required | Description |
65+
|-------|------|----------|-------------|
66+
| center | object | yes | `{ value: string, isCoordinates: boolean }` — address or `lat,lng` |
67+
| keyword | string | no | Place type (restaurant, cafe, hotel, gas_station, hospital, etc.) |
68+
| radius | number | no | Search radius in meters (default: 1000) |
69+
| openNow | boolean | no | Only show currently open places |
70+
| minRating | number | no | Minimum rating (0-5) |
71+
72+
Response: `{ success, location, data: [{ name, place_id, formatted_address, geometry, rating, user_ratings_total, opening_hours }] }`
73+
74+
---
75+
76+
## search-places
77+
78+
Free-text place search. More flexible than search-nearby.
79+
80+
```bash
81+
exec search-places '{"query": "ramen in Tokyo"}'
82+
```
83+
84+
| Param | Type | Required | Description |
85+
|-------|------|----------|-------------|
86+
| query | string | yes | Natural language search query |
87+
| locationBias | object | no | `{ latitude, longitude, radius? }` to bias results toward |
88+
| openNow | boolean | no | Only show currently open places |
89+
| minRating | number | no | Minimum rating (1.0-5.0) |
90+
| includedType | string | no | Place type filter |
91+
92+
Response: `{ success, data: [{ name, place_id, address, location, rating, total_ratings, open_now }] }`
93+
94+
---
95+
96+
## place-details
97+
98+
Get full details for a place by its place_id (from search results). Returns reviews, phone, website, hours, photos.
99+
100+
```bash
101+
exec place-details '{"placeId": "ChIJCewJkL2LGGAR3Qmk0vCTGkg"}'
102+
```
103+
104+
| Param | Type | Required | Description |
105+
|-------|------|----------|-------------|
106+
| placeId | string | yes | Google Maps place ID (from search results) |
107+
108+
---
109+
110+
## directions
111+
112+
Get step-by-step navigation between two points.
113+
114+
```bash
115+
exec directions '{"origin": "Tokyo Tower", "destination": "Shibuya Station", "mode": "transit"}'
116+
```
117+
118+
| Param | Type | Required | Description |
119+
|-------|------|----------|-------------|
120+
| origin | string | yes | Starting point (address or landmark) |
121+
| destination | string | yes | End point (address or landmark) |
122+
| mode | string | no | Travel mode: driving, walking, bicycling, transit |
123+
| departure_time | string | no | Departure time (ISO 8601 or "now") |
124+
| arrival_time | string | no | Desired arrival time (transit only) |
125+
126+
---
127+
128+
## distance-matrix
129+
130+
Calculate travel distances and times between multiple origins and destinations.
131+
132+
```bash
133+
exec distance-matrix '{"origins": ["Tokyo Tower"], "destinations": ["Shibuya Station", "Shinjuku Station"], "mode": "driving"}'
134+
```
135+
136+
| Param | Type | Required | Description |
137+
|-------|------|----------|-------------|
138+
| origins | string[] | yes | List of origin addresses |
139+
| destinations | string[] | yes | List of destination addresses |
140+
| mode | string | no | Travel mode: driving, walking, bicycling, transit |
141+
142+
---
143+
144+
## elevation
145+
146+
Get elevation data for geographic coordinates.
147+
148+
```bash
149+
exec elevation '{"locations": [{"latitude": 35.6586, "longitude": 139.7454}]}'
150+
```
151+
152+
| Param | Type | Required | Description |
153+
|-------|------|----------|-------------|
154+
| locations | object[] | yes | Array of `{ latitude, longitude }` |
155+
156+
Response:
157+
```json
158+
[{ "elevation": 17.23, "location": { "lat": 35.6586, "lng": 139.7454 }, "resolution": 610.81 }]
159+
```
160+
161+
---
162+
163+
## Common Chaining Patterns
164+
165+
**Search → Details**
166+
```bash
167+
exec search-places '{"query":"Michelin restaurants in Taipei"}'
168+
exec place-details '{"placeId":"ChIJ..."}' # use place_id from results
169+
```
170+
171+
**Geocode → Nearby Search**
172+
```bash
173+
exec geocode '{"address":"Taipei 101"}'
174+
exec search-nearby '{"center":{"value":"25.033,121.564","isCoordinates":true},"keyword":"cafe","radius":500}'
175+
```
176+
177+
**Multi-point Comparison**
178+
```bash
179+
exec distance-matrix '{"origins":["Taipei Main Station","Banqiao Station"],"destinations":["Taoyuan Airport","Songshan Airport"],"mode":"driving"}'
180+
```

0 commit comments

Comments
 (0)