Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .agents/plugins/marketplace.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"name": "cablate",
"interface": {
"displayName": "CabLate Plugins"
},
"plugins": [
{
"name": "mcp-google-map",
"source": {
"source": "npm",
"package": "@cablate/mcp-google-map",
"version": "latest",
"registry": "https://registry.npmjs.org"
},
"policy": {
"installation": "AVAILABLE",
"authentication": "ON_INSTALL"
},
"category": "Productivity"
}
]
}
File renamed without changes.
28 changes: 28 additions & 0 deletions .codex-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"name": "mcp-google-map",
"version": "0.0.63",
"description": "Use Google Maps-backed place search, routing, geocoding, weather, air quality, and geographic analysis through a standalone CLI.",
"author": {
"name": "CabLate",
"url": "https://github.com/cablate"
},
"homepage": "https://github.com/cablate/mcp-google-map",
"repository": "https://github.com/cablate/mcp-google-map",
"license": "MIT",
"keywords": ["google-maps", "places", "routing", "geocoding", "travel", "agent-skill"],
"skills": "./skills/",
"interface": {
"displayName": "Google Maps CLI",
"shortDescription": "Geospatial research and planning through a standalone CLI.",
"longDescription": "Guide an AI agent to use the @cablate/mcp-google-map exec CLI for place discovery, routing, geocoding, travel planning, local SEO, weather, air quality, and other geographic workflows. No MCP connection is required.",
"developerName": "CabLate",
"category": "Productivity",
"capabilities": ["Read"],
"websiteURL": "https://github.com/cablate/mcp-google-map",
"defaultPrompt": [
"Find and compare places for my trip.",
"Plan an efficient route between these stops.",
"Research what is near this location."
]
}
}
8 changes: 6 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,11 @@ jobs:
git pull --rebase

- name: Bump version
run: npm version patch --no-git-tag-version
run: |
npm version patch --no-git-tag-version
VERSION=$(node -p "require('./package.json').version")
jq --arg v "$VERSION" '.version = $v' plugin.json > plugin.tmp && mv plugin.tmp plugin.json
jq --arg v "$VERSION" '.version = $v' .codex-plugin/plugin.json > plugin.tmp && mv plugin.tmp .codex-plugin/plugin.json

- name: Update CHANGELOG
run: |
Expand Down Expand Up @@ -161,7 +165,7 @@ jobs:
- name: Commit version bump & tag
run: |
VERSION=$(node -p "require('./package.json').version")
git add package.json package-lock.json CHANGELOG.md server.json
git add package.json package-lock.json CHANGELOG.md server.json plugin.json .codex-plugin/plugin.json
git commit -m "chore: release v${VERSION}"
git tag "v${VERSION}"
git pull --rebase
Expand Down
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ node_modules/
credentials.json
.env
.agents/*
!.agents/plugins/
!.agents/plugins/marketplace.json
!.agents/skills/
!.agents/skills/project-docs/
!.agents/skills/project-docs/**
.mcpregistry_*
.mcp.json
output/
output/
25 changes: 17 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,17 @@ All tools are annotated with `readOnlyHint: true` and `destructiveHint: false`

## Installation

### Codex Plugin (Agent Skill, no MCP required)

Install the CabLate marketplace, then install the Skill-only plugin:

```bash
codex plugin marketplace add cablate/mcp-google-map --ref main
codex plugin add mcp-google-map@cablate
```

Set `GOOGLE_MAPS_API_KEY` in the environment available to Codex, make sure Node.js 18+ and `npx` are installed, then start a new conversation. The plugin teaches the agent to run `npx -y @cablate/mcp-google-map exec ...` directly. It does not register or start an MCP server; the MCP setup below remains an independent option.

### Method 1: stdio (Recommended for most clients)

Works with Claude Desktop, Cursor, VS Code, and any MCP client that supports stdio:
Expand Down Expand Up @@ -290,20 +301,18 @@ src/
tests/
└── smoke.test.ts # Smoke + E2E test suite
skills/
├── google-maps/ # Agent Skill — how to USE the tools
└── google-maps/ # Public Agent Skill — standalone CLI workflows
│ ├── SKILL.md # Tool map, recipes, invocation
│ ├── SKILL.skill # Importable archive of this Skill
│ └── references/
│ ├── tools-api.md # Tool parameters + scenario recipes
│ ├── travel-planning.md # Travel planning methodology
│ └── local-seo.md # Local SEO / Google Business Profile ranking analysis
└── project-docs/ # Project Skill — how to DEVELOP/MAINTAIN
├── SKILL.md # Architecture overview + onboarding
└── references/
├── architecture.md # System design, code map, 9-file checklist
├── google-maps-api-guide.md # API endpoints, pricing, gotchas
├── geo-domain-knowledge.md # GIS fundamentals, Japan context
└── decisions.md # 10 ADRs (design decisions + rationale)
.agents/
├── plugins/marketplace.json # CabLate marketplace catalog
└── skills/project-docs/ # Maintainer-only development Skill
.codex-plugin/plugin.json # Codex compatibility manifest
plugin.json # Portable Agent Plugin manifest
```

## Tech Stack
Expand Down
25 changes: 17 additions & 8 deletions README.zh-TW.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,17 @@ npx @cablate/mcp-google-map --port 3000 --apikey "YOUR_API_KEY"

## 安裝

### Codex Plugin(Agent Skill,不需要 MCP)

先加入 CabLate marketplace,再安裝只包含 Skill 的 plugin:

```bash
codex plugin marketplace add cablate/mcp-google-map --ref main
codex plugin add mcp-google-map@cablate
```

請在 Codex 可讀取的環境中設定 `GOOGLE_MAPS_API_KEY`,並確認已安裝 Node.js 18+ 與 `npx`,然後開啟新對話。Plugin 會教代理直接執行 `npx -y @cablate/mcp-google-map exec ...`;它不會註冊或啟動 MCP server。下方的 MCP 設定仍是另一種獨立使用方式。

### 方法一:stdio(大多數客戶端推薦)

適用於 Claude Desktop、Cursor、VS Code 及任何支援 stdio 的 MCP 客戶端:
Expand Down Expand Up @@ -287,20 +298,18 @@ src/
tests/
└── smoke.test.ts # Smoke + E2E 測試套件
skills/
├── google-maps/ # Agent Skill — 如何使用工具
└── google-maps/ # 公開 Agent Skill — 獨立 CLI 工作流程
│ ├── SKILL.md # 工具對照表、場景食譜、呼叫方式
│ ├── SKILL.skill # 可匯入的 Skill 封裝檔
│ └── references/
│ ├── tools-api.md # 工具參數 + 場景食譜
│ ├── travel-planning.md # 旅行規劃方法論
│ └── local-seo.md # Local SEO / Google 商家排名分析
└── project-docs/ # Project Skill — 如何開發/維護
├── SKILL.md # 架構概覽 + 入門指南
└── references/
├── architecture.md # 系統設計、code map、9 檔案 checklist
├── google-maps-api-guide.md # API 端點、定價、注意事項
├── geo-domain-knowledge.md # GIS 基礎、日本場景
└── decisions.md # 10 個 ADR(設計決策 + 理由)
.agents/
├── plugins/marketplace.json # CabLate marketplace 目錄
└── skills/project-docs/ # 僅供維護者使用的開發 Skill
.codex-plugin/plugin.json # Codex 相容 manifest
plugin.json # 可攜式 Agent Plugin manifest
```

## 技術棧
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
"dist",
"dist/**/*.map",
"README.md",
"plugin.json",
".codex-plugin",
"skills",
"examples"
],
Expand Down
14 changes: 14 additions & 0 deletions plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
"name": "mcp-google-map",
"version": "0.0.63",
"description": "Use Google Maps-backed place search, routing, geocoding, weather, air quality, and geographic analysis through a standalone CLI.",
"author": {
"name": "CabLate",
"url": "https://github.com/cablate"
},
"homepage": "https://github.com/cablate/mcp-google-map",
"repository": "https://github.com/cablate/mcp-google-map",
"license": "MIT",
"keywords": ["google-maps", "places", "routing", "geocoding", "travel", "agent-skill"]
}
2 changes: 0 additions & 2 deletions skills/google-maps/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,5 +111,3 @@ npx -y @cablate/mcp-google-map exec <tool> '<json_params>'
| `references/travel-planning.md` | Travel planning methodology — 6-layer model, Search Along Route, anti-patterns | When planning multi-day trips — **read before Recipe 1** |
| `references/local-seo.md` | Local SEO / Google Business Profile ranking analysis — competitor audit, keyword landscape, gap analysis | When analyzing business rankings, comparing competitors, or scouting locations |
| `references/content-attribution.md` | Google Maps content attribution, source links, AI disclosure, and storage limits | Before presenting reviews, photos, or AI summaries from Places |

> For **project development** knowledge (architecture, API guide, GIS domain, design decisions), see `skills/project-docs/SKILL.md`.
Binary file modified skills/google-maps/SKILL.skill
Binary file not shown.
60 changes: 60 additions & 0 deletions tests/pluginPackage.unit.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
import test from "node:test";

interface PluginManifest {
name: string;
version: string;
skills?: string;
mcpServers?: unknown;
}

interface PackageManifest {
version: string;
files: string[];
}

interface Marketplace {
name: string;
plugins: Array<{
name: string;
source: Record<string, string>;
policy: { installation: string; authentication: string };
}>;
}

function readJson<T>(path: string): T {
return JSON.parse(readFileSync(new URL(`../${path}`, import.meta.url), "utf8")) as T;
}

test("plugin package is Skill-only and versioned with the npm package", () => {
const packageJson = readJson<PackageManifest>("package.json");
const portableManifest = readJson<PluginManifest>("plugin.json");
const codexManifest = readJson<PluginManifest>(".codex-plugin/plugin.json");

assert.equal(portableManifest.name, "mcp-google-map");
assert.equal(codexManifest.name, portableManifest.name);
assert.equal(portableManifest.version, packageJson.version);
assert.equal(codexManifest.version, packageJson.version);
assert.equal(codexManifest.skills, "./skills/");
assert.equal("mcpServers" in portableManifest, false);
assert.equal("mcpServers" in codexManifest, false);
assert.ok(packageJson.files.includes("plugin.json"));
assert.ok(packageJson.files.includes(".codex-plugin"));
});

test("CabLate marketplace installs the published npm plugin", () => {
const marketplace = readJson<Marketplace>(".agents/plugins/marketplace.json");
const [plugin] = marketplace.plugins;

assert.equal(marketplace.name, "cablate");
assert.equal(plugin.name, "mcp-google-map");
assert.deepEqual(plugin.source, {
source: "npm",
package: "@cablate/mcp-google-map",
version: "latest",
registry: "https://registry.npmjs.org",
});
assert.equal(plugin.policy.installation, "AVAILABLE");
assert.equal(plugin.policy.authentication, "ON_INSTALL");
});
Loading