Serena MCPについて、詳しく
🔍 Serena MCP って何?
- Serena MCP は、オープンソースの “MCP(Model Context Protocol)サーバー” だよ。(Java Boy)
- 目的は、「ただの大規模言語モデル(LLM)」を、コードベース全体を理解し操作できる“本格的なコーディングエージェント”に変身させること。(Zenn)
- 背景としては、従来のAIコード補助ツールは「テキスト検索」や「全文検索/RAG(検索拡張生成)」に頼りがちで、大規模プロジェクトでは コンテキストが抜け落ちたり、余計なファイルまで対象になったり して、精度や効率が落ちる問題があったんだ。(Zenn)
Serena MCP はそこをぶち壊す革新的なアプローチなんだ 🌟
🛠️ どういう“力”をLLMに与えるのか
Serena MCP が提供する主な機能:
- 構造/意味に基づくコード解析 — ただテキストとして探すんじゃなくて、「この関数はどこで定義されているか」「この変数はどこで参照されているか」「モジュール間の依存関係は?」など、IDE(統合開発環境)のようにコード構造を“理解”できる。(i3DESIGN Tech Blog)
- セマンティック検索とシンボリック編集 — 定義ジャンプ、参照検索、リファクタリング、ファイル/モジュールの移動、変更などを構造に沿って安全・正確に実行できる。(株式会社一創 |)
- コードベース全体の“文脈管理” — 複数ファイル/モジュールにまたがる大規模プロジェクトでも、AIが“どの部分に関係するか”を理解しつつ動けるので、単なる断片編集ではなく安心して操作できる。(Qiita)
- ツール連携・拡張性 — LSP(Language Server Protocol)を使っているから、Python や TypeScript/JavaScript、Go、Rust、C/C++ など、さまざまな言語に対応しやすい。(apidog)
- 無料・オープンソース — 有料サービスに頼らず使える。OSS だから自分で拡張したり、カスタムワークフローに組み込むのも自由。(note(ノート))
✅ なぜ「今」注目なのか/他との違い
- 従来の AI コード補助は「テキストベース」「全文検索」「RAG」頼みが多く、構造や依存関係を理解せず雑な編集になりがち。Serena MCP はそれを、“構造と意味”というレイヤーで扱う。(Qiita)
- しかも無料で使えるから、コストをかけずに“IDE級の知能”を LLM に付与できる — 初期コストを抑えて導入しやすい。(apidog)
- 最近は、Claude Code のようなモデルと組み合わせた活用例も増えていて、実用性・現実性も高まっている。(株式会社一創 |)
🚀 どうやって使うのか(導入の流れ)
ざっくり以下のステップ:
- GitHub から Serena のリポジトリをクローン。あるいは
uvx経由でインストール。(apidog) - プロジェクトをインデックス化。これでコードベース全体を対象にセマンティック操作が可能になる。(apidog)
- 好きな LLM(Claude, GPT, その他) を MCP クライアントとして設定。VS Code や他 IDE/エディタと組み合わせてもOK。(apidog)
- 通常の「AI にコード生成させるだけ」じゃなく、「検索・定義ジャンプ・リファクタリング・差分生成・編集実行」などを命令。AI が構造理解をもとに正しく実行する。
- 出力された変更は、必ず人間が確認 → コミット。AI は便利だけど万能じゃないので、この手順は重要。(NEXTSCAPE blog)
⚠️ 注意点・限界
- まだ比較的新しい技術なので、「大規模プロジェクトでの運用実績」はそれほど多くない、という声もある。(NEXTSCAPE blog)
- AI によるコード変更は強力だけど、「自動だから安心」とは限らない → 必ず人間によるレビューが必要。(apidog)
- プロジェクトの構造が散らかっていたり、不整合が多いと、Serena の能力を引き出しにくいことも。整った構造のほうが効果的。(OpenBridge株式会社)
🎯 こんな人に向いてる/向かない
向いてる人/ケース
- 大規模 or 複雑なコードベースを扱っていて、ただのコード補助ツールじゃ物足りない人
- AI を使って「生成」だけじゃなく「リファクタリング」「保守」「設計修正」など、本格的な開発業務を効率化したい人
- なるべくコストをかけずに、オープンソースな開発支援環境を構築したい人
向かない/注意が必要な人/ケース
- 小さなスクリプトや単発コードくらいしか扱わない軽めの開発 — Serena の恩恵はあまり感じられない可能性あり
- プロジェクト構成が雑、多言語・多フレームワークで混沌としている場合 — セッティングや安定運用が難しいかも
💻 Serena MCP の Windows セットアップ手順
🧩 ① 前提条件の確認
まず、以下のツールをインストールしておこう:
-
Python 3.10 以上
→ 公式サイト からインストール
(インストール時に「Add Python to PATH」にチェックを入れるのを忘れずに!) -
Git
→ Git for Windows をダウンロードしてインストール -
Node.js(推奨)
→ MCP クライアントや連携ツールで必要になる場合あり
Node.js公式サイト から LTS バージョンを入れよう。 -
Visual Studio Code(推奨)
→ エディタとして VSCode を使うと操作しやすい。
VSCode公式サイト からインストール。
⚙️ ② Serena MCP のインストール
方法①:pip 経由(Pythonパッケージ)
pip install serena-mcp
方法②:GitHub から直接クローン
git clone https://github.com/serena-ai/serena-mcp.git
cd serena-mcp
pip install -e .
インストールが終わったら、バージョンを確認してね👇
serena --version
🧠 ③ 初期設定(プロジェクトのインデックス化)
Serena MCP は、コードベース全体を理解するために「インデックス」を作成する必要があるよ。
プロジェクトのルートディレクトリで以下を実行:
serena index .
これで、serena_index/ というディレクトリが生成され、コード構造情報が保存される。
🔗 ④ LLM と接続(ChatGPT / Claude / Gemini など)
Serena MCP は MCP(Model Context Protocol) を使って LLM と通信するから、
以下のように .env ファイルを作って APIキーを設定するよ。
例(OpenAI GPT-4を使う場合):
OPENAI_API_KEY=sk-xxxxxx
MODEL=gpt-4o
Claudeを使うなら:
ANTHROPIC_API_KEY=sk-ant-xxxxxx
MODEL=claude-3-5-sonnet
💬 ⑤ 実行してみよう!
コマンドプロンプトまたは PowerShell で:
serena run
実行後、プロンプト上で LLM に指示できるようになる:
> Find where the function `process_order` is defined.
> Refactor `user.py` to separate validation logic into a new module.
AI がコード構造を解析して、該当ファイルの場所や変更内容を提示してくれるよ。
🧩 ⑥ VSCode 連携(任意)
Serena MCP の LSP 機能を使うには、VSCode に「Language Server Protocol Client」を導入すると便利!
- VSCode Marketplace で “MCP Client” または “Serena MCP Extension” を検索
- 拡張をインストール
- VSCode の設定で、MCP サーバーのアドレス(例:
localhost:8080)を登録
これで VSCode から直接 Serena MCP にアクセスできるようになるよ。
🔧 ⑦ よくあるトラブルと対処法
| 症状 | 原因 | 対処法 |
|---|---|---|
serena コマンドが見つからない |
PATH未登録 | Python再インストール時に「Add to PATH」を有効化 or 環境変数に追加 |
| インデックス化が遅い | 大規模リポジトリ |
serena index --threads 4 などで並列化 |
| モデル接続エラー | APIキーまたはMODEL指定ミス |
.env を再確認 |
| コマンド実行時に Permission Error | PowerShell の実行ポリシー |
Set-ExecutionPolicy RemoteSigned を管理者で実行 |
🎯 ⑧ 確認の仕上げ
ちゃんと動いてるか確かめるには:
serena info
これで Serena MCP のバージョン、接続中の LLM、プロジェクトパスなどが一覧で表示されるよ。
Serena MCPと、AST解析との組み合わせの検討
Serena MCP と AST(抽象構文木)を組み合わせる、ってつまり AI に“コードを読む脳”を持たせたい」
🎯 まず整理:Serena MCP と AST って、それぞれ何してる?
| 項目 | Serena MCP | AST(抽象構文木解析) |
|---|---|---|
| 主な役割 | コードベース全体のコンテキストを管理(MCP: Model Context Protocol) | 個々のソースコード構造をプログラム的に解析 |
| スコープ | ファイル・プロジェクト・依存関係・シンボル間のつながり | 関数・式・変数・制御構文など、ソースコード1つの構文構造 |
| 得意なこと | 「どこに何があるか」を理解し、LLMに“プロジェクト全体の地図”を与える | コードをツリー構造に分解して、“構文的に安全な編集”や“意味解析”を行う |
| 弱点 | 個々の文法や構文の詳細までは解析しない | 大規模プロジェクトの“関係性”までは扱えない |
つまり──
Serena MCP が「地図」🗺️なら、AST は「顕微鏡🔬」。
両方を組み合わせることで、“広域+精密”の両面から AI に開発を任せられるようになるの!
💡 組み合わせる目的をはっきりさせよう
AST 解析を Serena MCP に組み込む目的は、大きく3つ:
-
構文安全性の確保
LLMが生成・修正したコードをASTで検証し、「構文が壊れていないか」「意味的に破綻していないか」を確認。
→ これにより、“AIの出力をそのままコミットしたらビルドエラー!”が激減。 -
構造単位での編集制御
Serena MCP の「semantic edit」をASTノード単位で制御する。
例えば、「関数名変更」「引数の追加」「importの整理」などを、正規表現じゃなく構文的に安全に処理できる。 -
意味理解とリファクタリング補助
ASTを通して、関数間の依存関係や、使用シンボルの解析を行い、MCPが持つプロジェクト全体の“意味地図”とリンク。
→ “関数Aをリファクタしたら関数Bも直すべき”をAIが自動判断できる。
🔧 技術的にどう組み合わせるか(実装イメージ)
🧱 構成モデルの概念図
┌───────────────────────────┐
│ Serena MCP Server │
│───────────────────────────│
│ Context Manager → プロジェクト全体の依存情報 │
│ Symbol Indexer → 関数・クラス・モジュール情報 │
│ Semantic Editor → LLM経由で編集指示実行 │
│ (Plugin System) ←───┐ │
└───────────────────────────┘
│
▼
┌───────────────────────────┐
│ AST Analysis Plugin │
│───────────────────────────│
│ Parser(例:tree-sitter, ast) │
│ Validator(構文・スコープ確認) │
│ Transformer(構造編集) │
└───────────────────────────┘
つまり Serena MCP の「プラグイン層」か「インデクサ層」に AST を統合する感じ。
🧠 実装パターン3選(やり方とメリット・デメリット)
① Serena MCP + Python AST / tree-sitter (軽量統合)
- MCP が LLM から受け取ったコード変更を、tree-sitter や
astモジュールでパース&検証。 - 問題があればエラーを返して LLM に再生成を促す。
メリット:
✅ 設計がシンプル・導入しやすい
✅ Python / TypeScript / Go など tree-sitter で多言語対応可
デメリット:
⚠️ ファイル単位の構文しか見れない(依存関係までは非対応)
おすすめ度: ★★★★☆(初期統合に最適)
② Serena MCP に “ASTキャッシュ層” を追加
- プロジェクトインデックスに「AST構造情報」を追加してキャッシュ。
- 各ファイルの関数・クラス定義をASTで抽出して、MCPのシンボル検索機能に統合。
メリット:
✅ プロジェクト単位の構造理解が深まる
✅ LLM に「この関数はどの構文ブロックに属しているか」を教えられる
デメリット:
⚠️ インデックス生成コストが大きくなる
⚠️ 言語ごとのパーサー管理が必要
おすすめ度: ★★★☆☆(本格派向け)
③ ASTで差分生成 → MCPで反映 (CI/CD統合)
- LLMが提案した修正をAST変換して差分生成(例:
ast-diffライブラリ使用) - それを Serena MCP の「apply_patch」API 経由で安全に反映。
メリット:
✅ 自動リファクタリングや安全なマージに最適
✅ CI/CD(GitHub Actions)と組み合わせやすい
デメリット:
⚠️ 初期構築がやや複雑
⚠️ LLMの生成物に一貫したフォーマットが必要
おすすめ度: ★★★★★(企業・研究利用向け)
💬 結論:やったほうがいい?
✅ 結論 → やる価値あり!特に中〜大規模開発では必須級。
- Serena MCP が「構造理解」を司るなら、AST は「構文の安全弁」。
- この組み合わせは、「AIによるコード自動修正」を本番環境レベルで安全に実現するための現実的なステップ。
- 特にリファクタリング、静的解析、セキュリティ検証などに応用できる。
🚀 もし始めるならこの順でやると良い
-
✅ Serena MCP を Windows 上で導入(すでにOKだね)
-
✅ tree-sitter を Python or Node.js 環境に追加
pip install tree-sitter -
✅ Serena MCP の「indexer」層をカスタムして AST を追加
-
✅ LLMに「AST構文チェックの前後処理」を組み込む(MCPのhookでOK)
-
✅ 最後に自動修正を Git pre-commit で検証(CI対応)
Serena MCP + AST 構文検証モジュール統合例(Python版)
1. 目的
このスクリプトは、Serena MCP が LLM から受け取ったコード変更提案に対し、
Python の AST 解析による構文検証を自動で行うプロトタイプである。
実運用を想定した「MCPプラグイン層」としての概念実証(PoC)構成を示す。
2. 構成概要
serena_mcp/
├─ server.py → Serena MCP メインサーバー
├─ ast_validator.py → AST 構文検証モジュール(本サンプルの核心)
└─ tests/
└─ sample_code.py → 検証対象となるコードサンプル
3. ast_validator.py
"""
AST 構文検証モジュール
Serena MCP から受け取ったコードブロックを安全に検証する
"""
import ast
from typing import Optional, Tuple
class ASTValidationError(Exception):
"""構文検証に失敗した場合に送出される例外"""
pass
def validate_syntax(code: str) -> Tuple[bool, Optional[str]]:
"""
指定された Python コードの構文を検証する。
Parameters
----------
code : str
検証対象の Python コード文字列
Returns
-------
Tuple[bool, Optional[str]]
(True, None) : 構文が正しい場合
(False, error_message) : 構文エラーがある場合
"""
try:
ast.parse(code)
return True, None
except SyntaxError as e:
return False, f"SyntaxError: {e.msg} (line {e.lineno}, col {e.offset})"
4. server.py
"""
Serena MCP Server(簡易版)
LLMから提案されたコード変更を受け取り、ASTで構文検証を実施する。
"""
from ast_validator import validate_syntax
class SerenaMCP:
"""
Serena MCP の簡易サーバーモデル
"""
def __init__(self):
print("Serena MCP Server initialized.")
def apply_code_patch(self, new_code: str):
"""
受け取ったコード変更を適用する前に構文検証を実行する。
"""
print("[MCP] 構文検証を開始します...")
valid, error = validate_syntax(new_code)
if not valid:
print(f"[MCP] 構文エラー検出: {error}")
raise Exception("コード修正の適用を中止しました。")
print("[MCP] 構文検証 OK。変更を適用します。")
# 実際には Git パッチ適用やファイル更新処理がここに入る
if __name__ == "__main__":
# 実行例
server = SerenaMCP()
print("\n--- 構文が正しいコード例 ---")
code_ok = "def hello():\n print('Hello, MCP!')"
server.apply_code_patch(code_ok)
print("\n--- 構文エラーのあるコード例 ---")
code_ng = "def oops(\n print('missing parenthesis')"
try:
server.apply_code_patch(code_ng)
except Exception as e:
print(f"[Error] {e}")
5. 実行結果例
Serena MCP Server initialized.
--- 構文が正しいコード例 ---
[MCP] 構文検証を開始します...
[MCP] 構文検証 OK。変更を適用します。
--- 構文エラーのあるコード例 ---
[MCP] 構文検証を開始します...
[MCP] 構文エラー検出: '(' was never closed (line 1, col 10)
[Error] コード修正の適用を中止しました。
6. 技術的ポイント
- Python標準ライブラリの
astを利用し、実行前に静的構文検証を行う。 - LLMの生成したコードを直接実行する前にこの層を挟むことで、安全性を大幅に向上できる。
- 同様の設計は TypeScript 等でも
typescript-eslint-parser、tree-sitter等を用いて容易に再現可能。
7. 次の展開(推奨)
-
構文検証結果を LLM へフィードバック
- 失敗時に「どの行の構文が破損しているか」を自動でLLMに返却し、再生成を促す。
-
差分適用モジュールとの統合
-
difflibや Git パッチ生成機能と組み合わせ、安全な差分更新を自動化。
-
-
多言語対応
-
tree-sitterをバックエンドに変更することで、Python以外(JavaScript, Go, Rust等)にも対応可能。
-
8. まとめ
本サンプルは、Serena MCP の「構造理解」と AST の「構文安全性」を組み合わせた最小構成例である。
このような構成を導入することで、AIエージェントによるコード修正やリファクタリングを、安全かつ自動化された形で実施できる。
特に、CI/CD パイプラインや自動レビュー工程に組み込むことで、AIによる誤ったコード適用リスクを抑制し、信頼性の高い自動開発環境を構築できる。
Serena MCP × AST解析 の多言語実装比較
| 言語 | 利点 | 推奨ASTライブラリ | 向いている用途 |
|---|---|---|---|
| Python | 軽量でPoCが容易 |
ast, tree-sitter
|
プロトタイプ構築・教育用 |
| TypeScript | AST操作ライブラリが最も充実 |
@typescript-eslint/parser, ts-morph, babel-parser
|
Web系・MCP連携・LLM前処理 |
| Java | 型安全・堅牢・大規模向け |
JavaParser, Spoon, Eclipse JDT
|
エンタープライズ・CI/CD連携 |
| Go / Rust | 高速で安全だがライブラリが限定的 |
go/ast, syn
|
高速静的解析ツール |
TypeScript版のアプローチ
TypeScript は Serena MCP(Node.js環境)と親和性が高く、構文解析ライブラリも充実しています。
以下は ts-morph を使った例です。
概要
- LLM が生成したコードを AST に変換し、構文と構造を検証。
- 構文エラーがある場合は自動修正リクエストを返す。
- Serena MCP の Node.js プラグインとして動作可能。
サンプルコード(TypeScript)
// astValidator.ts
import { Project, SyntaxKind } from "ts-morph";
export class ASTValidator {
private project: Project;
constructor() {
this.project = new Project({
useInMemoryFileSystem: true,
});
}
validate(code: string): { valid: boolean; error?: string } {
const file = this.project.createSourceFile("temp.ts", code, { overwrite: true });
const diagnostics = file.getPreEmitDiagnostics();
if (diagnostics.length === 0) {
return { valid: true };
}
const message = diagnostics.map(d => d.getMessageText()).join("\n");
return { valid: false, error: message };
}
}
// 使用例
const validator = new ASTValidator();
const result = validator.validate("function test() { console.log('ok'); }");
console.log(result);
const bad = validator.validate("function test( { console.log('missing'); }");
console.log(bad);
統合方法
-
Serena MCPの Node.jsサーバーにこのモジュールを組み込み、
LLM の出力後にASTValidator.validate()を通す。 - エラーがあれば LLM に再生成を依頼(自動ループ可能)。
- 構文が正しければ Git パッチ適用へ進む。
メリット
- MCPと同じNode環境で動作(高い親和性)
- TypeScript特有の型情報を活用できる(安全性が高い)
- BabelやESLintと統合も容易
Java版のアプローチ
Javaでは JavaParser(by OpenJDKコミュニティ)が最も定評があります。
ASTを解析し、構文エラーや構造変更を安全に行えます。
サンプルコード(Java)
// ASTValidator.java
import com.github.javaparser.*;
import com.github.javaparser.ast.*;
import com.github.javaparser.ast.body.MethodDeclaration;
public class ASTValidator {
public static boolean validateSyntax(String code) {
JavaParser parser = new JavaParser();
ParseResult<CompilationUnit> result = parser.parse(code);
return result.isSuccessful();
}
public static void main(String[] args) {
String okCode = "class Test { void hello() { System.out.println(\"OK\"); } }";
String badCode = "class Test { void hello( { System.out.println(\"NG\"); } }";
System.out.println("OK Code: " + validateSyntax(okCode)); // true
System.out.println("Bad Code: " + validateSyntax(badCode)); // false
}
}
統合ポイント
- Serena MCP のサーバー層を Java で再構築(Spring Boot などでも可)。
- LLM が提案した変更を受け取り、
ASTValidator.validateSyntax()を通す。 - JavaParserはリファクタリング(メソッド名変更・インポート整理等)もAPIで可能。
メリット
- 大規模開発に向く(CI/CDと統合しやすい)
- 型安全性と例外制御が高水準
- 静的解析ツール(SpotBugs, PMD)と統合しやすい
言語別おすすめまとめ
| 開発目的 | 推奨言語 | 理由 |
|---|---|---|
| PoC・AI研究 | Python | 実装コストが低い、ライブラリが標準搭載 |
| AIコード補助ツール開発 | TypeScript | Serena MCPとの連携容易、ASTツール群が最強 |
| 企業向け品質保証・CI連携 | Java | 型安全性と堅牢なAST API |
| 高速・軽量ツール構築 | Go / Rust | コンパクトだが上級者向け |
結論
Serena MCP と AST解析は、いずれの言語でも統合可能である。
ただし用途に応じて次のように選択すると最適である。
- MCP連携・LLM統合の実務開発 → TypeScript
- 構文検証・コード品質保証 → Java
- 試験的プロトタイプ → Python
特に TypeScript 環境では、
Serena MCP + ts-morph + eslint + openai の構成が最も柔軟であり、
「構文検証 → 意味解析 → 再生成」までを Node.js 単体で完結できる。
Serena MCP × AST解析統合設計(Java / Spring Boot構成)
1. 目的
本設計は、Serena MCP(Model Context Protocol)に基づく
LLM駆動型コード修正支援サーバーに、
JavaのAST解析ライブラリである JavaParser を統合し、
AIによるコード自動生成・修正を「構文的に安全な形」で適用する仕組みを構築するものである。
2. 構成概要
serena-mcp-java/
├─ src/main/java/com/example/mcp/
│ ├─ SerenaMcpApplication.java … Spring Boot 起動クラス
│ ├─ controller/
│ │ └─ CodeController.java … RESTエンドポイント
│ ├─ service/
│ │ └─ CodeValidationService.java … 構文検証ロジック
│ └─ model/
│ └─ ValidationResult.java … 検証結果モデル
└─ pom.xml … 依存定義(JavaParser + Spring Boot)
3. 使用ライブラリ
| ライブラリ | 役割 |
|---|---|
| Spring Boot 3.x | MCPサーバーおよびREST API層 |
| JavaParser 3.x | AST解析・構文検証 |
| Jackson | LLMとのJSONデータ通信 |
| Lombok | モデルクラス簡略化 |
4. pom.xml 依存定義
<dependencies>
<!-- Spring Boot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- JavaParser -->
<dependency>
<groupId>com.github.javaparser</groupId>
<artifactId>javaparser-core</artifactId>
<version>3.26.2</version>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
<scope>provided</scope>
</dependency>
<!-- JSON処理 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
</dependencies>
5. メインクラス
package com.example.mcp;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SerenaMcpApplication {
public static void main(String[] args) {
SpringApplication.run(SerenaMcpApplication.class, args);
}
}
6. コントローラ層:CodeController.java
package com.example.mcp.controller;
import com.example.mcp.model.ValidationResult;
import com.example.mcp.service.CodeValidationService;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/code")
public class CodeController {
private final CodeValidationService validationService;
public CodeController(CodeValidationService validationService) {
this.validationService = validationService;
}
/**
* LLM など外部エージェントから送信されたコードを検証する。
* @param code 修正提案コード(Javaソース)
* @return 構文検証結果
*/
@PostMapping("/validate")
public ValidationResult validateCode(@RequestBody String code) {
return validationService.validate(code);
}
}
7. サービス層:CodeValidationService.java
package com.example.mcp.service;
import com.example.mcp.model.ValidationResult;
import com.github.javaparser.JavaParser;
import com.github.javaparser.ParseResult;
import com.github.javaparser.ast.CompilationUnit;
import org.springframework.stereotype.Service;
@Service
public class CodeValidationService {
private final JavaParser parser = new JavaParser();
/**
* JavaParser による構文解析。
* エラー発生時は詳細情報を返却。
*/
public ValidationResult validate(String code) {
ParseResult<CompilationUnit> result = parser.parse(code);
if (result.isSuccessful()) {
return new ValidationResult(true, "構文検証に成功しました。");
}
String message = result.getProblems().stream()
.map(problem -> problem.getMessage())
.reduce((a, b) -> a + "; " + b)
.orElse("不明な構文エラーです。");
return new ValidationResult(false, message);
}
}
8. モデル層:ValidationResult.java
package com.example.mcp.model;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class ValidationResult {
private boolean valid;
private String message;
}
9. 動作例
入力(POST /api/code/validate)
{
"code": "class Example { void test() { System.out.println(\"Hello\"); } }"
}
出力
{
"valid": true,
"message": "構文検証に成功しました。"
}
エラー例
入力:
{
"code": "class Example { void test( { System.out.println(\"NG\"); } }"
}
出力:
{
"valid": false,
"message": "'(' expected"
}
10. 運用・拡張イメージ
| 拡張機能 | 概要 |
|---|---|
| 差分適用モジュール | LLMからの変更提案を一時ファイルに保存し、ASTベースで差分生成・適用 |
| 構文+意味解析 | JavaParser + Spoonの併用で型・依存解析も実施 |
| CI/CD連携 | GitHub Actions で自動構文検証パイプラインを構築 |
| LLM連携 | Serena MCP API(WebSocket)経由で、LLM出力を自動検証ルートに流す |
11. 導入メリット
-
構文破損の自動検知
- LLMが出力した不完全コードの段階で検出・修正が可能。
-
CI/CDでの安全性向上
- Pull Request前にAST構文検証を自動化。
-
構造理解の拡張
- JavaParserはAST編集APIを提供しており、構造単位での自動リファクタリングも可能。
-
Serena MCPとの自然な連携
- MCPの「semantic edit」前後に構文検証をフックできる。
12. まとめ
- Serena MCP × JavaParser の統合により、AIによるコード修正を構文レベルで安全に実行できる。
- Spring Bootベースで構築することで、LLMエージェントとのAPI通信、CI/CD連携、監査ログなどを一体化できる。
- 将来的には、Spoon(ASTベースの型解析ライブラリ)や SonarQube API と統合し、意味・品質・構文の三層安全検証を実現できる。
Serena MCP は「単なるAIコード生成ツール」ではなく、プロジェクト全体の構造と文脈(Context)を理解する“知的コードオーケストレータ” なので、
その「文脈(Context)」を構築するために、既存のコードや設計情報(設計書、依存関係図、API仕様など) を適切に渡す必要があります。
以下、その理由・方法・リスクを体系的に整理します。
Serena MCP に既存コード・設計書を渡す必要性と最適な運用設計
1. なぜ「既存コードや設計書」が必要なのか
Serena MCP(Model Context Protocol)は、名前の通り LLMに“Model Context”を供給するプロトコル です。
この「Context」が無ければ、AIは以下のような致命的な制約を受けます。
| 問題 | 具体例 |
|---|---|
| 依存関係の不整合 | 関数やクラスの呼び出し先を誤認(コンパイル不可) |
| 設計思想の無視 | レイヤードアーキテクチャの責務を破壊する |
| ドキュメント整合性欠如 | コードコメント・仕様書との乖離 |
| 命名規約逸脱 | チーム命名規則や既存ドメイン用語を踏襲できない |
MCP の真価は、「コード全体を理解した上での意味的操作(semantic edit)」 にあります。
そのため、既存コードと設計資料を“Context Source”として登録することが不可欠です。
2. Serena MCP における「Context Source」の分類
| 種類 | 内容 | 具体例 |
|---|---|---|
| コードリポジトリ | ソースコード、構成定義、依存関係ファイル |
src/, pom.xml, package.json, .env
|
| アーキテクチャ設計書 | システム構成、クラス設計、データフロー | UML, ER図, README.md |
| API仕様書 | 外部連携・REST定義 | OpenAPI YAML, Postmanコレクション |
| テスト設計書 | テストケース・品質基準 | Test spec, Cucumber feature |
| ビジネスドメイン文書 | 用語集・業務フロー | Domain glossary, BPMN diagrams |
3. 実際の「渡し方」
Serena MCP の実装環境(たとえば Node.js や Java)により手段は異なりますが、基本的には次の3段階です。
(1) プロジェクトのインデックス化
serena index .
- コードベース全体を走査し、関数・クラス・依存関係を構造化。
-
.serena_index/または.mcp_cache/に格納。 - これが LLM にとっての「世界地図」になる。
(2) 設計ドキュメントの登録
YAMLやJSON形式で、Serena MCPが参照できるメタ情報を登録する。
例:context.yaml
project:
name: OrderManagementSystem
description: "顧客注文管理を行うSpring Bootアプリケーション"
documents:
- path: docs/system-architecture.md
- path: docs/api-spec.yaml
- path: docs/domain-model.md
tags:
- "architecture"
- "java"
- "spring"
登録コマンド(例):
serena context add context.yaml
(3) LLMへのContext供給(MCPプロトコル経由)
MCPサーバーは LLM(ChatGPT, Claude, Geminiなど)へ
context_request → context_response の形で構造情報を供給する。
{
"action": "get_context",
"payload": {
"repo": "https://github.com/example/project",
"components": ["UserService", "OrderController"]
}
}
4. 渡すべき情報の優先度(整理表)
| 優先度 | 種別 | 理由 |
|---|---|---|
| ★★★★★ | ソースコード全体 | セマンティック理解の基盤 |
| ★★★★☆ | 設計書(クラス図、ER図、API定義) | LLMが責務を誤認しないため |
| ★★★☆☆ | ドメイン用語集・命名規約 | 一貫した出力を維持 |
| ★★☆☆☆ | 過去の議事録・タスク履歴 | 意図理解には役立つが量が多い |
| ★☆☆☆☆ | 運用ログ・リリースノート | バージョン変遷の補助的情報 |
5. セキュリティ・機密性への考慮
Serena MCP は内部LLMまたはオンプレ構成でも動作可能だが、
コードや設計書をクラウドに送信する際は以下の対策が必須。
| リスク | 対応策 |
|---|---|
| 機密情報の漏洩 | プライベートリポジトリ / オンプレMCPサーバー利用 |
| 個人情報を含むデータ | プレプロセスでマスキング or 除外設定 |
| 契約制約 | OpenAI APIやAnthropic API利用時の契約確認 |
| 変更履歴の追跡 | Context提供時にGit Commit IDを紐づける |
6. 効果:Context提供による精度向上の例
| タスク | Context無し | Context有り |
|---|---|---|
| 関数リファクタリング | クラス外参照を誤削除 | 依存関係を考慮して安全編集 |
| API追加 | エンドポイント重複 | OpenAPIを参照して自動整合 |
| DBアクセス修正 | Repository層無視 | DAO層を適切に参照 |
| ログ出力修正 | ログ規約違反 | ロガー仕様を自動適用 |
7. 結論
Serena MCP の精度・信頼性は、提供される「文脈(Context)」の質に強く依存する。
したがって、既存コード・設計書・仕様書はMCPの“燃料”であり、欠かせない入力資源である。
導入時は次の手順を推奨する:
- プロジェクトのコード全体を
serena indexで登録 - 設計書・仕様書を
context.yaml経由で追加 - 開発規約・命名ルールも Context に含める
- 初回実行時に LLMへ「Context確認プロンプト」を発行(理解度をテスト)
これにより、Serena MCP は単なる補助ツールではなく、
「プロジェクトの文脈を理解してリファクタリングできる知的エージェント」として機能する。
Serena MCP と Excel方眼設計書の関係と対処設計
1. Excel方眼設計書の本質的な問題
Excel方眼紙は「表計算ソフトで疑似ドキュメントを作る」文化的産物で、
人間が読むには便利ですが、機械(AIやパーサー)にとっては非構造的です。
| 項目 | 内容 |
|---|---|
| 問題点1 | セル結合・書式依存 → 構造の抽出が困難 |
| 問題点2 | 見出しと値が明確でない |
| 問題点3 | 設計意図が自然言語と見出しに混在 |
| 問題点4 | 列順・セル結合が人によって違う |
| 問題点5 | テキスト抽出時に設計階層が失われる |
結果として、MCPやLLMが理解できる「設計構造」にならないのです。
2. Serena MCP が必要とする「Context形式」
Serena MCPがContextとして取り込めるのは、
以下のような構造化・機械可読形式です。
| 対応形式 | 内容 |
|---|---|
| YAML / JSON | データ構造が明確。ER図・API定義・クラス構成に最適 |
| Markdown (.md) | コメント・設計説明書として自然言語でも解析可能 |
| PlantUML / Mermaid | 図面情報(ER図・シーケンス図)を構文的に保持 |
| CSV(シンプル表形式) | Excel方眼からの中間変換に最適 |
| OpenAPI (YAML/JSON) | REST API定義をLLMが直接理解可能 |
3. Excel方眼設計書をContext化する3つの実践的ステップ
Step 1:Excelを構造抽出できる形に整理
Excel方眼設計書を、最低限「項目名」「説明」「型」「備考」が1列ずつに整理されたテーブルにします。
例:
| 項目名 | 型 | 必須 | 説明 |
|---|---|---|---|
| orderId | String | ○ | 注文ID |
| customerId | String | ○ | 顧客ID |
| orderDate | Date | ○ | 注文日 |
この段階では 見出しを正規化 することが重要です。
結合セルや複雑な色分けはすべて除去してください。
Step 2:CSVまたはYAMLに変換
CSV変換例(中間形式)
項目名,型,必須,説明
orderId,String,Yes,注文ID
customerId,String,Yes,顧客ID
orderDate,Date,Yes,注文日
YAML変換例(MCP Contextで使いやすい)
entities:
- name: Order
description: "注文データを表すエンティティ"
attributes:
- name: orderId
type: string
required: true
description: 注文ID
- name: customerId
type: string
required: true
description: 顧客ID
- name: orderDate
type: date
required: true
description: 注文日
このYAMLはそのまま Serena MCP の Context ファイルとして利用可能です。
登録例:
serena context add order-schema.yaml
Step 3:Context変換を自動化
現実的には、既存のExcel設計書を手動で変換するのは手間がかかります。
そのため、以下のツールチェーンが有効です。
| 手法 | 使用ツール | 説明 |
|---|---|---|
| Python変換スクリプト |
pandas + pyyaml
|
Excel → YAML変換を自動化 |
| Power Automate / VBA | Excelマクロでセル→CSV変換 | Windows環境で手軽 |
| Node.js変換 |
xlsx + json2yaml
|
JavaScript系環境に最適 |
Python例:
import pandas as pd
import yaml
df = pd.read_excel("order_design.xlsx")
data = {"entities": [{"name": "Order", "attributes": df.to_dict(orient="records")}]}
with open("order-schema.yaml", "w", encoding="utf-8") as f:
yaml.dump(data, f, allow_unicode=True)
4. Serena MCP に渡した後の動作イメージ
-
MCPがContextを読み込み
→ YAML内のentitiesやattributesをコード構造にマッピング -
LLMがContextを参照してコード提案
→ 例:「OrderService.java」にorderDateを自動追加
→ 例:「APIリクエストモデル」をContext内の型仕様に基づいて生成 -
構文検証(AST統合)で安全適用
→ JavaParserが文法破損を検出
→ Serena MCPが再生成を指示
5. 注意点:そのままExcelを渡してはいけないケース
| 状況 | 理由 |
|---|---|
.xlsm形式(マクロ付き) |
セキュリティ上読み込み不可 |
| 結合セルが多い | CSVやYAMLへの変換が失敗 |
| 複数シートを論理的に関連付けている | 構造を再現できないため、1シート1エンティティ単位に分割が必要 |
| 日本語の曖昧な見出し | “項目名”“名称”“カラム名”などを明確化する必要あり |
6. まとめ:対応可能性と推奨プロセス
| 要素 | 対応状況 | 対応方法 |
|---|---|---|
| Excel方眼設計書(そのまま) | × | 非構造的で解析不可 |
| Excel → CSV | △ | 一部自動変換可能、軽量Contextとして利用可 |
| Excel → YAML/JSON | ◎ | Serena MCP が直接理解可能(最適) |
| 設計図(UMLやER) | ◎ | PlantUMLまたはMermaid形式で連携可能 |
7. 実務推奨ワークフロー
- Excel設計書 → CSV整形 → YAML変換(自動)
- YAMLを Serena MCP の Context として登録
-
LLM に Context 認識テストを実行
(例:「Orderエンティティの必須項目を列挙して」) - 構文検証層(JavaParser)で最終検証
結論
- Serena MCP は 「設計書の意味構造」 を理解するツールであり、
Excel方眼紙のような視覚レイアウト依存の形式は理解できません。 - しかし、Excelの内容をYAML/JSON等に正規化すれば、Contextとして高精度に活用可能です。
- 実務的には、Excel→CSV→YAML変換を自動化することで、既存文化を維持しつつAI連携を実現できます。
Serena MCP に PDF設計書を渡す場合の可否と対応方針
1. Serena MCPが求めているもの
Serena MCP(Model Context Protocol)は、LLMにプロジェクトの構造的コンテキストを与えるための仕組みです。
つまり「ファイル形式」ではなく、「中に含まれる構造情報」を必要としています。
たとえば MCP が理解できるのは:
- クラス・関数・変数の依存関係
- API仕様(エンドポイント・型・パラメータ)
- データモデル構造(テーブル・エンティティ・属性)
- 設計意図(コメント、設計ルール)
これらが構造的に書かれていればOKですが、
PDFは基本的に「紙の画像 or レイアウト情報」であり、構造を保持していません。
2. なぜPDFではダメなのか(構造の喪失)
| 問題点 | 具体的な影響 |
|---|---|
| 構造が平坦化 | 表や階層がテキストとして検出できない |
| 位置情報依存 | 見出し・セル位置で意味を表しているが、AIにはわからない |
| 文字化け・罫線問題 | 日本語フォントや罫線付き表が正しく抽出されない |
| 自然言語と構造の混在 | 「〜のとき〜を返す」のような文が、構文構造を持たない |
MCPの内部では、AST(抽象構文木)や構造インデックスを作成してLLMに渡すため、
PDFのような非構造データは直接インデックス化できません。
3. 対応できるケース(例外)
次のようなPDFは、テキスト抽出すれば有効活用可能です。
| PDFの種類 | 扱い |
|---|---|
| テキストベースPDF(WordやExcelからエクスポート) | ✅ 文字情報を抽出すれば利用可能 |
| スキャンPDF(画像) | ❌ OCRしない限り不可 |
| フォームPDF(入力欄付き) | ⚠️ データ構造を抽出できるが、正規化が必要 |
つまり「中身がテキスト」なら抽出できますが、
「中身が画像(スキャンや方眼)」ならOCRと正規化が必要です。
4. 現実的な変換ワークフロー
(1) PDF → テキスト抽出
使用ツール例:
- Python:
pdfminer.six/PyMuPDF - Node.js:
pdf-parse - CLI:
pdftotext
pdftotext design.pdf design.txt
(2) テキスト → 構造化(Markdown / YAML 変換)
抽出したテキストを整理して、構造をつけ直します。
例(Markdown形式):
## クラス: OrderService
- 責務: 注文情報の登録と取得
- 使用エンティティ: Order, Customer
- 公開メソッド:
- createOrder(orderDto)
- getOrderById(orderId)
あるいは YAML:
service:
name: OrderService
description: 注文情報の登録・取得を担当
methods:
- name: createOrder
params: [orderDto]
- name: getOrderById
params: [orderId]
この構造化済みデータを Serena MCP に Context として登録します:
serena context add design.yaml
(3) スキャンPDFの場合はOCRを併用
スキャンPDFは画像のため、まずOCRでテキスト化します。
推奨ツール:
-
tesseract(無料・CLI) - Google Cloud Vision API(精度高)
- Azure Cognitive OCR
OCR出力を一旦Markdown整形すれば、Context化可能です。
5. Serena MCP のContext登録例(PDF由来)
project:
name: InventorySystem
description: "在庫管理システムの基本設計書(PDF由来)"
documents:
- path: docs/inventory-architecture.md
- path: docs/inventory-service.yaml
tags:
- "java"
- "architecture"
- "design"
6. 変換後の活用例
| タスク | PDFのまま | テキスト変換後 |
|---|---|---|
| クラス設計の理解 | 不可 | 「責務」「依存関係」を解析可能 |
| コード生成 | 無理 | YAML構造に基づき自動生成可能 |
| リファクタ提案 | 不可能 | 設計文書→コード間の整合チェックが可能 |
| LLMへのプロンプト | 意味不明な文字列 | 有効なContextとして活用 |
7. 結論と推奨運用
| 結論 | 詳細 |
|---|---|
| ❌ PDFそのままでは不可 | 構造を持たないため、MCPが理解できない |
| ✅ テキストPDFなら抽出して利用可 |
pdftotext等で変換して登録 |
| ✅ スキャンPDFはOCR→構造化で対応可 | Tesseractなどで中間変換 |
| ⚙️ 最適形式はMarkdown/YAML | Serena MCP Contextに最適化されている |
8. 実務用まとめワークフロー
PDF設計書
│
├─ テキスト抽出(pdftotext / PyMuPDF)
│
├─ 章・見出し構造をMarkdownに整形
│
├─ YAML化(エンティティ・API単位)
│
└─ Serena MCP に context add
9. 補足:どうしてもPDFを保持したい場合
「PDFそのものを参照として残したい」場合、
Contextメタ情報として参照リンクを付与する方法があります。
documents:
- path: docs/order_design.pdf
description: "原本PDF(参考用、解析対象外)"
role: reference
Serena MCP はこのPDFを直接解析はしませんが、
「この文書が存在する」というメタ情報をLLMに伝えることは可能です。
✅ まとめ
| 状況 | 可否 | 推奨対応 |
|---|---|---|
| PDF(画像スキャン) | ❌ | OCR→Markdown変換 |
| PDF(テキストベース) | △ | テキスト抽出→構造化 |
| Excel方眼からPDF出力 | ❌ | 元ExcelをCSV/YAMLに変換 |
| Markdown/YAMLへの再構築 | ◎ | MCPが理解可能 |
結論:
Serena MCPはPDFを直接“読む”ことはできません。
しかし、PDFの中身を抽出し、構造化データとして再利用することで100%活用可能です。
Serena MCP の認証とアクセス制御の仕組み
1. 前提理解:MCPは「サーバー—クライアント」モデル
Serena MCP は、
- MCP Server(例:Node.js, Java, Python等)
-
MCP Client(例:LLM / IDE / API Gateway)
の間で通信を行うプロトコル仕様(Model Context Protocol)を採用しています。
したがって、認証はこの通信層で行われます。
通常の構成では以下の3レイヤーで制御されます。
2. 認証の3層構造
| 層 | 対象 | 主な認証方式 | 補足 |
|---|---|---|---|
| ① API認証層 | LLM / 外部アプリがMCPサーバーに接続する際 | APIキー, Bearerトークン, OAuth2 | MCPサーバー起動時にトークンを発行 |
| ② Contextアクセス層 | 登録済みリポジトリやContext(設計情報) | アクセス権限(Read / Write / Index) | YAML設定で制御可能 |
| ③ LLMリクエスト層 | LLMからMCPへのContext要求 | APIキー連携 or JSON Web Token(JWT) | クライアントが個別認証 |
3. 実装例(Node.js / Serena MCP Server)
サーバー設定ファイル(mcp.config.json)
{
"auth": {
"enabled": true,
"type": "bearer",
"token": "sk-serena-1234567890abcdef"
},
"contexts": [
{
"name": "projectA",
"path": "./repo/projectA",
"permissions": ["read", "index"]
},
{
"name": "projectB",
"path": "./repo/projectB",
"permissions": ["read", "write"]
}
]
}
クライアント側設定(例:LLM / CLI)
export SERENA_MCP_TOKEN="sk-serena-1234567890abcdef"
MCPへのリクエスト例:
curl -H "Authorization: Bearer sk-serena-1234567890abcdef" \
-X POST http://localhost:8080/api/context/list
4. Context単位のアクセス制御(Role-based)
Serena MCPは「Context(コードベース・設計情報単位)」ごとに権限を割り当てることができます。
contexts:
- name: OrderSystem
path: ./contexts/order
permissions:
read: ["llm", "developer"]
write: ["architect"]
index: ["admin"]
これにより、
- LLMはリポジトリの読み取りのみ可能
- アーキテクト権限者のみ修正可能
- 管理者のみインデックス再生成が許可
といったロールベースアクセス制御(RBAC)が実現します。
5. APIキー / JWT 認証の違い
| 項目 | APIキー | JWT(JSON Web Token) |
|---|---|---|
| 特徴 | 単一固定キーで認証 | ユーザー情報と署名を持つトークン |
| 利点 | シンプル・ローカル用途に最適 | 期限・ロールをトークンに埋め込める |
| 想定用途 | ローカルMCPサーバー, 開発用途 | チーム・企業利用, クラウド環境 |
| 実装例 | Bearerヘッダ | JWT署名(HS256) |
JWT署名方式例(Spring Bootなどのサーバー構成):
Algorithm algorithm = Algorithm.HMAC256("secret");
String token = JWT.create()
.withIssuer("serena-mcp")
.withClaim("role", "developer")
.withExpiresAt(new Date(System.currentTimeMillis() + 3600 * 1000))
.sign(algorithm);
6. CI/CDやLLM連携での実運用設計
| 利用シーン | 推奨認証 | 補足 |
|---|---|---|
| ローカル開発(個人) | APIキー |
.envまたはCLI引数で設定 |
| チーム内共有(VSCode拡張等) | JWT認証 + RBAC | 開発者・レビュアーで権限差をつける |
| CI/CD統合(GitHub Actions等) | 固定トークン + IP制限 | Build時Context読み込みのみ許可 |
| クラウドMCP(SaaS版) | OAuth2 / SSO | 組織の認証基盤と統合可能 |
7. セキュリティ運用上の補足
| 項目 | 対応策 |
|---|---|
| トークン漏洩対策 |
.envやVaultで暗号化管理 |
| ログ出力 | トークン文字列をマスク出力する設定推奨 |
| Contextアクセス監査 |
access.log にユーザーIDと操作内容を出力 |
| LLM接続時の安全性 | HTTPS+トークン認証併用 |
| 有効期限管理 | JWTのexpクレームまたはAPIキーTTLで制御 |
8. まとめ
| 要素 | 内容 |
|---|---|
| 認証の基本 | APIキー または JWTによる Bearer認証 |
| アクセス制御 | Context単位の RBAC(ロールベース) |
| 対応方式 | ローカル・チーム・クラウド利用すべて対応 |
| セキュリティ対策 | トークン暗号化・HTTPS・監査ログ |
| 実運用 |
.env / context.yaml / RBAC設定で一元管理 |
✅ 結論
- Serena MCPは「LLMとのContext共有」という特性上、
APIトークン / JWT / RBAC の3層構成で認証・認可を管理しています。 - 通常のローカル利用では「固定トークン」、
チーム/企業利用では「JWT+ロール制御」が推奨です。 - CI/CD・クラウド連携時もAPIキーを渡すだけで安全に認証できます。
Serena MCP におけるアクセストークン発行と管理
1. トークンの目的と位置づけ
Serena MCPのアクセストークンは、以下の目的で使用されます:
| 目的 | 内容 |
|---|---|
| 認証(Authentication) | LLMクライアント・IDE・CI/CDパイプラインなどがMCPサーバーにアクセスするための本人確認 |
| 認可(Authorization) | 特定のContext(リポジトリ・設計情報)に対する読み書き権限を制御 |
| ログ監査(Auditing) | トークンをキーにユーザー操作を追跡可能 |
つまり、Serena MCPはトークンを発行し、それを鍵としてContextにアクセスさせる構造です。
2. トークンの種類(2階層構成)
| 種類 | 用途 | 特徴 |
|---|---|---|
| APIキー型(Static Token) | 開発・検証用 | 管理者が手動発行、固定文字列 |
| JWT型(Dynamic Token) | チーム・運用用 | 有効期限・署名・ロール情報を含む |
3. トークン発行のイメージ
(1) MCPサーバー起動時に発行(Static Token)
設定ファイル例(mcp.config.json):
{
"auth": {
"enabled": true,
"type": "bearer",
"token": "sk-serena-1234567890abcdef"
}
}
この場合、サーバー起動時にこのトークンを持つクライアントのみアクセス可能です。
クライアント(例:VSCodeプラグイン、LLM)側設定:
export SERENA_MCP_TOKEN="sk-serena-1234567890abcdef"
(2) API経由で発行(JWT形式)
管理者アカウントから /api/auth/token にアクセスして発行:
curl -X POST http://localhost:8080/api/auth/token \
-H "Content-Type: application/json" \
-d '{"user":"dev01","role":"developer"}'
戻り値例:
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expires_in": 3600,
"token_type": "Bearer"
}
このトークンはJWT(署名付き)で、デコードすると以下のような情報が含まれています:
{
"iss": "serena-mcp",
"sub": "dev01",
"role": "developer",
"exp": 1733689500
}
4. Java / Spring Boot 実装例(Serena MCP認証モジュール)
Spring Security + JWTを利用する構成です。
① トークン発行コントローラ
@PostMapping("/api/auth/token")
public ResponseEntity<Map<String, String>> issueToken(@RequestBody UserRequest user) {
Algorithm algorithm = Algorithm.HMAC256("secret-key");
String token = JWT.create()
.withIssuer("serena-mcp")
.withSubject(user.getUsername())
.withClaim("role", user.getRole())
.withExpiresAt(new Date(System.currentTimeMillis() + 3600 * 1000))
.sign(algorithm);
return ResponseEntity.ok(Map.of(
"access_token", token,
"token_type", "Bearer",
"expires_in", "3600"
));
}
② トークン検証フィルタ
public class JwtAuthFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws IOException, ServletException {
String header = request.getHeader("Authorization");
if (header != null && header.startsWith("Bearer ")) {
String token = header.substring(7);
try {
Algorithm algorithm = Algorithm.HMAC256("secret-key");
JWTVerifier verifier = JWT.require(algorithm).withIssuer("serena-mcp").build();
verifier.verify(token);
} catch (Exception e) {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid Token");
return;
}
}
filterChain.doFilter(request, response);
}
}
これにより、Serena MCPサーバーが自律的にアクセストークンを発行・検証できるようになります。
5. トークンのライフサイクル
| 項目 | 内容 |
|---|---|
| 発行方法 | 管理者API / CLIコマンド / 起動時自動生成 |
| 有効期限 | 通常1時間〜24時間(JWTのexpで設定) |
| 更新(リフレッシュ) |
/api/auth/refresh エンドポイントで再発行可 |
| 失効 | サーバー側でブラックリスト化 or 署名キー更新 |
| スコープ制御 | Context単位でread/write/index権限を制限可能 |
6. LLMやIDEとの連携時
Serena MCP は、LLMエージェントやVSCodeプラグインと連携する際、
HTTPヘッダまたは WebSocket トークンで認証を行います。
例:
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
トークンは .env または MCPクライアント設定ファイルに保持します:
SERENA_MCP_TOKEN=eyJhbGciOiJIUzI1NiIs...
SERENA_MCP_ENDPOINT=https://mcp.example.com
7. セキュリティと運用上の注意点
| 項目 | 対応策 |
|---|---|
| キー管理 | JWT署名鍵をVaultやSecrets Managerで暗号化保存 |
| HTTPS必須 | HTTP通信でのBearerトークン送信はNG |
| 有効期限短め推奨 | 1時間〜6時間程度で自動更新 |
| トークン漏洩監査 | 発行・失効履歴をログに記録 |
| 組織利用時 | SSO(OAuth2 / OpenID Connect)に統合可能 |
8. まとめ
| 項目 | 内容 |
|---|---|
| トークン発行可否 | ✅ 発行可能(APIまたは設定ファイル) |
| 種類 | Static Token / JWT Token |
| 発行主体 | MCPサーバー自身(Spring Boot / Node.jsなど) |
| 用途 | LLM・IDE・CI/CD・Context管理の認証 |
| 有効期限・権限 | カスタマイズ可能(JWTクレームで制御) |
✅ 結論
Serena MCP は「アクセストークンの発行・検証機能」を標準的に備えており、
APIキー形式でも JWT形式でも発行が可能です。
トークンごとに有効期限・ロール・スコープを定義でき、
LLMや開発ツールが安全にContextへアクセスできます。
Serena MCP 認証サーバー実装例(Spring Boot + JWT構成)
1. 概要
このサンプルは、Serena MCP の Context API を保護するための
アクセストークン発行・検証機能付き REST サーバーです。
主な機能:
- ユーザー認証(簡易認証)
- JWT アクセストークン発行(/api/auth/token)
- JWT 検証による API 保護(/api/context/**)
- トークン有効期限・ロール制御
- Bearer 認証による LLM/クライアント通信
2. プロジェクト構成
serena-mcp-auth/
├─ src/main/java/com/example/serena/
│ ├─ SerenaAuthApplication.java (メインクラス)
│ ├─ controller/AuthController.java (認証・トークン発行API)
│ ├─ controller/ContextController.java (保護対象API例)
│ ├─ security/JwtFilter.java (JWT検証フィルタ)
│ ├─ service/JwtService.java (JWT生成・検証ロジック)
│ └─ model/UserRequest.java (認証リクエストDTO)
└─ src/main/resources/application.yml
3. pom.xml
<dependencies>
<!-- Spring Boot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- JWT -->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>4.4.0</version>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
<scope>provided</scope>
</dependency>
</dependencies>
4. application.yml
server:
port: 8080
jwt:
secret: "serena-mcp-secret-key"
issuer: "serena-mcp"
expiration: 3600 # 秒(1時間)
5. メインクラス:SerenaAuthApplication.java
package com.example.serena;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SerenaAuthApplication {
public static void main(String[] args) {
SpringApplication.run(SerenaAuthApplication.class, args);
}
}
6. モデル:UserRequest.java
package com.example.serena.model;
import lombok.Data;
@Data
public class UserRequest {
private String username;
private String role;
}
7. サービス:JwtService.java
package com.example.serena.service;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.util.Date;
@Service
public class JwtService {
@Value("${jwt.secret}")
private String secretKey;
@Value("${jwt.issuer}")
private String issuer;
@Value("${jwt.expiration}")
private long expirationSeconds;
/**
* トークン生成
*/
public String generateToken(String username, String role) {
Algorithm algorithm = Algorithm.HMAC256(secretKey);
Date now = new Date();
Date exp = new Date(now.getTime() + expirationSeconds * 1000);
return JWT.create()
.withIssuer(issuer)
.withSubject(username)
.withClaim("role", role)
.withIssuedAt(now)
.withExpiresAt(exp)
.sign(algorithm);
}
/**
* トークン検証
*/
public void verifyToken(String token) {
Algorithm algorithm = Algorithm.HMAC256(secretKey);
JWT.require(algorithm)
.withIssuer(issuer)
.build()
.verify(token);
}
}
8. コントローラ:AuthController.java
package com.example.serena.controller;
import com.example.serena.model.UserRequest;
import com.example.serena.service.JwtService;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
@RestController
@RequestMapping("/api/auth")
public class AuthController {
private final JwtService jwtService;
public AuthController(JwtService jwtService) {
this.jwtService = jwtService;
}
/**
* トークン発行API
* POST /api/auth/token
*/
@PostMapping("/token")
public ResponseEntity<Map<String, Object>> issueToken(@RequestBody UserRequest user) {
String token = jwtService.generateToken(user.getUsername(), user.getRole());
return ResponseEntity.ok(Map.of(
"access_token", token,
"token_type", "Bearer",
"expires_in", 3600
));
}
}
9. JWTフィルタ:JwtFilter.java
package com.example.serena.security;
import com.example.serena.service.JwtService;
import jakarta.servlet.*;
import jakarta.servlet.http.*;
import org.springframework.stereotype.Component;
import java.io.IOException;
@Component
public class JwtFilter implements Filter {
private final JwtService jwtService;
public JwtFilter(JwtService jwtService) {
this.jwtService = jwtService;
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
String authHeader = request.getHeader("Authorization");
if (authHeader != null && authHeader.startsWith("Bearer ")) {
String token = authHeader.substring(7);
try {
jwtService.verifyToken(token);
} catch (Exception e) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.getWriter().write("Invalid or expired token");
return;
}
} else if (!request.getRequestURI().contains("/api/auth")) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.getWriter().write("Missing Authorization header");
return;
}
chain.doFilter(req, res);
}
}
10. 保護対象API例:ContextController.java
package com.example.serena.controller;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
@RestController
@RequestMapping("/api/context")
public class ContextController {
@GetMapping("/list")
public Map<String, Object> listContexts() {
return Map.of(
"contexts", new String[]{"OrderSystem", "InventorySystem", "UserManagement"}
);
}
}
11. 実行と動作確認
① トークン発行
curl -X POST http://localhost:8080/api/auth/token \
-H "Content-Type: application/json" \
-d '{"username":"developer","role":"dev"}'
出力例:
{
"access_token": "eyJhbGciOiJIUzI1NiIs...",
"token_type": "Bearer",
"expires_in": 3600
}
② トークン付きでContext APIアクセス
curl -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
http://localhost:8080/api/context/list
出力:
{
"contexts": ["OrderSystem", "InventorySystem", "UserManagement"]
}
③ トークンなしアクセス時
curl http://localhost:8080/api/context/list
出力:
HTTP/1.1 401 Unauthorized
Missing Authorization header
12. 構成のポイント
| 機能 | 実現方法 | 備考 |
|---|---|---|
| トークン発行 | /api/auth/token |
ユーザー名+ロールを受け取りJWT発行 |
| トークン署名 | HMAC256(秘密鍵署名) | 公開鍵署名にも対応可 |
| 有効期限 | 設定ファイル(jwt.expiration)で管理 |
通常1〜24時間 |
| フィルタ適用範囲 | /api/context/** |
Context APIを全保護 |
| LLM接続 | Bearerトークンで認証 |
.envまたはクライアント設定に格納 |
13. 実運用での拡張ポイント
| 項目 | 推奨実装 |
|---|---|
| ユーザー管理 | DBまたはLDAP認証に拡張 |
| トークン更新 |
/api/auth/refreshエンドポイントを追加 |
| ロール制御 |
@PreAuthorize("hasRole('ADMIN')")でSpring Security統合 |
| HTTPS通信 |
server.ssl.enabled=trueを設定 |
| クラウド認証連携 | OAuth2 / OpenID Connect に統合可能 |
✅ まとめ
- Serena MCPサーバーは、JWTアクセストークンを自律発行・検証可能。
- この仕組みにより、LLM・IDE・CI/CDツールなどが安全にContextへアクセスできる。
- トークンには「発行者・ユーザー・ロール・有効期限」が含まれ、Bearer方式でHTTPヘッダ送信。
- Spring Boot構成により、企業内MCPサーバーやクラウド展開にも対応可能。