3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【IBM Bob × WAS Liberty】MCPで既存Javaシステムを自然言語で使う

3
Last updated at Posted at 2026-10-01

IBM BobのMCP機能を使い、既存のJavaシステムを自然言語で使う

AI に社内資料を読ませて質問へ答えさせる取り組みは増えています。しかし実務で欲しくなるのは、説明だけではありません。既存の業務システムから最新情報を取得し、業務ルールに沿って処理することです。

この記事では、IBM WebSphere Application Server Liberty(以降、WAS Liberty)で稼働する Java アプリケーションのメソッドを MCP Tool として公開し、IBM Bob から呼び出す構成を紹介します。匿名化した会社員Aの交通費精算を題材に、Bob → MCP → WAS Liberty → Java 業務ロジックの流れを確認します。

この記事でできること

  1. WAS Liberty の Java メソッドを MCP Tool として公開する
  2. IBM Bob に Streamable HTTP の MCP サーバーとして接続する
  3. Bob から自然言語で Tool を実行し、Java 側の結果を受け取る

前提

必要なもの 用途
Java 17 以降 WAS Liberty とアプリケーションの実行
WAS Liberty 26.0.0.9 以降 mcp-1.0 を有効にする対象ランタイム
Maven サンプルのビルドと起動
IBM Bob MCP Client として Tool を呼び出す

このサンプルの通信経路は次のとおりです。

Bob → MCP Tool 呼び出し → WAS Liberty → CDI Bean の Java メソッド
Bob ← 結果の説明       ← MCP 応答       ← Java メソッドの実行結果

「社員ID EMP-A001(会社員A)の交通費精算状況を教えて」
「未精算の交通費と承認待ち件数を教えて」
「差戻しの明細があるか確認して」

こうした質問に答えるには、最新データを取得し、既存の業務ルールに従って処理する必要があります。

WAS Liberty の mcp-1.0 は、既存 Java アプリケーションの業務ロジックを MCP Tool として公開するための機能です。

mcp-1.0 は 26.0.0.9(2026年9月8日)で GA(正式提供)になりました。WAS Liberty 26.0.0.9 も同日に提供されています。ベータ版では機能名が mcpServer-1.0、設定要素が <mcpServer> でしたが、GA 版では mcp-1.0 と <mcp> を使用します。この記事のサンプルは GA 版の表記です。

ここでいう Tool は、AI が必要に応じて呼び出せる、名前と説明付きのアプリケーション機能です。AI が Java プログラムを直接実行するわけではありません。AI が MCP Tool を呼び出し、WAS Liberty がその Tool に対応する Java メソッドを実行します。AI は業務ルールそのものを実装するのではなく、「利用者の依頼を理解する」「使う Tool を選ぶ」「結果を人に伝える」役を担います。

最小の Tool を作る

コード上の役割

既存の Java アプリケーションには、すでに「顧客を調べる」「在庫を確認する」「金額を計算する」といった処理があります。MCP Tool 化は、その処理を AI に全部開放することではありません。AI が呼んでよい機能に、名前と説明を付けて専用の窓口を作ることです。

コード上の名前 役割 たとえ
ExpenseService などの既存 Service DB や社内 API を呼び、業務ルールを実行する 社内の専門部署
@Tool を付けたメソッド AI が呼べるようにする、限定された入口 その部署への受付窓口
@ToolArg AI が渡す情報の名前と意味を示す 受付票の入力欄
Bob 依頼内容を理解し、どの窓口へ行くか決め、結果を説明する 受付係と案内役

Bob が Java プログラムを自由に操作するわけではありません。開発者が @Tool を付けて公開した窓口だけを、MCP 経由で呼び出せます。

以下の3ファイルで動かせます。匿名化した会社員Aの交通費精算を返すので、外部APIやDBを準備せずに、MCP の接続・Tool 選択・応答を一度に確認できます。サンプルの EMP-A001 はダミーの社員IDです。

pom.xml

この最小サンプルは再現しやすさのため Open Liberty の Maven runtime を使います。WAS Liberty では、同じ Java コードと server.xml を、社内で標準化されている WAS Liberty 26.0.0.9 以降のビルド・デプロイ方法に載せ替えてください。WAS Liberty は Open Liberty を基盤としており、ほとんどの Liberty 機能と構成を共有しています。

<project xmlns="http://maven.apache.org/POM/4.0.0">
  <modelVersion>4.0.0</modelVersion>
  <groupId>io.openliberty.samples</groupId>
    <artifactId>mcp-expense</artifactId>
  <version>1.0.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <properties>
    <maven.compiler.release>17</maven.compiler.release>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.mcpjava</groupId>
      <artifactId>mcp-server-api</artifactId>
      <version>1.0.0</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>io.openliberty.api</groupId>
      <artifactId>io.openliberty.mcp</artifactId>
      <version>1.0.117</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>jakarta.enterprise</groupId>
      <artifactId>jakarta.enterprise.cdi-api</artifactId>
      <version>4.1.0</version>
      <scope>provided</scope>
    </dependency>
  </dependencies>

  <build>
    <finalName>mcp-expense</finalName>
    <plugins>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.14.1</version>
        <configuration>
          <release>${maven.compiler.release}</release>
        </configuration>
      </plugin>
      <plugin>
        <artifactId>maven-war-plugin</artifactId>
        <version>3.4.0</version>
        <configuration>
          <failOnMissingWebXml>false</failOnMissingWebXml>
        </configuration>
      </plugin>
      <plugin>
        <groupId>io.openliberty.tools</groupId>
        <artifactId>liberty-maven-plugin</artifactId>
        <version>3.12.0</version>
        <configuration>
          <serverName>mcp-expense</serverName>
          <runtimeArtifact>
            <groupId>io.openliberty</groupId>
            <artifactId>openliberty-runtime</artifactId>
            <version>26.0.0.9</version>
            <type>zip</type>
          </runtimeArtifact>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

src/main/java/io/openliberty/samples/mcp/ExpenseTools.java

CDI Bean のメソッドに @Tool と @ToolArg を付けます。

package io.openliberty.samples.mcp;

import java.util.Map;

import jakarta.enterprise.context.ApplicationScoped;
import org.mcpjava.server.tools.Tool;
import org.mcpjava.server.tools.ToolArg;

@ApplicationScoped
public class ExpenseTools {

    // 接続確認用の匿名化したサンプルデータ。実業務では Service / Repository を呼ぶ。
    private static final Map<String, ExpenseSummary> SAMPLE_SUMMARIES = Map.of(
            "EMP-A001", new ExpenseSummary("EMP-A001", "会社員A", 12000, 2, 0));

    @Tool(
        name = "getExpenseSummary",
        description = "Get unsettled travel expenses, pending approval count, and returned count for an employee. "
                + "The sample accepts EMP-A001 for fictional employee 会社員A."
    )
    public ExpenseSummary getExpenseSummary(
            @ToolArg(name = "employeeId", description = "Employee ID. The sample accepts EMP-A001.") String employeeId) {
        ExpenseSummary summary = SAMPLE_SUMMARIES.get(employeeId);
        if (summary == null) {
            throw new IllegalArgumentException("Unknown employee ID: " + employeeId);
        }
        return summary;
    }

public record ExpenseSummary(String employeeId, String employeeName,
            int unsettledTravelExpense, int pendingApprovalCount, int returnedCount) {}
}

MCP Tool はどこに追加するか

既存の業務Serviceそのものへ @Tool を付けるより、同じWAS Libertyアプリケーション内にMCP専用のToolクラスを追加するのが基本です。MCP対応は既存のWeb画面やREST APIを置き換えません。既存の入口は残したまま、Bob向けの ExpenseTools を並行して追加します。

既存の利用者                         IBM Bob
    ↓                                   ↓
Web画面 / REST API                 MCP
    ↓                                   ↓
ExpenseResource                 ExpenseTools  ← 新規追加
    └───────────────┬───────────────┘
                    ↓
          ExpenseService  ← 既存の業務ロジック
                    ↓
         ExpenseRepository / DB

既存の利用者は従来どおり画面やAPIを使い、Bobからの利用者だけがMCP経由で同じ業務ロジックを使います。ExpenseTools は AI 向けの入口だけを担い、既存の ExpenseService、Repository、DBアクセスは従来どおり利用します。

実業務では、サンプルの固定値を次のように既存Service呼び出しへ置き換えます。

@ApplicationScoped
public class ExpenseTools {

    @Inject
    ExpenseService expenseService;

    @Tool(name = "getExpenseSummary",
          description = "社員の未精算交通費と承認状況を返す")
    public ExpenseSummary getExpenseSummary(
            @ToolArg(name = "employeeId", description = "社員ID") String employeeId) {
        // この先で ExpenseService が Repository を呼び、DBを検索・集計する。
        return expenseService.findExpenseSummary(employeeId);
    }
}

この @Tool メソッド自体に SQL を書く必要はありません。MCP Tool は Bob からの入口、ExpenseService は業務ルール、Repository はDB検索という責務分担にします。例えば findExpenseSummary(employeeId) の内部で、社員IDを条件に未精算交通費を SUM し、承認待ち・差戻しを COUNT して ExpenseSummary を返します。具体的なSQL例は次の記事で扱います。

追加方法 向く状況 判断
同じWAS LibertyアプリにToolクラスを追加 既存アプリを変更できる 基本はこちら。業務ルール、認可、監査をそのまま使える。
別のWAS LibertyアプリをMCPゲートウェイとして追加 本体を変更できない、チームや認可境界を分けたい 既存システムのREST APIなどを呼ぶ。
別サーバーからDBを直接読む 既存APIがなく、限定した参照用途だけが必要 原則おすすめしない。認可や業務ルールを迂回しやすい。

別アプリにする場合も、DBを直接読むより既存システムのAPIを呼ぶほうが安全です。更新系Toolは特に、既存アプリケーションと同じ認可・入力検証・監査の境界で実行します。

src/main/liberty/config/server.xml

mcp-1.0 を有効にし、アプリケーション配下の MCP パスを指定します。

<server description="WAS Liberty MCP expense sample">
  <featureManager>
    <feature>mcp-1.0</feature>
  </featureManager>

  <httpEndpoint id="defaultHttpEndpoint" host="*" httpPort="9081" httpsPort="-1" />

  <application location="mcp-expense.war" type="war">
    <mcp path="/mcp" />
  </application>
</server>

起動します。

mvn liberty:run

アプリケーションを起動すると、Liberty のログに MCP エンドポイントが出力されます。

CWMCM0008I: The MCP server endpoint: http://localhost:9081/mcp-expense/mcp

Bob から呼び出す

Bob の MCP 設定に、Streamable HTTP の接続先を追加します。

{
  "mcpServers": {
    "liberty-expense": {
      "type": "streamable-http",
      "url": "http://localhost:9081/mcp-expense/mcp"
    }
  }
}

設定後、Bob の MCP 画面で liberty-expense が「接続済み」になれば、WAS Liberty の MCP エンドポイントへの接続は成功です。

スクリーンショット 2026-10-01 22.04.52.png

Bob で新しい会話を始めて「社員ID EMP-A001(会社員A)の交通費精算状況を教えて」と聞くと、Bob は getExpenseSummary を呼び出します。WAS Liberty が未精算交通費・承認待ち件数・差戻し件数を返します。Bob の応答に Tool 実行が表示され、結果が説明されれば成功です。

スクリーンショット 2026-10-01 22.02.51.png

なぜ WAS Liberty で MCP を使うのか

MCP サーバーは Node.js、Python、Go など、他の言語でも実装できます。AI が Tool を選び、外部システムの結果を説明するという仕組みは言語共通です。

WAS Liberty の価値は、既存 Java アプリケーションの CDI Bean、サービス層、Jakarta Security、運用監視を生かしながら、薄い追加実装で MCP の入口を作れることにあります。新しい AI 用バックエンドを別に作るのではなく、すでに動いている業務処理を安全に公開する選択肢になります。

WAS Liberty を使う実務上の利点

既存の WAS Liberty 資産 MCP Tool 化で生かせること
CDI Bean @ApplicationScoped などの CDI スコープを持つ Bean の、@Tool を付けたメソッドを WAS Liberty が検出する。既存の Service や依存性注入をそのまま利用できる。
Jakarta Security @RolesAllowed、@PermitAll、@DenyAll を Tool のクラスまたはメソッドへ指定できる。呼び出し元のロールに応じて、利用可能な Tool だけを公開できる。
WAS Liberty の運用基盤 起動時には MCP エンドポイントが WAS Liberty のメッセージログへ出る。monitor-1.0 を追加すれば、Tool 呼び出しの時間やエラーを既存のメトリクス基盤で観測できる。

たとえば、管理者だけが実行できる Tool は、通常の Jakarta Security のアノテーションで保護できます。

@ApplicationScoped
@RolesAllowed("Admins")
public class CustomerAdminTools {

    @Tool(
        name = "disableCustomer",
        description = "Disable a customer account."
    )
    public String disableCustomer(
        @ToolArg(name = "customerId", description = "Customer ID") String customerId
    ) {
        return customerService.disable(customerId);
    }
}

これは AI が安全性を保証するという意味ではありません。認可、入力検証、業務ルール、監査ログは、従来どおり WAS Liberty アプリケーション側で保証します。最初の導入では、更新しない参照系 Tool から始めるのが安全です。

WAS Liberty の MCP を選ぶ判断

MCP のためだけに Java や WAS Liberty を新規採用する、という話ではありません。すでに WAS Liberty または Jakarta EE の業務アプリケーションを運用していて、その機能を AI から使わせたい場合に特に適しています。

状況 選びやすい理由
既存の WAS Liberty アプリに、経費精算・在庫照会・社内検索などの機能がある 既存の Service と認可を生かし、薄い Tool 層を追加できる。
AI に最新の業務データを参照させたい RAG の文書だけではなく、既存アプリケーションの処理結果を返せる。
更新操作にも将来対応したい Jakarta Security、入力検証、監査ログと同じ境界で Tool を守れる。
運用チームが WAS Liberty のログ・監視基盤を使っている MCP の障害や遅延を、別の新規サーバーではなく既存の運用方法で追える。

一方、単発のローカル自動化だけが目的なら、Node.js や Python の stdio 型 MCP サーバーのほうが小さく始めやすい場合があります。既存の Java 業務アプリを AI とつなぐことが目的なら、WAS Liberty の mcp-1.0 は自然な選択肢になります。

なぜ業務 Tool がうれしいのか

このサンプルはダミーの会社員Aを返します。本番で価値が出るのは、WAS Liberty で動いている既存の経費精算機能を Tool として公開し、認可済みの実データを返すことです。

実業務では、サンプルの固定値を ExpenseService や Repository 呼び出しに置き換えます。AI がユーザーの「会社員Aの交通費精算状況を教えて」という依頼を理解し、WAS Liberty 上の Tool を呼び出します。アプリケーションは認可済みの範囲で最新情報を返し、AI はそれを読みやすい文章にします。

ユーザー: 会社員Aの交通費精算状況を教えて

AI:
- 未精算の交通費は 12,000 円です
- 申請済みで承認待ちの明細は 2 件です
- 差戻しの明細はありません

AI が情報を創作しているのではなく、業務システムが返した最新結果を説明している点が重要です。

担当 役割
AI 質問の理解、Tool の選択、結果の要約・説明
WAS Liberty アプリケーション データ取得、業務ルール、認可、入力検証、監査

この役割分担なら、既存アプリケーションを置き換えずに、自然言語で使える入口を追加できます。

最初に向くのは「参照系」

導入初期は、データを変更しない Tool が現実的です。

  • getExpenseSummary(employeeId)
  • getOrderDeliveryStatus(orderId)
  • searchKnowledgeBase(query)
  • getServiceHealth(serviceName)
  • getRecentErrorSummary(serviceName, duration)

たとえば運用チームなら、「決済サービスで昨日から何が起きている?」という質問に対して、Tool がログ・メトリクス・デプロイ情報を必要な範囲で集約し、AI が状況と次の確認事項を説明できます。

人は複数の運用画面を横断する代わりに、会話から入れます。一方で、実データの取得や集計は既存の Java コードと運用基盤が担います。

更新系 Tool は、便利だからこそ慎重にする

注文の登録、在庫の引当、ユーザーの無効化のような更新処理も Tool にできます。ただし、AI が自然言語を解釈して実行する以上、参照系より厳格な設計が必要です。

  • @RolesAllowed などで実行者の権限を制御する
  • Java 側で入力値と業務ルールを必ず検証する
  • 破壊的操作には明確な確認フローを入れる
  • 実行者、入力、結果を監査ログに残す
  • 可能なら最初は「変更案の作成」までに留め、人が確定する

MCP の Tool メタデータには、読み取り専用か、破壊的な可能性があるか、といったヒントも設定できます。ただし、これはあくまでクライアントへのヒントです。安全性は必ず認可と業務ロジック側で担保します。

REST API を置き換えるものではない

MCP Tool は REST API の代替ではありません。

REST API はシステム同士を確定的に連携させるインターフェースです。一方 MCP Tool は、AI が目的に合わせて「いつ、どの機能を呼ぶか」を選べるようにするインターフェースです。

既存の REST API、サービス層、DB アクセスを生かしつつ、その上に AI 向けの業務単位の入口を作る、という関係が扱いやすいでしょう。

まとめ

WAS Liberty の MCP 対応によって、既存 Java アプリの業務ロジックを AI の会話から呼び出せます。

価値があるのは、AI に業務処理を丸投げすることではありません。AI は依頼の理解、適切な Tool の選択、結果の説明を担い、正確な処理、認可、検証、監査は WAS Liberty アプリケーションが担う。この役割分担が、既存の業務システムを AI 時代の実用的な基盤へ変えます。

次の記事

MCP Tool が返す明細をどう絞り、LLMへ渡す情報量を抑えるかは、次の記事で解説します。

【IBM Bob × WAS Liberty】LLMに渡す明細を減らすMCP Tool設計

Java 25 移行済みの既存アプリを取得し、実際に MCP Tool を追加して Bob から呼び出す手順は、こちらです。

【IBM Bob × Liberty】既存Java 25アプリにMCP Toolを追加するハンズオン

参考: Expose your Liberty business logic as AI tools - a guide to the MCP feature

3
0
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
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?