2025年4月9日水曜日

Chainlitをコンテナで実行してOracleに問い合わせるMCPサーバーを組み込む

以前の記事「ChainlitのアプリケーションにOracle Databaseに問い合わせるMCPサーバーを組み込み質問する」でChainlitを動作させました。このアプリケーションをあまり環境に依存しないように、コンテナで実行させてみました。

作業はmacOSのpodmanを使って行います。

ローカルに適当なディレクトリを作成します。以下ではディレクトリとしてchainlit-mcp-oracleを作成しました。作成したディレクトリに移動して作業します。

mkdir chainlit-mcp-oracle
cd chainlit-mcp-oracle


% mkdir chainlit-mcp-oracle

% cd chainlit-mcp-oracle 

chainlit-mcp-oracle % 


以下の内容でDockerfileを作成します。

FROM python:3.13-slim
# Set environment variables
ENV DEBIAN_FRONTEND=noninteractive
# Install curl and other dependencies for Node.js
RUN apt-get update && apt-get install -y curl gnupg && \
curl -fsSL https://deb.nodesource.com/setup_23.x | bash - && \
apt-get install -y nodejs && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
WORKDIR /app
# Copy your application files
COPY requirements.txt .
COPY app.py .
COPY openai.env .
COPY index.ts .
# Copy any other necessary files or directories
# Install dependencies
RUN pip install --no-cache-dir -r requirements.txt
# Expose the port Chainlit runs on
EXPOSE 8000
# Command to run your Chainlit application
CMD ["chainlit", "run", "app.py", "--port", "8000", "--host", "0.0.0.0"]
view raw Dockerfile hosted with ❤ by GitHub

こちらの記事「ChainlitのアプリケーションよりPlaywright MCPを呼び出してOracle APEXのアプリケーションを操作する」で作成したapp.pyを、作業ディレクトリ以下に配置します。

https://github.com/monuminu/AOAI_Samples/blob/main/mcp_aoai/app.py

オリジナルのapp.pyに以下の変更を加えます。
< from openai import AzureOpenAI, AsyncAzureOpenAI
---
> from openai import OpenAI, AsyncOpenAI
11c11
< load_dotenv("azure.env")
---
> load_dotenv("openai.env")
17,21c17,19
<         self.deployment_name = os.environ["AZURE_OPENAI_MODEL"]
<         self.client = AsyncAzureOpenAI(
<                 azure_endpoint=os.environ["AZURE_OPENAI_ENDPOINT"],
<                 api_key=os.environ["AZURE_OPENAI_API_KEY"],
<                 api_version=os.environ["OPENAI_API_VERSION"]
---
>         self.deployment_name = os.environ["OPENAI_MODEL"]
>         self.client = AsyncOpenAI(
>                 api_key=os.environ["OPENAI_API_KEY"]

作業ディレクトリ以下にファイルopenai.envを作成し、OPENAI_MODELOPENAI_API_KEYの設定を記述します。
OPENAI_MODEL=gpt-4o-mini
OPENAI_API_KEY=[Open AIのAPIキー]
以下の内容を記述したファイルrequirements.txtを作成します。
chainlit
openai
python-dotenv
aiohttp
Oracleに問い合わせるMCPサーバーのコードindex.tsをあらかじめ配置しておきます。

https://gist.github.com/ujnak/22bacdabcf0fa108ff9d1d14d98e1e58

結果として、以下のファイルが作成されます。

chainlit-mcp-oracle % ls

Dockerfile app.py.org openai.env

app.py index.ts requirements.txt

chainlit-mcp-oracle % 


以上で準備は完了です。

コンテナ・イメージをchainlit-oracle-mcpという名前で作成します。

podman build --file Dockerfile --tag chainlit-oracle-mcp

chainlit-mcp-oracle % podman build --file Dockerfile --tag chainlit-oracle-mcp

STEP 1/11: FROM python:3.13-slim

STEP 2/11: ENV DEBIAN_FRONTEND=noninteractive

--> Using cache 1264b22e4ba065c8f8d00b723edd54d3922467ca7690ce0b7e0437945503731c

--> 1264b22e4ba0

STEP 3/11: RUN apt-get update && apt-get install -y curl gnupg &&     curl -fsSL https://deb.nodesource.com/setup_23.x | bash - &&     apt-get install -y nodejs &&     apt-get clean &&     rm -rf /var/lib/apt/lists/*

--> Using cache a2a3cba9b0a4485a807a281f09692dc413fed26aee34c58ceb6b7bd6d38fc051

--> a2a3cba9b0a4

STEP 4/11: WORKDIR /app

--> Using cache 2ae9c5a3f01fd3b031f741025f2218943d522bddc46baf42348ce89df4fa6041

--> 2ae9c5a3f01f

STEP 5/11: COPY requirements.txt .

--> deab204ce2e9

STEP 6/11: COPY app.py .

--> 469e9dbc1871

STEP 7/11: COPY openai.env .

--> f9c558203ec1

STEP 8/11: COPY index.ts .

--> 0741acf2d3c4

STEP 9/11: RUN pip install --no-cache-dir -r requirements.txt

Collecting chainlit (from -r requirements.txt (line 1))

  Downloading chainlit-2.4.400-py3-none-any.whl.metadata (6.3 kB)

Collecting openai (from -r requirements.txt (line 2))

  Downloading openai-1.72.0-py3-none-any.whl.metadata (25 kB)

Collecting python-dotenv (from -r requirements.txt (line 3))

  Downloading python_dotenv-1.1.0-py3-none-any.whl.metadata (24 kB)

Collecting aiohttp (from -r requirements.txt (line 4))

  Downloading aiohttp-3.11.16-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.metadata (7.7 kB)

Collecting aiofiles<25.0.0,>=23.1.0 (from chainlit->-r requirements.txt (line 1))

  Downloading aiofiles-24.1.0-py3-none-any.whl.metadata (10 kB)

Collecting asyncer<0.0.8,>=0.0.7 (from chainlit->-r requirements.txt (line 1))

  Downloading asyncer-0.0.7-py3-none-any.whl.metadata (6.6 kB)


[中略]


[notice] A new release of pip is available: 24.3.1 -> 25.0.1

[notice] To update, run: pip install --upgrade pip

--> b2e0e3dc56c2

STEP 10/11: EXPOSE 8000

--> 3b34cebebc30

STEP 11/11: CMD ["chainlit", "run", "app.py", "--port", "8000", "--host", "0.0.0.0"]

COMMIT chainlit-oracle-mcp

--> 684dab947de4

Successfully tagged localhost/chainlit-oracle-mcp:latest

684dab947de4fbeeaa2ee34f4cbffb86e527d8e6210efd9747321dd1001c8f87

chainlit-mcp-oracle % 


作成されたイメージを確認します。

podman image ls chainlit-oracle-mcp

chainlit-mcp-oracle % podman image ls chainlit-oracle-mcp

REPOSITORY                     TAG         IMAGE ID      CREATED             SIZE

localhost/chainlit-oracle-mcp  latest      684dab947de4  About a minute ago  546 MB

chainlit-mcp-oracle % 


イメージからコンテナをmy-chainlit-mcpという名前で作成して実行します。

podman run -d -p 8000:8000 --name my-chainlit-mcp localhost/chainlit-oracle-mcp

chainlit-mcp-oracle % podman run -d -p 8000:8000 --name my-chainlit-mcp localhost/chainlit-oracle-mcp

31be6d9e26003c31c0122e9940ecc5436bea94316afb34f3da2403bc66a0a8e0

chainlit-mcp-oracle % 


コンテナに接続して、Oracleに接続するMCPサーバーをビルドします。ビルドする手順は記事「Oracle Databaseに接続するMCPサーバーを作成しClaudeから問い合わせる」と同じです。

podman exec -it my-chainlit-mcp bash

chainlit-mcp-oracle % podman exec -it my-chainlit-mcp bash

root@31be6d9e2600:/app# 


以下を実行します。作成するMCPサーバーの名前はoracleとしています。

npx @modelcontextprotocol/create-server oracle-server

root@31be6d9e2600:/app# npx @modelcontextprotocol/create-server oracle-server

Need to install the following packages:

@modelcontextprotocol/create-server@0.3.1

Ok to proceed? (y) y


? What is the name of your MCP server? oracle

? What is the description of your server? My first MCP server

MCP server created successfully!


Next steps:

  cd oracle-server

  npm install

  npm run build  # or: npm run watch

  npm link       # optional, to make available globally


root@31be6d9e2600:/app# 


oracle-server/src以下にあるindex.tsをOracleのMCPサーバーの実装に置き換えます。

cp index.ts oracle-server/src/index.ts

root@31be6d9e2600:/app# cp index.ts oracle-server/src/index.ts 

root@31be6d9e2600:/app# 


Next stepsで案内されている通りにビルドします。

root@31be6d9e2600:/app# cd oracle-server/

root@31be6d9e2600:/app/oracle-server# npm install


> oracle@0.1.0 prepare

> npm run build



> oracle@0.1.0 build

> tsc && node -e "require('fs').chmodSync('build/index.js', '755')"



added 17 packages, and audited 18 packages in 2s


1 package is looking for funding

  run `npm fund` for details


found 0 vulnerabilities

root@31be6d9e2600:/app/oracle-server# npm run build


> oracle@0.1.0 build

> tsc && node -e "require('fs').chmodSync('build/index.js', '755')"


root@31be6d9e2600:/app/oracle-server# npm link


added 1 package, and audited 3 packages in 686ms


found 0 vulnerabilities

root@31be6d9e2600:/app/oracle-server# 


以上でコンテナにOracleに問い合わせるMCPサーバーが作成できました。

実行中のChainlitに、手元のブラウザから接続します。


コンセントのアイコンをクリックします。


Add your first MCP serverをクリックします。


NameOracleとし、Commandに以下を記述します。MCPサーバーの実体であるindex.jsはコンテナ内のパスを指定します。また、ローカルホストで動作しているOracle Databaseを接続先にしているためホスト名としてhost.containers.internalを指定しています。

npx node /app/oracle-server/build/index.js http://host.containers.internal:8181/ords/apexdev/_/sql wksp_apexdev [パスワード]

確認をクリックします。


MCPサーバーとしてOracleが追加されます。


以下の問い合わせを入力し、MCPサーバーの動作を確認します。

「私のOracleにはどのような表がありますか?」


以下のSQLを実行して回答しているので、MCPサーバーとしての組み込みは成功です。
{
    "mcp_name": "Oracle",
    "function_name": "query",
    "function_args": {
        "sql": "SELECT table_name FROM user_tables"
    }
}
今回の記事は以上になります。