# Verge MCP Server
**Model Context Protocol (MCP) server for VergeCMS** - ChatGPT/ClaudeなどのAIアシスタントから直接ブログを管理
[](https://github.com/tomohirof/verge-mcp-server)
[](https://www.typescriptlang.org/)
[](LICENSE)
## 📋 概要
Verge MCP Serverは、[VergeCMS](https://github.com/tomohirof/verge-cms)をModel Context Protocol (MCP)サーバーとして実装したものです。Claude DesktopやChatGPTなどのAIアシスタントから、ブログの作成・管理、記事の作成・編集・公開を自然言語で行うことができます。
### なぜこれが重要か?
- **AIアシスタントから直接CMS操作**: 自然言語でブログや記事を管理
- **14の強力なツール**: 認証、ブログ管理、記事管理の完全なCRUD操作
- **3ステップ自動認証**: ブラウザ起動→ユーザー承認→トークン永続化
- **型安全なAPI**: TypeScript + Zodによる完全な型チェックとバリデーション
- **TDD開発**: 155のテストによる品質保証
## ✨ 主な機能
### ツール構成(14ツール)
#### 認証ツール(3個)
- `verge_login` - ブラウザ自動起動による認証フロー
- `verge_get_current_user` - 現在のユーザー情報取得
- `verge_update_user` - ユーザー情報更新
#### ブログ管理ツール(5個)
- `verge_list_blogs` - ブログ一覧取得
- `verge_get_blog` - ブログ詳細取得
- `verge_create_blog` - ブログ作成
- `verge_update_blog` - ブログ更新
- `verge_delete_blog` - ブログ削除
#### 記事管理ツール(6個)
- `verge_list_articles` - 記事一覧取得(検索・フィルタリング可能)
- `verge_get_article` - 記事詳細取得
- `verge_create_article` - 記事作成
- `verge_update_article` - 記事更新
- `verge_publish_article` - 記事公開
- `verge_delete_article` - 記事削除
### その他の特徴
- **自動認証フロー**: ブラウザが自動起動し、認証後トークンを安全に保存
- **Zodバリデーション**: すべてのAPI入出力を型安全に検証
- **エラーハンドリング**: 詳細なエラー情報とリトライ機能
- **エクスポネンシャルバックオフ**: ネットワークエラー時の賢いリトライ戦略
## 🚀 クイックスタート
### 前提条件
- **Node.js** >= 18.0.0
- **VergeCMS アカウント** ([tomohirof/verge-cms](https://github.com/tomohirof/verge-cms))
- **MCPクライアント** (Claude Desktop、ChatGPTなど)
### インストール
```bash
# リポジトリのクローン
git clone https://github.com/tomohirof/verge-mcp-server.git
cd verge-mcp-server
# 依存関係のインストール
npm install
# ビルド
npm run build
```
### 環境変数の設定
`.env.example`をコピーして`.env`を作成:
```bash
cp .env.example .env
```
`.env`ファイルを編集:
```bash
# Plume API URL
VERGE_API_URL=https://api.vergecms.io
# 認証情報(オプション: ブラウザ認証を使う場合は不要)
VERGE_EMAIL=your-email@example.com
VERGE_PASSWORD=your-password
```
> **注意**: 環境変数に認証情報を設定しなくても、初回実行時にブラウザ認証フローが自動的に開始されます。
### MCPクライアントでの設定
#### Claude Desktopの場合
`~/Library/Application Support/Claude/claude_desktop_config.json`に追加:
```json
{
"mcpServers": {
"plume": {
"command": "node",
"args": ["/absolute/path/to/verge-mcp-server/dist/index.js"],
"env": {
"VERGE_API_URL": "https://api.vergecms.io"
}
}
}
}
```
Claude Desktopを再起動後、以下のようにプロンプトで利用できます:
```
あなた: "ブログを作成してください。名前は『Tech Blog』です"
→ verge_create_blogツールが実行され、ブログが作成されます
あなた: "先ほど作成したブログに新しい記事を書いてください"
→ verge_create_articleツールが実行され、記事が作成されます
あなた: "記事を公開してください"
→ verge_publish_articleツールが実行され、記事が公開されます
```
## 🔐 3ステップ認証フロー
このMCPサーバーは、安全で使いやすい3ステップ認証フローを提供します:
```
1. ブラウザ自動起動
↓
MCPサーバーが認証用URLでブラウザを自動的に開きます
2. ユーザー承認
↓
ブラウザでVergeCMSにログインし、MCPサーバーへのアクセスを承認
3. トークン永続化
↓
認証トークンが安全にローカルに保存され、次回以降自動的に使用されます
```
### 認証の使い方
#### 方法1: ブラウザ認証(推奨)
```typescript
// Claude Desktopで以下のように実行
"VergeCMSにログインしてください"
// 自動的にブラウザが起動し、認証フローが開始されます
// 一度認証すれば、トークンが保存され、次回以降は自動ログイン
```
#### 方法2: 環境変数認証
`.env`ファイルに認証情報を設定:
```bash
VERGE_EMAIL=your-email@example.com
VERGE_PASSWORD=your-password
```
## 📚 ツールリファレンス
### 認証ツール
#### `verge_login`
VergeCMSにログインし、JWTトークンを取得します。
**入力パラメータ:**
```typescript
{
email?: string; // メールアドレス(オプション: 省略時はブラウザ認証)
password?: string; // パスワード(オプション)
}
```
**レスポンス例:**
```typescript
{
success: true,
token: "eyJhbGc...",
user: {
id: 1,
email: "user@example.com",
name: "John Doe"
}
}
```
#### `verge_get_current_user`
現在ログイン中のユーザー情報を取得します。
**入力パラメータ:** なし
**レスポンス例:**
```typescript
{
id: 1,
email: "user@example.com",
name: "John Doe",
created_at: "2024-01-01T00:00:00Z"
}
```
#### `verge_update_user`
ユーザー情報を更新します。
**入力パラメータ:**
```typescript
{
user_id: number; // ユーザーID
name?: string; // 新しい名前
email?: string; // 新しいメールアドレス
password?: string; // 新しいパスワード
}
```
### ブログ管理ツール
#### `verge_list_blogs`
すべてのブログを一覧表示します。
**入力パラメータ:** なし
**レスポンス例:**
```typescript
[
{
id: 1,
name: "Tech Blog",
title: "技術ブログ",
slug: "tech-blog",
description: "技術記事を書くブログ"
}
]
```
#### `verge_get_blog`
特定のブログの詳細情報を取得します。
**入力パラメータ:**
```typescript
{
blog_id: number; // ブログID
}
```
#### `verge_create_blog`
新しいブログを作成します。
**入力パラメータ:**
```typescript
{
name: string; // ブログ名(必須)
title: string; // タイトル(必須)
slug: string; // URLスラッグ(必須)
description?: string; // 説明(オプション)
}
```
**使用例:**
```typescript
// Claude Desktopでの使用例
"新しいブログを作成してください。
名前: 'My Tech Blog'
タイトル: '技術ブログ'
スラッグ: 'tech-blog'
説明: '最新の技術トレンドを発信するブログ'"
```
#### `verge_update_blog`
既存のブログを更新します。
**入力パラメータ:**
```typescript
{
blog_id: number; // ブログID(必須)
name?: string; // 新しい名前
title?: string; // 新しいタイトル
slug?: string; // 新しいスラッグ
description?: string; // 新しい説明
}
```
#### `verge_delete_blog`
ブログを削除します。
**入力パラメータ:**
```typescript
{
blog_id: number; // ブログID
}
```
### 記事管理ツール
#### `verge_list_articles`
記事一覧を取得します(検索・フィルタリング可能)。
**入力パラメータ:**
```typescript
{
blog_id: number; // ブログID(必須)
search?: string; // 検索キーワード
status?: 'draft' | 'published'; // ステータスフィルタ
category_ids?: number[]; // カテゴリIDでフィルタ
tag_ids?: number[]; // タグIDでフィルタ
}
```
**使用例:**
```typescript
// 公開済み記事のみを取得
{
blog_id: 1,
status: 'published'
}
// キーワード検索
{
blog_id: 1,
search: 'TypeScript'
}
```
#### `verge_get_article`
記事の詳細情報を取得します。
**入力パラメータ:**
```typescript
{
article_id: number; // 記事ID
blog_id: number; // ブログID
}
```
#### `verge_create_article`
新しい記事を作成します。
**入力パラメータ:**
```typescript
{
blog_id: number; // ブログID(必須)
title: string; // タイトル(必須)
content: string; // 本文(必須、Markdown)
slug: string; // URLスラッグ(必須)
status?: 'draft' | 'published'; // ステータス(デフォルト: draft)
featured_image?: string; // アイキャッチ画像URL
excerpt?: string; // 抜粋
author_id?: number; // 著者ID
category_ids?: number[]; // カテゴリID配列
tag_ids?: number[]; // タグID配列
}
```
**使用例:**
```typescript
// Claude Desktopでの使用例
"新しい記事を作成してください。
ブログID: 1
タイトル: 'TypeScriptでMCPサーバーを作る'
スラッグ: 'typescript-mcp-server'
内容: '# はじめに\n\nこの記事では...'"
```
#### `verge_update_article`
既存の記事を更新します。
**入力パラメータ:**
```typescript
{
article_id: number; // 記事ID(必須)
blog_id: number; // ブログID(必須)
title?: string; // 新しいタイトル
content?: string; // 新しい本文
slug?: string; // 新しいスラッグ
status?: 'draft' | 'published'; // 新しいステータス
featured_image?: string; // 新しいアイキャッチ画像
excerpt?: string; // 新しい抜粋
author_id?: number; // 新しい著者ID
category_ids?: number[]; // 新しいカテゴリID配列
tag_ids?: number[]; // 新しいタグID配列
}
```
#### `verge_publish_article`
記事を公開状態に変更します。
**入力パラメータ:**
```typescript
{
article_id: number; // 記事ID
blog_id: number; // ブログID
}
```
#### `verge_delete_article`
記事を削除します。
**入力パラメータ:**
```typescript
{
article_id: number; // 記事ID
blog_id: number; // ブログID
}
```
## 🧪 開発ワークフロー
### TDD方針
このプロジェクトはTest-Driven Development (TDD) で開発されています:
1. **Zodスキーマのユニットテスト優先**: 入出力フォーマットを確定
2. **APIクライアント層**: fetchモックでリクエスト生成・レスポンス処理をテスト
3. **MCPツール層**: APIクライアントモックでハンドラーをテスト
4. **統合テスト**: 型整合性とMCPプロトコル整合性を確認
**現在のテスト状態**: 155テスト全てパス ✅
### テストの実行
```bash
# 全テスト実行
npm test
# テストUI起動
npm run test:ui
# カバレッジ測定
npm run test:coverage
```
### 開発コマンド
```bash
# TypeScriptを直接実行(開発モード)
npm run dev
# MCPインスペクター(ツールの動作を検証)
npm run inspector
# ビルド
npm run build
# 型チェック
npx tsc --noEmit
# Lint
npm run lint
```
## 📂 プロジェクト構造
```
verge-mcp-server/
├── src/
│ ├── index.ts # MCPサーバーエントリーポイント
│ ├── server.ts # MCPサーバーコア実装
│ ├── config.ts # 環境変数管理
│ ├── auth/
│ │ ├── index.ts # 認証フロー統合
│ │ ├── browser-auth.ts # ブラウザ認証フロー
│ │ └── token-storage.ts # トークン永続化
│ ├── client/
│ │ ├── types.ts # Zodスキーマ・型定義
│ │ ├── errors.ts # カスタムエラークラス
│ │ └── api.ts # Plume APIクライアント
│ └── tools/
│ ├── schemas.ts # MCPツール入力スキーマ
│ ├── auth.ts # 認証ツールハンドラー
│ ├── blogs.ts # ブログ管理ツールハンドラー
│ └── articles.ts # 記事管理ツールハンドラー
├── tests/
│ ├── client/
│ │ ├── types.test.ts # Zodスキーマテスト(43テスト)
│ │ ├── api.test.ts # APIクライアントテスト(21テスト)
│ │ ├── api-retry.test.ts # リトライ機能テスト(11テスト)
│ │ ├── api-backoff.test.ts # バックオフテスト(7テスト)
│ │ ├── api-timeout.test.ts # タイムアウトテスト(5テスト)
│ │ └── errors.test.ts # エラーハンドリングテスト(11テスト)
│ ├── tools/
│ │ ├── auth.test.ts # 認証ツールテスト(6テスト)
│ │ ├── blogs.test.ts # ブログ管理ツールテスト(10テスト)
│ │ └── articles.test.ts # 記事管理ツールテスト(8テスト)
│ └── integration/
│ ├── server.e2e.test.ts # E2Eテスト(6テスト)
│ ├── error-handling.test.ts # エラーハンドリング統合テスト(8テスト)
│ └── articles.scenario.test.ts # 記事管理シナリオテスト(3テスト)
├── dist/ # ビルド出力
├── package.json
├── tsconfig.json
├── vitest.config.ts
└── README.md
```
## 🔧 トラブルシューティング
### よくある質問(FAQ)
#### Q: 認証に失敗します
A: 以下を確認してください:
- VergeCMSのアカウントが有効か
- `VERGE_API_URL`が正しいか
- ブラウザ認証の場合、ブラウザが正常に起動するか
- 環境変数認証の場合、メールアドレスとパスワードが正しいか
#### Q: "Token expired" エラーが表示されます
A: トークンの有効期限が切れています。以下のコマンドで再認証してください:
```bash
# トークンファイルを削除
rm ~/.verge-mcp-token.json
# Claude Desktopを再起動し、再度ログインを実行
```
#### Q: MCPツールが認識されません
A: Claude Desktopの設定を確認してください:
1. `claude_desktop_config.json`のパスが正しいか
2. `dist/index.js`のパスが絶対パスになっているか
3. Claude Desktopを再起動したか
#### Q: ビルドエラーが発生します
A: 以下を試してください:
```bash
# node_modulesを削除して再インストール
rm -rf node_modules
npm install
# ビルド
npm run build
```
### セキュリティに関する注意事項
- **トークン保存**: 認証トークンは`~/.verge-mcp-token.json`に保存されます
- **環境変数**: 本番環境では環境変数に認証情報を設定しないでください
- **ブラウザ認証推奨**: セキュリティの観点から、ブラウザ認証フローの使用を推奨します
## 🔗 関連リンク
- [VergeCMS リポジトリ](https://github.com/tomohirof/verge-cms)
- [Model Context Protocol 公式ドキュメント](https://modelcontextprotocol.io/)
- [TypeScript MCP SDK](https://github.com/modelcontextprotocol/typescript-sdk)
- [Zod - TypeScript-first schema validation](https://zod.dev/)
- [親Issue #65](https://github.com/tomohirof/verge-cms/issues/65)
## 📝 ライセンス
MIT License - 詳細は[LICENSE](LICENSE)を参照してください。
## 👤 作者
**Tomohiro Fukuda**
- GitHub: [@tomohirof](https://github.com/tomohirof)
## 🙏 謝辞
- [Anthropic](https://www.anthropic.com/) - Model Context Protocolの開発
- [VergeCMS](https://github.com/tomohirof/verge-cms) - ブログプラットフォーム
- [Zod](https://zod.dev/) - TypeScript-first schema validation
- すべてのコントリビューターとユーザーの皆様