Skip to main content
Glama
README.md
# Verge MCP Server

**Model Context Protocol (MCP) server for VergeCMS** - ChatGPT/ClaudeなどのAIアシスタントから直接ブログを管理

[![Tests](https://img.shields.io/badge/tests-155%20passed-brightgreen)](https://github.com/tomohirof/verge-mcp-server)
[![TypeScript](https://img.shields.io/badge/TypeScript-5.3+-blue)](https://www.typescriptlang.org/)
[![License](https://img.shields.io/badge/license-MIT-blue.svg)](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
- すべてのコントリビューターとユーザーの皆様