概要
Model Context Protocol(MCP)は、AI エージェントが外部ツール・データソースと安全に連携するための標準プロトコルです。2026 年 2 月、国土交通省が地理空間情報の MCP サーバーを公開し、官公庁データと AI の連携が現実のものとなりました。
MCP(Model Context Protocol)とは
基本アーキテクチャ
┌─────────────────┐ ┌─────────────────┐
│ AI エージェント │◄──────►│ MCP クライアント │
│ (Claude Code) │ │ (ホスト側) │
└─────────────────┘ └────────┬────────┘
│
MCP プロトコル
│
▼
┌─────────────────┐
│ MCP サーバー │
│ (国土地理院) │
└─────────────────┘
│
▼
┌─────────────────┐
│ 地理空間情報 │
│ (基盤地図など) │
└─────────────────┘
3 つの基本機能
| 機能 | 説明 | 例 |
|---|
| Prompts | 事前定義されたプロンプトテンプレート | 「この住所の緯度経度を取得」 |
| Resources | 読み取り専用データソース | 地図タイル、住所データ |
| Tools | 実行可能な操作 | 住所検索、経路計算、エリア分析 |
国土交通省地理空間 MCP サーバー
提供データ
| データ種別 | 内容 | 出典 |
|---|
| 基盤地図情報 | 道路、建物、河川、行政区画 | 国土地理院 |
| 住所検索 | 全国住所・緯度経度変換 | 住居表示データベース |
| 標高データ | 5m メッシュ標高 | 数値標高モデル |
| 土地利用 | 土地利用メッシュ | 国土数値情報 |
| 災害リスク | 浸水想定区域、土砂災害警戒区域 | 各自治体 |
| 交通網 | 鉄道、バス路線、道路 | 国土数値情報 |
インストール
# npm でインストール
npx -y @mlit/geospatial-mcp-server
# または globaにインストール
npm install -g @mlit/geospatial-mcp-server
Claude Code での設定
// .mcp.json
{
"mcpServers": {
"mlit-geospatial": {
"command": "npx",
"args": ["-y", "@mlit/geospatial-mcp-server"],
"env": {
"MLIT_API_KEY": "your-api-key"
}
}
}
}
API キー取得
- 国土交通省地理空間情報 API ポータル にアクセス
- ユーザー登録(無料)
- API キーを発行
- 利用規約に同意
使用例
1. 住所から緯度経度取得
ユーザー: 東京都千代田区永田町 1-1-1 の緯度経度を教えて
MCP: geospatial/geocode 実行
入力: {"address": "東京都千代田区永田町 1-1-1"}
出力: {"lat": 35.6794, "lon": 139.7416}
回答: 東京都千代田区永田町 1-1-1 の緯度経度は
北緯 35.6794 度、東経 139.7416 度です。
2. エリア内の施設検索
ユーザー: 東京駅周辺 500m 以内のコンビニを検索して
MCP: geospatial/search_pois 実行
入力: {
"lat": 35.6812,
"lon": 139.7671,
"radius": 500,
"category": "convenience_store"
}
出力: [
{"name": "セブンイレブン", "distance": 120},
{"name": "ローソン", "distance": 230},
{"name": "ファミリーマート", "distance": 380}
]
3. 災害リスク評価
ユーザー: 大阪市北区梅田 1-1-1 の災害リスクを評価して
MCP: geospatial/disaster_risk 実行
入力: {"address": "大阪市北区梅田 1-1-1"}
出力: {
"flood_risk": "low",
"landslide_risk": "none",
"earthquake_risk": "medium",
"tsunami_risk": "none"
}
4. 経路探索と標高プロファイル
ユーザー: 富士山五合目から山頂までの経路と標高変化を教えて
MCP: geospatial/route_profile 実行
入力: {
"start": {"lat": 35.3606, "lon": 138.7274},
"end": {"lat": 35.3628, "lon": 138.7304}
}
出力: {
"distance": 3.2km,
"elevation_gain": 700m,
"profile": [...]
}
開発者向け:自作 MCP サーバーの作成
基本構造
// server.ts
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
const server = new Server({
name: 'my-mcp-server',
version: '1.0.0',
}, {
capabilities: {
prompts: {},
resources: {},
tools: {},
},
});
// ツール定義
server.setRequestHandler('tools/call', async (request) => {
const { name, arguments: args } = request.params;
if (name === 'my_tool') {
return {
content: [{ type: 'text', text: '結果' }],
};
}
throw new Error(`Unknown tool: ${name}`);
});
const transport = new StdioServerTransport();
await server.connect(transport);
公開手順
- GitHub リポジトリ作成
- npm パッケージとして公開
- MCP サーバーレジストリに登録
MCP サーバーエコシステム(2026 年 3 月)
官公庁系
| サーバー | 提供元 | 機能 |
|---|
| @mlit/geospatial-mcp-server | 国土交通省 | 地理空間情報 |
| @e-stat/stats-mcp-server | 総務省統計局 | 国勢調査、経済統計 |
| @meteojapan/weather-mcp-server | 気象庁 | 気象データ、警報 |
| @corporate-number/houjin-mcp-server | 国税庁 | 法人番号検索 |
企業系
| サーバー | 提供元 | 機能 |
|---|
| @google/maps-mcp-server | Google | 地図・経路検索 |
| @stripe/payments-mcp-server | Stripe | 決済処理 |
| @slack/mcp-server | Slack | チーム連携 |
| @github/mcp-server | GitHub | リポジトリ操作 |
オープンソース系
| サーバー | 機能 |
|---|
| @mcp/filesystem | ローカルファイル操作 |
| @mcp/postgres | PostgreSQL データベース |
| @mcp/redis | Redis 操作 |
| @mcp/fetch | Web コンテンツ取得 |
| @mcp/time | 日時・カレンダー |
実装パターン
パターン 1: データ取得のみ(Resources)
// 読み取り専用データソース
server.setRequestHandler('resources/read', async (request) => {
const { uri } = request.params;
if (uri.startsWith('stats://')) {
const data = await fetchStatistics(uri);
return {
contents: [{
uri,
mimeType: 'application/json',
text: JSON.stringify(data),
}],
};
}
});
パターン 2: 対話型プロンプト(Prompts)
// プロンプトテンプレート
server.setRequestHandler('prompts/get', async (request) => {
const { name, arguments: args } = request.params;
if (name === 'analyze_data') {
return {
messages: [{
role: 'user',
content: {
type: 'text',
text: `以下のデータを分析してください:\n\n${args.data}`,
},
}],
};
}
});
// 実行ツール
server.setRequestHandler('tools/call', async (request) => {
const { name, arguments: args } = request.params;
if (name === 'send_email') {
await sendEmail(args.to, args.subject, args.body);
return {
content: [{ type: 'text', text: 'メールを送信しました' }],
};
}
});
セキュリティ考慮事項
認証・認可
// API キー認証
const apiKey = process.env.API_KEY;
server.setRequestHandler('tools/call', async (request) => {
if (!apiKey) {
throw new Error('API key required');
}
// ツール実行
});
レートリミット
// 簡易レートリミット
const rateLimiter = new Map<string, number[]>();
function checkRateLimit(clientId: string, limit: number, window: number): boolean {
const now = Date.now();
const calls = rateLimiter.get(clientId) || [];
const recentCalls = calls.filter(t => now - t < window);
if (recentCalls.length >= limit) {
return false;
}
recentCalls.push(now);
rateLimiter.set(clientId, recentCalls);
return true;
}
データバリデーション
// 入力バリデーション
function validateGeocodeRequest(input: unknown): { address: string } {
if (typeof input !== 'object' || input === null) {
throw new Error('Invalid input');
}
const { address } = input as Record<string, unknown>;
if (typeof address !== 'string' || address.length === 0) {
throw new Error('Address is required');
}
return { address };
}
今後の展開
2026 年予想
- 省庁横断 MCP: 複数省庁データ連携
- 地方自治体 MCP: 都道府県・市区町村データ
- 民間連携 MCP: 企業データとの安全な連携
- MCP オーケストレーション: 複数サーバー協調
- MCP マーケットプレイス: サーバー共有プラットフォーム
標準化動向
- MCP Specification 2.0: 2026 年 Q2 予定
- ISO 標準化: 2027 年目指し検討中
- 相互運用性テスト: 公式認証プログラム
参考リンク