2025年8月7日木曜日

Ollamaでgpt-oss:20bを実行しOpen WebUIからSQLclのMCPサーバーを呼び出す

OpenAIからリリースされたgpt-oss:20bOllamaで実行し、SQLclのMCPサーバーをツールとして呼び出してデータベースに問い合わせを発行します。チャットを受け付けるフロントエンドにOpen WebUIを使用し、Open WebUIからSQLclのMCPサーバーを呼び出すために、mcpoを使用します。

作業にはApple SiliconのMacbook Pro(M4 128GB)を使用します。Open WebUI、mcpoおよびOracle Databaseはそれぞれ、podmanを使ってコンテナとして実行します。

以下の作業を行います。
  1. データベースにサンプル・スキーマSHをインストールし、SQLclのMCPサーバーが使用するデータベース・ユーザーMCPUSERを作成します。
  2. mcpoとSQLclをインストールしたコンテナ・イメージを作成します。作成したコンテナ・イメージからコンテナの作成と実行を行い、コンテナにSQLclが参照するデータベースへの接続情報を保存します。
  3. Ollamaにgpt-oss:20bをロードし実行します。
  4. Open WebUIをコンテナとして実行します。
  5. ブラウザからOpen WebUIにアクセスし、ツールとしてSQLclを組み込んだmcpoを設定します。
  6. チャットを行い動作を確認します。

データベースの準備



Oracle Database 23ai Freeのコンテナ・イメージからコンテナsales-dbを作成し実行します。オプションとして-p 1521:1521を指定し、ホストからデータベースにネット接続できるようにします。

podman run -d --name sales-db -p 1521:1521 container-registry.oracle.com/database/free:latest

% podman run -d --name sales-db -p 1521:1521 container-registry.oracle.com/database/free:latest

f0c94a522a9b3c32fba7fa3295774de338c8958bdf63a0df15b1491232d12a30

% 


コンテナのログにDATABASE IS READY TO USE!と出力されていることを確認します。出力されていれば、データベースは利用できます。

podman logs sales-db

% podman logs sales-db   

Starting Oracle Net Listener.

Oracle Net Listener started.

Starting Oracle Database instance FREE.

Oracle Database instance FREE started.


The Oracle base remains unchanged with value /opt/oracle

#########################

DATABASE IS READY TO USE!

#########################

The following output is now a tail of the alert.log:

FREEPDB1(3):Opening pdb with Resource Manager plan: DEFAULT_PLAN

2025-08-07T00:44:35.601724+00:00

Completed: Pluggable database FREEPDB1 opened read write 

Completed: ALTER DATABASE OPEN

2025-08-07T00:44:35.741920+00:00

===========================================================

Dumping current patch information

===========================================================

No patches have been applied

===========================================================

% 


SYSおよびSYSTEMのパスワードを設定します。デフォルトではランダムなパスワードが設定されています。

podman exec sales-db ./setPassword.sh <SYSのパスワード>

% podman exec sales-db ./setPassword.sh *******

The Oracle base remains unchanged with value /opt/oracle


SQL*Plus: Release 23.0.0.0.0 - Production on Thu Aug 7 00:48:52 2025

Version 23.8.0.25.04


Copyright (c) 1982, 2025, Oracle.  All rights reserved.



Connected to:

Oracle Database 23ai Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free

Version 23.8.0.25.04


SQL> 

User altered.


SQL> 

User altered.


SQL> 

Session altered.


SQL> 

User altered.


SQL> Disconnected from Oracle Database 23ai Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free

Version 23.8.0.25.04

% 


Oracle Database Sample Schemas 23cのv23.3をダウンロードします。

curl -OL https://github.com/oracle-samples/db-sample-schemas/archive/refs/tags/v23.3.zip


% curl -OL https://github.com/oracle-samples/db-sample-schemas/archive/refs/tags/v23.3.zip

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current

                                 Dload  Upload   Total   Spent    Left  Speed

  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0

100 11.6M    0 11.6M    0     0  3674k      0 --:--:--  0:00:03 --:--:-- 4709k

% 


ダウンロードしたv23.3.zipを解凍し、sales_historyのサンプル・データをインストールします。インストール作業にSQLclを使用します。


データベースにユーザーSYSTEMで接続し、sh_install.sqlを実行します。スクリプトを実行すると、新規に作成するスキーマSHに設定するパスワードの入力を求められます。この後の作業でデータベースにスキーマSHで接続するため、入力するパスワードは覚えておきます。


スキーマSHのデフォルト表領域上書きの設定はデフォルトのままで、変更は不要です。


unzip v23.3.zip
cd db-sample-schemas-23.3/sales_history
sql system/[パスワード]@localhost/freepdb1
@sh_install


% unzip v23.3.zip 

Archive:  v23.3.zip

e3325a83e56c516815844025418a96ecaf219751

   creating: db-sample-schemas-23.3

 extracting: db-sample-schemas-23.3/.gitignore  

  inflating: db-sample-schemas-23.3/LICENSE.txt  

  inflating: db-sample-schemas-23.3/README.md  

  inflating: db-sample-schemas-23.3/README.txt  

  inflating: db-sample-schemas-23.3/SECURITY.md  


[中略]


  inflating: db-sample-schemas-23.3/sales_history/sh_install.sql  

  inflating: db-sample-schemas-23.3/sales_history/sh_populate.sql  

  inflating: db-sample-schemas-23.3/sales_history/sh_uninstall.sql  

  inflating: db-sample-schemas-23.3/sales_history/supplementary_demographics.csv  

  inflating: db-sample-schemas-23.3/sales_history/times.csv  

% cd db-sample-schemas-23.3/sales_history 

sales_history % sql system/*******@localhost/freepdb1



SQLcl: 木 8月 07 10:08:22 2025のリリース25.2 Production


Copyright (c) 1982, 2025, Oracle.  All rights reserved.


Last Successful login time: 木 8月  07 2025 10:08:23 +09:00


接続先:

Oracle Database 23ai Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free

Version 23.8.0.25.04


SQL> @sh_install


Thank you for installing the Oracle Sales History Sample Schema.

This installation script will automatically exit your database session

at the end of the installation or if any error is encountered.

The entire installation will be logged into the 'sh_install.log' log file.


Enter a password for the user SH: ******



Enter a tablespace for SH [USERS]: 

Do you want to overwrite the schema, if it already exists? [YES|no]: 


Start time: 07-AUG-25 01.09.00.140452 AM +00:00                                      

******  Creating COUNTRIES table ....


Table COUNTRIESは作成されました。


******  Creating CUSTOMERS table ....


Table CUSTOMERSは作成されました。


******  Creating PROMOTIONS table ....


Table PROMOTIONSは作成されました。


[中略]


Installation verification    

____________________________ 

Verification:                


Table                            provided    actual 

_____________________________ ___________ _________ 

channels                                5         5 

costs                               82112     82112 

countries                              35        35 

customers                           55500     55500 

products                               72        72 

promotions                            503       503 

sales                              918843    918843 

times                                1826      1826 

supplementary_demographics           4500      4500 


Thank you!                                                  

___________________________________________________________ 

The installation of the sample schema is now finished.      

Please check the installation verification output above.    

                                                            

You will now be disconnected from the database.             

                                                            

Thank you for using Oracle Database!                        

                                                            

Oracle Database 23ai Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free

Version 23.8.0.25.04から切断されました

sales_history % 


スキーマSHに接続し、マテリアライズド・ビューCAL_MONTH_SALES_MVFWEEK_PSCAT_SALES_MVを完全リフレッシュします。
begin
     dbms_mview.refresh('CAL_MONTH_SALES_MV', method => 'C');
     dbms_mview.refresh('FWEEK_PSCAT_SALES_MV', method => 'C');
end;
/

sales_history % sql sh/********@localhost/freepdb1



SQLcl: 木 8月 07 10:17:01 2025のリリース25.2 Production


Copyright (c) 1982, 2025, Oracle.  All rights reserved.


接続先:

Oracle Database 23ai Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free

Version 23.8.0.25.04


SQL> begin

  2      dbms_mview.refresh('CAL_MONTH_SALES_MV', method => 'C');

  3      dbms_mview.refresh('FWEEK_PSCAT_SALES_MV', method => 'C');

  4  end;

  5* /


PL/SQLプロシージャが正常に完了しました。


SQL> exit

Oracle Database 23ai Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free

Version 23.8.0.25.04から切断されました

sales_history % 


以上でサンプル・データセットのsales_historyがインストールできました。

SQLclのMCPサーバーがsales_historyのサンプル・データセットを参照できるように、特別なデータベース・ユーザーを作成します。サンプル・データセットの参照だけを許可し、データセットの変更は許可しません。

データベースにSYS AS SYSDBAで接続し、データベース・ユーザーとしてMCPUSERを作成します。

create user mcpuser identified by mcpuser;
grant connect,resource to mcpuser;
alter user mcpuser quota 10m on users;

sales_history % sql sys/******@localhost/freepdb1 as sysdba



SQLcl: 木 8月 07 10:30:27 2025のリリース25.2 Production


Copyright (c) 1982, 2025, Oracle.  All rights reserved.


接続先:

Oracle Database 23ai Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free

Version 23.8.0.25.04


SQL> create user mcpuser identified by mcpuser;


User MCPUSERは作成されました。


SQL> grant connect,resource to mcpuser;


Grantが正常に実行されました。


SQL> alter user mcpuser quota 10m on users;


User MCPUSERが変更されました。


SQL> 


作成したデータベース・ユーザーMCPUSERに、スキーマSHが持つ表やビューのSELECT権限を与えます。

grant select any table on schema sh to mcpuser;

SQL> grant select any table on schema sh to mcpuser;


Grantが正常に実行されました。


SQL> exit

Oracle Database 23ai Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free

Version 23.8.0.25.04から切断されました

sales_history % 


データベースにユーザーMCPUSERで接続し、スキーマSHの表やビューを参照するシノニムを作成します。
set serveroutput on
declare
    l_statement varchar2(32767);
    l_select    varchar2(32767);
    l_count     number;
begin
    for r in (
        select owner, object_name from all_objects
        where owner = 'SH' and object_type in ('TABLE','VIEW')
          and instr(object_name,'$') = 0
    )
    loop
        if true then
            /* create synonym */
            l_statement := 'create synonym ' || r.object_name || ' for ' || r.owner || '.' || r.object_name;
            dbms_output.put_line(l_statement);
            execute immediate l_statement;
            -- verify synonym by counting rows
            l_select    := 'select count(*) into :cnt from ' || r.object_name;
            execute immediate l_select into l_count;
            dbms_output.put_line(l_select || ' / ' || l_count);
        else
            /* drop synonym */
            l_statement := 'drop synonym ' || r.object_name;
            dbms_output.put_line(l_statement);
            execute immediate l_statement;
        end if;
    end loop;
end;

sales_history % sql mcpuser/mcpuser@localhost/freepdb1



SQLcl: 木 8月 07 10:57:26 2025のリリース25.2 Production


Copyright (c) 1982, 2025, Oracle.  All rights reserved.


接続先:

Oracle Database 23ai Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free

Version 23.8.0.25.04


SQL> set serveroutput on

SQL> declare

  2      l_statement varchar2(32767);

  3      l_select    varchar2(32767);

  4      l_count     number;

  5  begin

  6      for r in (

  7          select owner, object_name from all_objects

  8          where owner = 'SH' and object_type in ('TABLE','VIEW')

  9            and instr(object_name,'$') = 0

 10      )

 11      loop

 12          if true then

 13              /* create synonym */

 14              l_statement := 'create synonym ' || r.object_name || ' for ' || r.owner || '.' || r.object_name;

 15              dbms_output.put_line(l_statement);

 16              execute immediate l_statement;

 17              -- verify synonym by counting rows

 18              l_select    := 'select count(*) into :cnt from ' || r.object_name;

 19              execute immediate l_select into l_count;

 20              dbms_output.put_line(l_select || ' / ' || l_count);

 21          else

 22              /* drop synonym */

 23              l_statement := 'drop synonym ' || r.object_name;

 24              dbms_output.put_line(l_statement);

 25              execute immediate l_statement;

 26          end if;

 27      end loop;

 28  end;

 29* /

create synonym CAL_MONTH_SALES_MV for SH.CAL_MONTH_SALES_MV

select count(*) into :cnt from CAL_MONTH_SALES_MV / 48

create synonym CHANNELS for SH.CHANNELS

select count(*) into :cnt from CHANNELS / 5

create synonym COSTS for SH.COSTS

select count(*) into :cnt from COSTS / 82112

create synonym COUNTRIES for SH.COUNTRIES

select count(*) into :cnt from COUNTRIES / 35

create synonym CUSTOMERS for SH.CUSTOMERS

select count(*) into :cnt from CUSTOMERS / 55500

create synonym FWEEK_PSCAT_SALES_MV for SH.FWEEK_PSCAT_SALES_MV

select count(*) into :cnt from FWEEK_PSCAT_SALES_MV / 10512

create synonym PRODUCTS for SH.PRODUCTS

select count(*) into :cnt from PRODUCTS / 72

create synonym PROFITS for SH.PROFITS

select count(*) into :cnt from PROFITS / 916039

create synonym PROMOTIONS for SH.PROMOTIONS

select count(*) into :cnt from PROMOTIONS / 503

create synonym SALES for SH.SALES

select count(*) into :cnt from SALES / 918843

create synonym SUPPLEMENTARY_DEMOGRAPHICS for SH.SUPPLEMENTARY_DEMOGRAPHICS

select count(*) into :cnt from SUPPLEMENTARY_DEMOGRAPHICS / 4500

create synonym TIMES for SH.TIMES

select count(*) into :cnt from TIMES / 1826



PL/SQLプロシージャが正常に完了しました。


SQL> exit

Oracle Database 23ai Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free

Version 23.8.0.25.04から切断されました

sales_history % 


参照可能な表のメタデータを、JSONドキュメントとして取得しておきます。スキーマSHで接続して以下のコードを実行します。スプール先のファイル名はmetadata.jsonとします。
set serveroutput on
set feedback off
spool metadata.json
declare
    l_metadata json;
    l_count    pls_integer;
begin
    l_count := 0;
    dbms_output.put_line('[');
    for r in (
        select object_name from all_objects
        where owner = 'SH' and object_type in ('TABLE','VIEW')
          and instr(object_name,'$') = 0
    )
    loop
        if l_count > 0 then
            dbms_output.put_line(',');
        end if;
        l_metadata := dbms_developer.get_metadata(r.object_name,level => 'BASIC');
        -- remove scheme from object info.
        select json_transform(l_metadata, remove '$.objectInfo.schema') into l_metadata;
        dbms_output.put_line(json_serialize(l_metadata pretty));
        l_count := l_count + 1;
    end loop;
    dbms_output.put_line(']');
end;
/
spool off

sales_history % sql sh/*******@localhost/freepdb1



SQLcl: 木 8月 07 12:01:42 2025のリリース25.2 Production


Copyright (c) 1982, 2025, Oracle.  All rights reserved.


接続先:

Oracle Database 23ai Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free

Version 23.8.0.25.04


SQL> set serveroutput on

SQL> set feedback off

SQL> spool metadata.json

SQL> declare

  2      l_metadata json;

  3      l_count    pls_integer;

  4  begin

  5      l_count := 0;

  6      dbms_output.put_line('[');

  7      for r in (

  8          select object_name from all_objects

  9          where owner = 'SH' and object_type in ('TABLE','VIEW')

 10            and instr(object_name,'$') = 0

 11      )

 12      loop

 13          if l_count > 0 then

 14              dbms_output.put_line(',');

 15          end if;

 16          l_metadata := dbms_developer.get_metadata(r.object_name,level => 'BASIC');

 17          -- remove scheme from object info.

 18          select json_transform(l_metadata, remove '$.objectInfo.schema') into l_metadata;

 19          dbms_output.put_line(json_serialize(l_metadata pretty));

 20          l_count := l_count + 1;

 21      end loop;

 22      dbms_output.put_line(']');

 23  end;

 24* /

[

{

  "objectType" : "TABLE",

  "objectInfo" :

  {

    "name" : "CAL_MONTH_SALES_MV",

    "columns" :

    [

      {

        "name" : "CALENDAR_MONTH_DESC",

        "notNull" : true,

        "dataType" :

        {

          "type" : "VARCHAR2",

          "length" : 8,

          "sizeUnits" : "BYTE"

        }

      },

      {

        "name" : "DOLLARS",

        "notNull" : false,

        "dataType" :

        {

          "type" : "NUMBER"

        }

      }

    ]

  },

  "etag" : "8C9210395BE477CBC7AA962A9F82E790"

}

,

{

  "objectType" : "TABLE",

  "objectInfo" :

  {

    "name" : "CHANNELS",

    "columns" :

    [

      {

        "name" : "CHANNEL_ID",

        "notNull" : true,

        "dataType" :

        {

          "type" : "NUMBER"

        }

      },

      {

        "name" : "CHANNEL_DESC",

        "notNull" : true,

        "dataType" :


[中略]


      {

        "name" : "END_OF_FIS_YEAR",

        "notNull" : true,

        "dataType" :

        {

          "type" : "DATE"

        }

      }

    ]

  },

  "etag" : "16A2DBCED85E5EF2F3A14DDDB492ABFD"

}

]


SQL> spool off

SQL> exit

Oracle Database 23ai Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free

Version 23.8.0.25.04から切断されました

sales_history %


以上でデータベースの準備は完了です。


mcpoとSQLclを組み込んだコンテナの実行



mcpoとSQLclを組み込んだコンテナ・イメージを作成します。mcpoはOpen WebUI向けに、MCPサーバーをOpenAPI互換のHTTPサーバーとしてにアクセスできるようにする、一種の代理サーバーです。詳しくはmcpoのGitHubのページを参照してください。

コンテナ・イメージの作成に、以下のDockerfileを使用します。


コンテナ・イメージに組み込むSQLclをダウンロードします。

curl -OL https://download.oracle.com/otn_software/java/sqldeveloper/sqlcl-latest.zip

コンテナ・イメージを作成します。

podman build -f Dockerfile -t mcpo:latest

% curl -OL https://download.oracle.com/otn_software/java/sqldeveloper/sqlcl-latest.zip


  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current

                                 Dload  Upload   Total   Spent    Left  Speed

100 87.8M  100 87.8M    0     0  9800k      0  0:00:09  0:00:09 --:--:-- 9359k

% podman build -f Dockerfile -t mcpo:latest  

STEP 1/12: FROM oraclelinux:9

STEP 2/12: RUN dnf update -y &&     dnf install -y sudo passwd unzip python3.12 python3.12-pip npm java-21-openjdk-headless &&     dnf clean all

--> Using cache 23e0b3aa2d45ddd2b3bf2e0181677e0a187370adc22398e8c9c97b735058ea83

--> 23e0b3aa2d45

STEP 3/12: ENV API_KEY=top-secret

--> 241ef719729a

STEP 4/12: RUN pip3.12 install --no-cache-dir mcpo

Collecting mcpo

  Obtaining dependency information for mcpo from https://files.pythonhosted.org/packages/3b/b2/54aab11bfcb7cdd574d1796dcaecf8f93e4d92d150286ba0d2d6e68b9524/mcpo-0.0.17-py3-none-any.whl.metadata

  Downloading mcpo-0.0.17-py3-none-any.whl.metadata (7.0 kB)

Collecting click>=8.1.8 (from mcpo)

  Obtaining dependency information for click>=8.1.8 from https://files.pythonhosted.org/packages/85/32/10bb5764d90a8eee674e9dc6f4db6a0ab47c8c4d0d83c27f7c39ac415a4d/click-8.2.1-py3-none-any.whl.metadata

  Downloading click-8.2.1-py3-none-any.whl.metadata (2.5 kB)

Collecting fastapi>=0.115.12 (from mcpo)

  Obtaining dependency information for fastapi>=0.115.12 from https://files.pythonhosted.org/packages/e5/47/d63c60f59a59467fda0f93f46335c9d18526d7071f025cb5b89d5353ea42/fastapi-0.116.1-py3-none-any.whl.metadata

  Downloading fastapi-0.116.1-py3-none-any.whl.metadata (28 kB)

Collecting mcp>=1.12.1 (from mcpo)


[中略]


--> ddbcfb283d6d

STEP 11/12: EXPOSE 8000

--> 02e68addb64b

STEP 12/12: CMD ["sh","-c","mcpo --port 8000 --api-key $API_KEY -- /home/oracle/sqlcl/bin/sql -mcp"]

COMMIT mcpo:latest

--> 6c4e198228ed

Successfully tagged localhost/mcpo:latest

6c4e198228eddbd7daf7c9e7426e57da09179adea3567944b3fb8a2465338cf9

% 


コンテナ・イメージがlocalhost/mcpo:latestとして作成されます。

作成されたコンテナ・イメージをもとに、コンテナmcpoを作成して実行します。環境変数API_KEYとしてOpenAPIのサーバーにアクセスする際に必要なAPIキーを指定しています。psなどの出力よりAPIキーが見えてしまうので、実運用を検討する場合は一工夫が必要です。

podman run -e API_KEY=my_secret -p 8091:8000 --name mcpo mcpo:latest

私の環境ではホストのポート8000が使用済みだったため、オプション-p 8091:8000を指定することにより、ホスト・ポートの8091番でOpenAPIのリクエストを受け付けるようにしています。

 % podman run -e API_KEY=my_secret -p 8091:8000 --name mcpo mcpo:latest


2025-08-07 03:24:40,514 - INFO - Starting MCPO Server...

2025-08-07 03:24:40,514 - INFO -   Name: MCP OpenAPI Proxy

2025-08-07 03:24:40,514 - INFO -   Version: 1.0

2025-08-07 03:24:40,514 - INFO -   Description: Automatically generated API from MCP Tool Schemas

2025-08-07 03:24:40,514 - INFO -   Hostname: 928ffdcd4c04

2025-08-07 03:24:40,514 - INFO -   Port: 8000

2025-08-07 03:24:40,514 - INFO -   API Key: Provided

2025-08-07 03:24:40,514 - INFO -   CORS Allowed Origins: ['*']

2025-08-07 03:24:40,514 - INFO -   Path Prefix: /

2025-08-07 03:24:40,514 - INFO - Configuring for a single Stdio MCP Server with command: /home/oracle/sqlcl/bin/sql -mcp

2025-08-07 03:24:40,514 - INFO - Uvicorn server starting...

INFO:     Started server process [1]

INFO:     Waiting for application startup.

OpenJDK 64-Bit Server VM warning: Unable to get SVE vector length on this system. Disabling SVE. Specify -XX:UseSVE=0 to shun this warning.

---------- MCP SERVER STARTUP ----------

MCP Server started successfully on Thu Aug 07 03:24:40 UTC 2025

Press Ctrl+C to stop the server

----------------------------------------

Aug 07, 2025 3:24:41 AM io.modelcontextprotocol.server.McpAsyncServer$AsyncServerImpl lambda$asyncInitializeRequestHandler$5

INFO: Client initialize request - Protocol: 2025-06-18, Capabilities: ClientCapabilities[experimental=null, roots=null, sampling=null], Info: Implementation[name=mcp, version=0.1.0]

Aug 07, 2025 3:24:41 AM io.modelcontextprotocol.server.McpAsyncServer$AsyncServerImpl lambda$asyncInitializeRequestHandler$5

WARNING: Client requested unsupported protocol version: 2025-06-18, so the server will sugggest the 2024-11-05 version instead

INFO:     Application startup complete.

INFO:     Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)

Starting MCP OpenAPI Proxy on 0.0.0.0:8000 with command: /home/oracle/sqlcl/bin/sql -mcp

INFO:     10.88.0.6:33308 - "GET /openapi.json HTTP/1.1" 200 OK

INFO:     10.88.0.6:33308 - "GET /favicon.ico HTTP/1.1" 404 Not Found



mcpoにアクセスして、動作を確認します。mcpoサーバーのopenapi.jsonを表示します。

http://localhost:8091/openapi.json

SQLclのMCPサーバーが提供しているツールの仕様が、OpenAPIのドキュメントとして表示されます。


コンテナmcpoに接続して、データベースへの接続を設定します。

podman exec -it mcpo sh

% podman exec -it mcpo sh 

sh-5.1$ 


SQLclを実行し、先ほど構成したデータベースにユーザーmcpuserで接続する設定を保存します。mcpoはpodmanのコンテナとして実行されているため、接続先のホストとして、localhostの代わりにhost.containers.internalを指定します。

./sqlcl/bin/sql /nolog
conn -save mydb -savepwd mcpuser/mcpuser@host.containers.internal/freepdb1
exit
exit

sh-5.1$ ./sqlcl/bin/sql /nolog

OpenJDK 64-Bit Server VM warning: Unable to get SVE vector length on this system. Disabling SVE. Specify -XX:UseSVE=0 to shun this warning.



SQLcl: Release 25.2 Production on Thu Aug 07 03:31:31 2025


Copyright (c) 1982, 2025, Oracle.  All rights reserved.


/bin/bash: line 1: tput: command not found

/bin/bash: line 1: tput: command not found

SQL> conn -save mydb -savepwd mcpuser/mcpuser@host.containers.internal/freepdb1

Name: mydb

Connect String: host.containers.internal/freepdb1

User: mcpuser

Password: ******

Connected.

SQL> exit

Disconnected from Oracle Database 23ai Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free

Version 23.8.0.25.04

sh-5.1$ exit

exit

%  


以上でmcpoとSQLclの準備は完了です。



Ollamaとgpt-oss:20bの実行



Ollamaでgpt-oss:20bを実行する方法については、巷に沢山の情報があると思います。以下のようにOllamaを実行し、モデルとしてgpt-oss:20bを選択します。


SettingsContext lengthは大きい値に変更しておきます。


Ollamaとgpt-oss:20bの準備は以上で完了です。


Open WebUIの実行



Open WebUIのコンテナを作成して実行します。Open WebUIでツール呼び出しをサポートしているのはバージョン0.6以上なので、タグにlatestが付いたイメージをもとにします。

最初に、設定その他を保存するボリュームを作成します。

podman volume create open-webui

% podman volume create open-webui

open-webui

% 


コンテナopen-webuiを作成し実行します。

podman run -d -p 3000:8080 -v open-webui:/app/backend/data -e OLLAMA_BASE_URL=http://host.containers.internal:11434 --name open-webui --restart always ghcr.io/open-webui/open-webui:latest

% podman run -d -p 3000:8080 -v open-webui:/app/backend/data -e OLLAMA_BASE_URL=http://host.containers.internal:11434 --name open-webui --restart always ghcr.io/open-webui/open-webui:latest

ff13fa1ee43b4b98be34e875900259f8f754cd4286e4f4e308ff428030cafd73

ynakakoshi@Ns-Macbook ~ % 


以上でOpen WebUIが実行されました。私の環境ではポート8080が使用済みだったため、オプション-p 3000:8080を指定しホスト・ポートの3000番でOpen WebUIにアクセスするようにしています。


ブラウザからアクセスすると、以下の画面が開きます。


Open WebUIが起動するまで、時間がかかる場合があります。そのような場合は、コンテナopen-webuiのログを確認します。

podman logs open-webui -f




mcpoをツールとして追加



Open WebUIの初期設定を行い、先ほど準備したmcpoをツールに追加します。

開始をクリックし、管理者アカウントを作成します。


管理者アカウントを作成すると、チャットの画面が開きます。

アカウントのメニューから設定を開きます。


設定ツールを開き、接続を追加をクリックします。


mcpoのサーバーにアクセスするURLを、URLに指定します。

Open WebUIのサーバーはコンテナ内で実行されていますが、ここで追加するツール呼び出しはブラウザから行われます。そのため、接続先のホストはhost.containers.internalではなくlocalhostになります。

URLとしてhttp://localhost:8091を設定し、Authにmcpoのコンテナ実行時に環境変数API_KEYとして設定した値をBearer以降に設定します。

リフレッシュのアイコンをクリックすると接続の確認ができます。これはAPIサーバーへの接続のみを確認し(openapi.jsonの取得)、APIキーが正しいかどうかは確認していないようです。

以上で接続を保存します。


以上で操作でツール・サーバーが追加されます。


Open WebUIでは管理者パネルにもツールの設定があります。管理者は、すべてのユーザーや限定されたグループが利用できるツールを設定できます。

しかし、管理者パネルツールを追加する際に接続の確認を実行すると、必ず失敗します。これは、管理者パネルからの接続の確認はコンテナ内で実行しているサーバーが行うため、localhostではなくhost.containers.internalでないと、コンテナの外にアクセスできないためです。


以上でツール呼び出しを行う設定が完了しました。


動作確認



新しいチャットを開始します。利用可能ツールとしてが表示されます。


利用可能ツールをクリックすると、利用可能ツールとしてsqlcl-mcp-server - v1.0.0が設定されていることが確認できます。

ツールを開くと、SQLclのMCPサーバーが提供しているツールの詳細が表示されます。


後は好きなようにチャットします。

「データベースmydbに接続して。」


先ほど出力したmetadata.jsonをファイルとしてアップロードします。アップロードしたmetadata.jsonだけを参照して、Oracle Databaseのカタログは参照せずにSQLを生成するように指示します。プロンプトはClaudeにmetadata.jsonを渡して生成してもらいました。


「これから生成するSQLは、metadata.jsonの情報のみを参照し、Oracle Databaseのカタログは参照しないでください。」

放っておくとカタログを検索するのですが、すべてシノニムにしているためカタログを検索しても情報は見つかりません。


「一番売り上げの多い製品を教えて。」


Claude Sonnet 4だと、生成したSELECT文の実行に失敗すると、SELECT文を生成し直して再度ツールを呼び出して実行しますが、Open WebUIとmcpoの組み合わせでは、再実行を指示する必要がありました。

「実行結果を表示してもらえますか?」


Claudeと比較するのはさすがに酷だとは思いますが、とりあえずは動いていますし、それもノートPCで動いているというのは、かなりの進歩だと思います。

今回の記事は以上になります。