Serena MCPのRubyサポートを改善してみた
背景
最近話題のSerena MCPですが、早速弊社でも利用を始めています。
LSPを利用してセマンティックなコード操作が行えるのが特徴ですが、一方で、対応言語はまだ限られています。
例えば、記事執筆現在、Rubyは indirect support (may require some code changes/manual installation) というステータスになっています。
(注: と書いていましたが、記事公開時点では正式サポートに格上げされました)

実際に我々が利用しているRuby on Railsの開発環境で起こっていた問題として、以下のようなエラーでSerena MCPの起動に失敗するというものがありました。
ERROR: While executing gem ... (Gem::FilePermissionError)
  You don't have write permissions for the
  /opt/rbenv/versions/x.x.x/lib/ruby/gems/x.x.x/gems/yard-0.x.xx directory.
これは、bundle config --local path vendor/bundle で設定されたRubyプロジェクトにおいて、Solargraphの初期化に失敗したことにより起こります。
今回は、この問題をClaude Code + Serena MCP自身を用いて調査・解消してみました。
解決した技術的課題
Solargraph LSPサポートの改善
問題: Serena MCPは従来、システムレベルでのgem installまたはgem execのみをサポートしており、Bundler環境を適切に処理できていませんでした。
解決策: Solargraph LSP実装に以下の機能を追加:
  # Gemfileの存在でBundlerプロジェクトを検出
  gemfile_path = os.path.join(repository_root_path, "Gemfile")
  is_bundler_project = os.path.exists(gemfile_path)
  if is_bundler_project:
      # bin/bundle と bundle コマンドの両方をサポート
      for bundle_cmd in ["bin/bundle", "bundle"]:
          # Gemfile.lockでsolargraphの存在を確認
          if "solargraph" in gemfile_lock_content:
              return f"{bundle_path} exec solargraph"
タイムアウト値の設定
問題: Solargraph LSP実装には明示的なタイムアウト設定がなく、他の言語サーバー(ElixirTools:
180秒、TypeScript: フォールバック機能付き)と比較して堅牢性に欠けていました。
解決策: 階層化されたタイムアウト戦略を実装:
  class Solargraph(SolidLanguageServer):
      def __init__(self, ...):
          # Bundler環境での遅い初期化を考慮
          self.set_request_timeout(120.0)  # LSPリクエストタイムアウト
      def _start_server(self):
          # サーバー準備待機のタイムアウト
          server_ready_timeout = 60.0
          if self.server_ready.wait(timeout=server_ready_timeout):
              self.logger.log("Solargraph is ready", logging.INFO)
          else:
              self.logger.log("Timeout but proceeding anyway", logging.WARNING)
まとめ
これらの改善により、幅広いRuby環境においてSerena MCPを実行できるようになりました。
最終的なPRは以下のものです。
Discussion