3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

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 のようなモデルと組み合わせた活用例も増えていて、実用性・現実性も高まっている。(株式会社一創 |)

🚀 どうやって使うのか(導入の流れ)

ざっくり以下のステップ:

  1. GitHub から Serena のリポジトリをクローン。あるいは uvx 経由でインストール。(apidog)
  2. プロジェクトをインデックス化。これでコードベース全体を対象にセマンティック操作が可能になる。(apidog)
  3. 好きな LLM(Claude, GPT, その他) を MCP クライアントとして設定。VS Code や他 IDE/エディタと組み合わせてもOK。(apidog)
  4. 通常の「AI にコード生成させるだけ」じゃなく、「検索・定義ジャンプ・リファクタリング・差分生成・編集実行」などを命令。AI が構造理解をもとに正しく実行する。
  5. 出力された変更は、必ず人間が確認 → コミット。AI は便利だけど万能じゃないので、この手順は重要。(NEXTSCAPE blog)

⚠️ 注意点・限界

  • まだ比較的新しい技術なので、「大規模プロジェクトでの運用実績」はそれほど多くない、という声もある。(NEXTSCAPE blog)
  • AI によるコード変更は強力だけど、「自動だから安心」とは限らない → 必ず人間によるレビューが必要。(apidog)
  • プロジェクトの構造が散らかっていたり、不整合が多いと、Serena の能力を引き出しにくいことも。整った構造のほうが効果的。(OpenBridge株式会社)

🎯 こんな人に向いてる/向かない

向いてる人/ケース

  • 大規模 or 複雑なコードベースを扱っていて、ただのコード補助ツールじゃ物足りない人
  • AI を使って「生成」だけじゃなく「リファクタリング」「保守」「設計修正」など、本格的な開発業務を効率化したい人
  • なるべくコストをかけずに、オープンソースな開発支援環境を構築したい人

向かない/注意が必要な人/ケース

  • 小さなスクリプトや単発コードくらいしか扱わない軽めの開発 — Serena の恩恵はあまり感じられない可能性あり
  • プロジェクト構成が雑、多言語・多フレームワークで混沌としている場合 — セッティングや安定運用が難しいかも


💻 Serena MCP の Windows セットアップ手順

🧩 ① 前提条件の確認

まず、以下のツールをインストールしておこう:

  1. Python 3.10 以上
    公式サイト からインストール
    (インストール時に「Add Python to PATH」にチェックを入れるのを忘れずに!)

  2. Git
    Git for Windows をダウンロードしてインストール

  3. Node.js(推奨)
    → MCP クライアントや連携ツールで必要になる場合あり
    Node.js公式サイト から LTS バージョンを入れよう。

  4. 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」を導入すると便利!

  1. VSCode Marketplace で “MCP Client” または “Serena MCP Extension” を検索
  2. 拡張をインストール
  3. 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つ:

  1. 構文安全性の確保
    LLMが生成・修正したコードをASTで検証し、「構文が壊れていないか」「意味的に破綻していないか」を確認。
    → これにより、“AIの出力をそのままコミットしたらビルドエラー!”が激減。

  2. 構造単位での編集制御
    Serena MCP の「semantic edit」をASTノード単位で制御する。
    例えば、「関数名変更」「引数の追加」「importの整理」などを、正規表現じゃなく構文的に安全に処理できる。

  3. 意味理解とリファクタリング補助
    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によるコード自動修正」を本番環境レベルで安全に実現するための現実的なステップ。
  • 特にリファクタリング、静的解析、セキュリティ検証などに応用できる。

🚀 もし始めるならこの順でやると良い

  1. ✅ Serena MCP を Windows 上で導入(すでにOKだね)

  2. ✅ tree-sitter を Python or Node.js 環境に追加

    pip install tree-sitter
    
  3. ✅ Serena MCP の「indexer」層をカスタムして AST を追加

  4. ✅ LLMに「AST構文チェックの前後処理」を組み込む(MCPのhookでOK)

  5. ✅ 最後に自動修正を 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-parsertree-sitter 等を用いて容易に再現可能。

7. 次の展開(推奨)

  1. 構文検証結果を LLM へフィードバック

    • 失敗時に「どの行の構文が破損しているか」を自動でLLMに返却し、再生成を促す。
  2. 差分適用モジュールとの統合

    • difflib や Git パッチ生成機能と組み合わせ、安全な差分更新を自動化。
  3. 多言語対応

    • 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. 導入メリット

  1. 構文破損の自動検知

    • LLMが出力した不完全コードの段階で検出・修正が可能。
  2. CI/CDでの安全性向上

    • Pull Request前にAST構文検証を自動化。
  3. 構造理解の拡張

    • JavaParserはAST編集APIを提供しており、構造単位での自動リファクタリングも可能。
  4. 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_requestcontext_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の“燃料”であり、欠かせない入力資源である。

導入時は次の手順を推奨する:

  1. プロジェクトのコード全体を serena index で登録
  2. 設計書・仕様書を context.yaml 経由で追加
  3. 開発規約・命名ルールも Context に含める
  4. 初回実行時に 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 に渡した後の動作イメージ

  1. MCPがContextを読み込み
    → YAML内のentitiesattributesをコード構造にマッピング

  2. LLMがContextを参照してコード提案
    → 例:「OrderService.java」にorderDateを自動追加
    → 例:「APIリクエストモデル」をContext内の型仕様に基づいて生成

  3. 構文検証(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. 実務推奨ワークフロー

  1. Excel設計書 → CSV整形 → YAML変換(自動)
  2. YAMLを Serena MCP の Context として登録
  3. LLM に Context 認識テストを実行
    (例:「Orderエンティティの必須項目を列挙して」)
  4. 構文検証層(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サーバーやクラウド展開にも対応可能。

3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?