発展編 PythonでMCP Serverを作る
はじめに
本シリーズ「VS Code + Pythonで学ぶCodexとMCP入門」は、本編・全3回を通じて、Codexを「仕組みを理解する → 公開サーバーを使う → 実務で連携する」という流れで学ぶ構成となっています。本記事は、その発展編として、Codexから使うMCP Serverを自分で作る方法を解説します。
Codexは、単にコードを提案するだけのツールではなく、プロジェクトのファイルを読み、コードを書き換え、ターミナルコマンドを実行するところまで一貫して行う「コーディングエージェント」です。本編ではMCP(Model Context Protocol)の仕組みを理解し、公開されているMCP Serverを使い、GitHubなどと連携するところまでを扱いました。この発展編では、さらに一歩進んで、Pythonで独自のMCP Serverを自作します。
前提となる記事: 本記事は、本編(特に第1回・第2回)を読んで、MCPの仕組みと公開MCP Serverの使い方を理解していることを前提にしています。また、Codex単体の基本的な使い方は、次の記事で扱っています。
シリーズ全体の構成
| 回 | テーマ |
|---|---|
| 第1回 | CodexとMCPを理解する |
| 第2回 | 公開されているMCP ServerをCodexから使ってみる |
| 第3回 | Codex + MCPで外部サービスと連携してみる |
| 発展編 | PythonでMCP Serverを作ってCodexから使ってみる(本記事) |
本編では、公開されているMCP Serverを「使う側」として学びました。この発展編では、いよいよ提供する側を体験します。PythonでMCP Serverを自作し、自分で作ったツール(Tool)をCodexから呼び出してみます。
本記事はローカルPC上だけで完結します。サーバー契約は不要で、追加インフラ費用は0円です。
補足: 本記事の内容は執筆時点の情報にもとづいています。MCP SDKやCodexは更新が速いため、最新のAPIや設定方法はMCP公式ドキュメントとOpenAI公式のCodex MCPドキュメントで確認してください。
この記事のゴール
本記事では、PythonでMCP Serverを自作し、そのツールをCodexから呼び出すという一連の流れを学習します。
最終的には、
自分で書いたPython関数を「Codexが使えるツール」として公開し、Codexとの会話の中で呼び出せるようになる
ところをゴールにします。
1. なぜMCP Serverを自作するのか
MCP Serverを自作するメリットは、既存のMCP Serverにはない、自分専用の機能をCodexから使えるようにできることです。例えば、次のような機能です。
自作MCP Server
│
├─ 社内データベースを検索する
├─ CSVファイルから売上を集計する
├─ 自社APIから商品情報を取得する
├─ 独自の計算処理を実行する
└─ 社内システム用の処理を実行する
つまり、次のように考えると分かりやすいでしょう。
| やりたいこと | 使うもの |
|---|---|
| すでにある機能を使う | 公開MCP Server(本編第2回のGitHubなど) |
| 自分独自の機能をCodexに追加する | 自作MCP Server(本記事) |
本記事ではMCP Serverを自作する仕組みを理解するため、まずはシンプルな計算ツールから作っていきます。仕組みが分かれば、あとは中身を「社内DB検索」「CSV集計」などに差し替えるだけで、自分専用のツールを作れるようになります。
2. 今回作るもの
今回は、シンプルな計算ツールを提供するMCP Serverを作ります。次の2つのツールを用意します。
| ツール | 役割 |
|---|---|
add(a, b) |
2つの数を足し算する |
bmi(height_cm, weight_kg) |
身長と体重からBMIを計算する |
完成すると、Codexとの会話で「12と30を足して」「身長170cm・体重65kgのBMIは?」と頼むだけで、Codexが自作サーバーのツールを呼び出して答えてくれるようになります。
この記事でいちばん大切なのは、足し算そのものではなく、普通のPython関数が @mcp.tool() を付けるだけでCodexの道具になるという点です。全体の流れは次のようになります。
普通のPython関数
↓
@mcp.tool() を付ける
↓
MCP ServerがToolとして公開
↓
MCP(stdio)
↓
Codex
↓
「このToolを使おう」と判断
↓
Python関数が実行される
CodexとMCP Serverは同じPC内で動くため、通信方式は stdio(標準入出力) を使います。
3. 開発環境を準備しよう
作業用のフォルダを用意し、Pythonの仮想環境(venv)を作って、その中にMCP SDKをインストールします。
仮想環境(venv)とは: プロジェクトごとにライブラリを分離しておく仕組みです。ライブラリが増えても、他のプロジェクトに影響しません。venvやVS Codeでの実行に不安がある方は、次の記事も参考にしてください。
仮想環境を作る
VS Codeで C:\work\my-mcp-server フォルダを作って開き、ターミナル(PowerShell)で次を実行します。
cd C:\work\my-mcp-server
python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
Activate.ps1 を実行すると、プロンプトの先頭に (.venv) と表示されます。これが「仮想環境が有効な状態」です。
補足:
.gitignoreを作る場合は、仮想環境フォルダ.venv/を除外に追加しておきましょう。
MCP SDKをインストールする
仮想環境が有効な状態で、MCP SDKをインストールします。MCP SDKには、サーバーを手軽に書ける FastMCP という仕組みが含まれています。
pip install "mcp[cli]"
インストールできたか、確認します。パッケージによってはトップレベルに __version__ がないことがあるため、pip show で確認するのが確実です。
python -m pip show mcp
実行結果(例)
Name: mcp
Version: 2.2.0
Summary: Model Context Protocol SDK
...
補足: バージョン番号は実行時期により異なります(上記は一例です)。
Name: mcpとバージョンが表示されれば、インストールは成功です。
uvをインストールする
MCP Inspectorは、PythonのMCP Serverを起動する際に、内部で uv というツールを利用します。uv はPythonのパッケージ・プロジェクト管理ツールです。あらかじめインストールしておきましょう。
Windowsでは、PowerShellから次のコマンドでインストールできます。
winget install --id=astral-sh.uv -e
補足: インストール後に「パス環境変数が変更されました」といったメッセージが表示された場合は、いったんPowerShellを終了し、新しいPowerShellを起動してください。変更後のパスは、起動し直したPowerShellから反映されます。
本記事ではPythonの仮想環境(venv)を使っているため、PowerShellを起動し直した場合は、もう一度仮想環境を有効化します。
cd C:\work\my-mcp-server
.\.venv\Scripts\Activate.ps1
続いて、uv が使えるか確認します。
uv --version
実行結果(例)
uv 0.12.12
このようにバージョンが表示されれば、準備完了です(バージョン番号は実行時期により異なります)。
FastMCPとMCPの関係
「MCPとFastMCPは別物?」と迷いやすいので、関係を整理しておきます。
MCP(プロトコル:共通ルール)
└─ Python SDK(mcpパッケージ)
└─ FastMCP(サーバーを簡潔に書く高レベルAPI)
├─ Tool
├─ Resource
└─ Prompt
FastMCPは、MCP ServerをPythonで簡潔に実装するための高レベルAPIです。MCPという共通ルールに従ったサーバーを、難しい部分を意識せず数行で書けるようにしてくれます。
なお、MCP ServerはToolのほかに Resource(読み取り用データ)や Prompt(定型プロンプト)も提供できます。本記事では、仕組みを理解しやすくするために、いちばん分かりやすい Tool だけを扱います。
4. MCP Serverを作る
C:\work\my-mcp-server に server.py を作成します。FastMCPを使うと、普通のPython関数に @mcp.tool() を付けるだけで、その関数がCodexから呼べるツールになります。
# server.py
from mcp.server.mcpserver import MCPServer
# MCP Serverを作成
mcp = MCPServer("calc")
@mcp.tool()
def add(a: float, b: float) -> float:
"""2つの数を足し算する"""
return a + b
@mcp.tool()
def bmi(height_cm: float, weight_kg: float) -> float:
"""身長(cm)と体重(kg)からBMIを計算する(小数点以下2桁)"""
# ツールの引数はAIから渡されるため、値を信用しすぎない
if height_cm <= 0:
raise ValueError("身長は0より大きい値を指定してください。")
if weight_kg <= 0:
raise ValueError("体重は0より大きい値を指定してください。")
height_m = height_cm / 100
return round(weight_kg / (height_m ** 2), 2)
if __name__ == "__main__":
# stdio(標準入出力)でサーバーを起動する
mcp.run()
ポイントを整理します。
| 記述 | 意味 |
|---|---|
FastMCP("calc") |
calc という名前のMCP Serverを作る |
@mcp.tool() |
この関数をCodexが呼べるツールとして公開する |
型ヒント(a: float) |
引数の型がそのままツールの入力仕様になる |
docstring("""...""") |
ツールの説明としてCodexに伝わる |
mcp.run() |
stdioでサーバーを起動する |
型ヒントとdocstringは、単なるコメントではありません。Codexが「このツールは何をするもので、どんな引数が必要か」を理解するための情報になります。分かりやすく書くほど、Codexが正しくツールを使ってくれます。
入力値チェックの重要性
bmi 関数に入力値チェックを入れている点に注目してください。ツールの引数は、AI(Codex)から渡されます。想定外の値(例: height_cm=0)が渡されると、ゼロ除算などのエラーにつながります。MCP Toolでも、普通のPython関数と同じように入力値のバリデーションが重要です。「AIから渡される値を信用しすぎない」というのは、MCP Serverを作るうえでの実践的なポイントです。
5. サーバーを動作確認する(MCP Inspector)
Codexに登録する前に、サーバーが正しく動くかを単体で確認しておくと安心です。MCP SDKには、ブラウザ上でツールを試せる MCP Inspector が付属しています。
mcp dev server.py
実行すると、ローカルでInspectorが起動し、アクセス用のURLが表示されます。
実行結果(例)
Need to install the following packages:
@modelcontextprotocol/inspector@2.6.0
Ok to proceed? (y) y
初回実行時は、MCP Inspectorのインストール確認が表示される場合があります。
y を入力してEnterキーを押します。
Starting MCP inspector...
MCP Inspector Web is up and running at:
http://127.0.0.1:6274?MCP_INSPECTOR_API_TOKEN=...
...
ブラウザが自動的に起動し、MCP Inspectorの画面が表示されます。
最初はステータスが「Disconnected」になっています。
画面右側にあるトグルスイッチをクリックして、MCP Serverへ接続します。
接続に成功すると、「Connected」に変わります。
画面上部の Tools をクリックします。
続いて「add」 をクリックすると右側の「Select a tool to view details」の部分が、add の詳細・入力画面に変わります。
そこで、「a = 12」「b = 30」を入力して、「Execute Tool」をクリックします。
結果として、「42」が返れば成功です。
確認が終わったら、ターミナルで Ctrl + C を押してInspectorを停止します。
6. CodexにMCP Serverを登録する
作ったサーバーをCodexに登録します。Codex CLIでは、codex mcp add コマンドで登録できます。
仮想環境のPythonを明示する(重要)
ここで注意点があります。単に python と書くと、仮想環境(.venv)とは別のPythonが使われてしまうことがあります。その場合、.venv に入れた mcp パッケージが見つからず、サーバーが起動しません。
これを防ぐため、仮想環境のPythonを絶対パスで明示します。
codex mcp add calc -- C:\work\my-mcp-server\.venv\Scripts\python.exe C:\work\my-mcp-server\server.py
こうすると、次のように「確実に仮想環境のPythonでサーバーが動く」状態になります。
Codex
↓
.venv\Scripts\python.exe(仮想環境のPython)
↓
server.py
↓
mcp パッケージ(.venvにインストール済み)
登録できたか、一覧で確認します。
codex mcp list
実行結果
Name Command ...
calc C:\python\venv\Scripts\python.exe
...
Name Url Bearer Token Env Var Status Auth
github https://api.githubcopilot.com/mcp/ GITHUB_PAT_TOKEN enabled Bearer token
calc が一覧に表示されれば登録成功です。
補足(設定ファイルで登録する方法):
codex mcp addは、内部的に~/.codex/config.tomlに設定を書き込みます。手で書く場合は、次のような[mcp_servers.calc]テーブルを追記します。この設定は、Codex CLI・VS Code拡張・Codexアプリで共有されます。[mcp_servers.calc] command = "C:\\work\\my-mcp-server\\.venv\\Scripts\\python.exe" args = ["C:\\work\\my-mcp-server\\server.py"]
7. Codexからツールを実行する
Codexを起動します。作業フォルダはどこでも構いませんが、ここでは分かりやすくサーバーのフォルダで起動します。
codex
Codexが起動したら、TUI内で /mcp と入力すると、接続中のMCP Serverと、使えるツールを確認できます。
/mcp
実行結果
MCP servers
calc (stdio) … connected
tools: add, bmi
calc サーバーの add と bmi が見えていれば、Codexから使える状態です。実際に、日本語でそのまま頼んでみましょう。
calc サーバーの add ツールを使って、12 と 30 を足してください。
Codexはツールを呼び出す前に、確認を求めることがあります。内容を見て問題なければ許可すると、ツールが実行されます。
今回は動作確認のため、1. Allow を選択してEnterキーを押します。
ここで重要なのは、Codex自身が単純に 12 + 30 を計算しているのではなく、
Codex
↓
calc MCP Server
↓
add(a=12, b=30)
↓
実行結果をCodexへ返す
という形で、自作したMCP Toolを呼び出している点です。
続けて、BMIも計算させてみます。
身長170cm、体重65kgのBMIを、bmi ツールで計算してください。
実行結果
bmi ツールを呼び出しました(height_cm=170, weight_kg=65)。
BMIは 22.49 です。
Codexが、自分で書いたPython関数をツールとして呼び出し、その結果を使って答えてくれました。これが「MCP Serverを自作してCodexから使う」ということです。
8. ツールを追加してみよう
MCP Serverは、関数を追加するだけでツールを増やせます。試しに、消費税込みの金額を計算する tax_included ツールを追加してみます。
# server.py に追記
@mcp.tool()
def tax_included(price: float, rate: float = 0.10) -> int:
"""税抜き価格から税込み価格を計算する(rateは税率、既定10%)"""
# 学習用に端数を単純に切り捨てています(実際の税計算には端数処理のルールがあります)
return int(price * (1 + rate))
補足:
int(...)は小数部分を単純に切り捨てます。実際の税計算には四捨五入や切り上げなどの端数処理ルールがありますが、本記事では学習用として単純化しています。
追記したら、Codexを再起動します。
まず、Codex TUI内で次のコマンドを実行して終了します。
/quit
PowerShellに戻ったら、再度Codexを起動します。
codex
Codex起動後、必要に応じて /mcp でMCP Serverの接続状態を確認します。
/mcp
なぜ再起動が必要か: Codexは起動時にMCP Serverへ接続し、そのときにツール定義を読み込みます。ツールを追加・変更したら、MCP Serverのプロセスを再起動して新しいツール定義を読み込ませる必要があります。Codexを起動し直すと、サーバーも起動し直されます。
再起動後、/mcp で確認すると、ツールが3つに増えています。
Codexに頼んでみます。
1500円の税込み価格を tax_included ツールで計算してください。
実行結果
tax_included ツールを呼び出しました(price=1500)。
税込み価格は 1650 円です。
このように、Python関数を書いて @mcp.tool() を付けるだけで、Codexの能力を自由に拡張できます。
9. MCP Serverからデータベースを操作してみよう
ここまでは「計算」というシンプルなツールを作ってきました。ここからは、「自作MCP Serverなら社内データベースを検索できる」を、実際に体験してみます。
「計算するだけ」から一歩進んで、MCP ServerからデータベースのデータをCodexに取得させると、MCP Serverの実用性が一気に高まります。全体像は、これまで作ってきたものの自然な発展です。
【第1段階】ここまでで作ったもの
普通のPython関数
↓
@mcp.tool()
↓
Codexから実行
↓ 発展
【第2段階】これから作るもの
Codex
↓
MCP Server
↓
Python Tool
↓
Docker PostgreSQL
↓
実データを取得
データベースを直接PCにインストールすると、後片付けが面倒です。Dockerを使えば、コンテナを起動・停止・削除するだけで、PCを汚さずにPostgreSQLを試せます。
Docker環境を構築していない方は、以下の記事を参考にDocker Desktopをインストールしてください。
Docker Desktop for Windows 入門:仕組みと構築方法
9-1. 今回追加する構成
追加するのは、「指定した価格以下の商品をDBから検索する」search_products ツールです。データの流れは次のようになります。
Codex
│
│ MCP(stdio)
▼
MCP Server(Python / FastMCP)
│
│ search_products()
▼
psycopg(PostgreSQL用ドライバ)
│
│ localhost:5432
▼
Docker
└─ PostgreSQL
│
└─ products テーブル
Codexは、これまでの add や bmi と同じ感覚でツールを呼ぶだけです。「その裏でDBに接続してSQLを実行している」ことは、MCP Server(Python)側が引き受けます。ここでも「文章や判断はCodex、正確なデータ取得はPython」という役割分担は変わりません。
9-2. DockerでPostgreSQLを起動する
C:\work\my-mcp-server に、docker-compose.yml を作成します。
# docker-compose.yml
services:
db:
image: postgres:16
environment:
POSTGRES_USER: appuser
POSTGRES_PASSWORD: apppass
POSTGRES_DB: shop
ports:
- "5432:5432"
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:
PowerShellで、PostgreSQLをバックグラウンド起動します。
docker compose up -d
起動したか確認します。
docker compose ps
STATUS が Up になっていれば、PostgreSQLが localhost:5432 で使える状態です。
補足:
docker-compose.ymlにはDBのパスワードを書いています。これはローカル学習用のためです。実運用では、パスワードも環境変数やDocker secretsなどで管理し、リポジトリにコミットしないようにしてください。
9-3. products テーブルを作成する
商品を格納する products テーブルを作り、サンプルデータを入れます。次のような構成です。
products
├─ id … 商品ID
├─ name … 商品名
├─ price … 価格
└─ category … カテゴリ
| id | name | price | category |
|---|---|---|---|
| 1 | キーボード | 3000 | 周辺機器 |
| 2 | マウス | 1500 | 周辺機器 |
| 3 | USBケーブル | 800 | ケーブル |
| 4 | HDMIケーブル | 900 | ケーブル |
初期化用のSQLをinit.sqlとしてC:\work\my-mcp-serverディレクトリに作成します。
-- init.sql
CREATE TABLE IF NOT EXISTS products (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
price INTEGER NOT NULL,
category TEXT NOT NULL
);
INSERT INTO products (name, price, category) VALUES
('キーボード', 3000, '周辺機器'),
('マウス', 1500, '周辺機器'),
('USBケーブル', 800, 'ケーブル'),
('HDMIケーブル', 900, 'ケーブル');
このSQLを、起動中のコンテナに流し込みます。
Get-Content init.sql -Encoding UTF8 | docker compose exec -T db psql -U appuser -d shop
実行結果(例)
CREATE TABLE
INSERT 0 4
INSERT 0 4 と表示されれば、4件のサンプルデータが入りました。
9-4. PythonからPostgreSQLへ接続する
PythonからPostgreSQLへ接続するために、psycopg(PostgreSQL用ドライバ)をインストールします。仮想環境が有効な状態で実行してください。
pip install "psycopg[binary]"
接続の流れは次のとおりです。
Python
↓
psycopg
↓
PostgreSQL(Docker)
DB接続情報は、コードに直接書かず環境変数から読み込みます(第2回・実践編と同じ考え方です)。PowerShellで設定します。
codex mcp add --env DATABASE_URL=postgresql://appuser:apppass@localhost:5432/shop calc -- C:\python\venv\Scripts\python.exe C:\work\my-mcp-server\server.py
9-5. DB検索処理を作る
まず、MCPとは切り離した「普通のPython関数」として、DB検索処理を書きます。指定した価格以下の商品を取得する処理です。
# server.py に追記
import os
import psycopg
DATABASE_URL = os.environ.get("DATABASE_URL", "")
@mcp.tool()
def search_products(max_price: int) -> list[dict]:
"""指定価格以下の商品をDBから検索する(内部処理)"""
if not DATABASE_URL:
raise RuntimeError("DATABASE_URL が設定されていません。環境変数を確認してください。")
# SQLに値を文字列連結しない。プレースホルダ(%s)を使う(SQLインジェクション対策)
sql = "SELECT id, name, price, category FROM products WHERE price <= %s ORDER BY price"
with psycopg.connect(DATABASE_URL) as conn:
with conn.cursor() as cur:
cur.execute(sql, (max_price,)) # 値はタプルで別に渡す
rows = cur.fetchall()
return [
{"id": r[0], "name": r[1], "price": r[2], "category": r[3]}
for r in rows
]
作った _search_products を、@mcp.tool() を付けた関数から呼び出して、Codexが使えるツールにします。ここまで作ってきた add や bmi とまったく同じ作り方です。
ポイントは、SQLの中に max_price を文字列連結せず、プレースホルダ(%s)とパラメータで渡していることです。これがSQLインジェクション対策の基本になります
追記したら、Codexを再起動して新しいツールを読み込ませます(8章と同じ理由です)。
codex
/mcp で確認すると、calc MCP Serverで利用可能なToolが 4つ(4 tools) に増えていることを確認できます。
9-6. CodexからDBを検索する
実際に、Codexに日本語で頼んでみます。
1000円以下の商品を search_products ツールで検索してください。
Codexは search_products を呼び出し、その裏でPostgreSQLにSQLが実行されます。処理の流れは次のとおりです。
Codex
↓
search_products(max_price=1000)
↓
MCP Server
↓
PostgreSQL
↓
USBケーブル 800円
HDMIケーブル 900円
↓
Codexが回答
実行結果(例)
search_products ツールを呼び出しました(max_price=1000)。
1000円以下の商品は2件です。
- USBケーブル(800円 / ケーブル)
- HDMIケーブル(900円 / ケーブル)
Codexが、MCP Server経由で実際のデータベースからデータを取得して答えてくれました。
9-7. MCP ServerでDBを扱うときの注意点
最後に、MCP ServerからDBを扱うときの実践的な注意点をまとめます。AIから呼ばれるという前提が、通常のアプリ以上に重要になります。
-
DB接続情報をコードに直接書かない: 接続文字列やパスワードは環境変数(
DATABASE_URLなど)で管理し、リポジトリにコミットしない。 -
入力値を検証する:
max_priceのような引数はAIから渡される。範囲や型をチェックしてから使う。 - AIに自由なSQLを生成・実行させない: 「Codexが書いたSQLをそのまま実行する」のは危険。Tool側で決まったSQLを用意し、変えられるのは引数(パラメータ)だけにする。
-
UPDATE/DELETEは特に慎重に: 書き込み・削除系のツールは、影響範囲が大きい。本当に必要か検討し、必要でも確認や制限を設ける。
これらを踏まえると、MCP ServerでDBを扱う基本方針は次のようにまとめられます。
Tool側で決まったSQLを用意する
├─ AIが変えられるのは引数(パラメータ)だけ
├─ パラメータ化クエリでSQLインジェクションを防ぐ
└─ まずはSELECT中心(書き込みは慎重に)
これで、冒頭で挙げた「自作MCP Serverなら社内データベースを検索できる」を、実際に体験できました。products テーブルを社内の商品DBや在庫DBに置き換えれば、そのまま業務で使える形になります。
後片付け: DBを使い終わったら、Dockerコンテナを停止・削除できます。
docker compose downで停止、docker compose down -vとすればデータ(ボリューム)ごと削除されます。
10. MCP Serverを作るときのポイント
- docstringを丁寧に書く: ツールの説明はCodexが読んで判断します。「何をするツールか」を一文で明確に書きましょう。
-
型ヒントを必ず付ける: 引数の型(
float/str/intなど)を書くと、Codexが正しい形で呼び出してくれます。 - 入力値をチェックする: 引数はAIから渡されます。想定外の値に備えて、関数の中でバリデーションしましょう。
-
stdoutにプロトコル以外の出力を混ぜない: stdio transportでは、標準出力(stdout)がCodexとのプロトコル通信に使われます。ここに
print()などで任意の文字列を出すと、通信が壊れることがあります。デバッグ表示やログは、標準エラー出力(stderr)やloggingを使いましょう。
その関係を図にすると、次のようになります。
Codex
│
│ stdin → リクエスト
▼
server.py
│
│ stdout → レスポンス(プロトコル専用)
▼
Codex
stdoutは「Codexとの会話専用の通り道」なので、そこに関係のない出力を混ぜてはいけない、というわけです。
-
まずInspectorで単体確認: Codexに登録する前に
mcp devで動作確認しておくと、問題の切り分けが楽になります。 - 変更したら再起動: ツールを追加・修正したら、Codexを再起動して読み込み直します。
11. 登録解除・後片付け
MCP Serverをもう使わない場合は、Codexから登録を解除できます。削除コマンドはCLIのバージョンによって変わることがあるため、まず利用可能なコマンドを確認します。
codex mcp --help
一般的には、次のように名前を指定して削除します。
codex mcp remove calc
削除後、codex mcp list に calc が表示されなくなっていれば、登録解除は完了です。作成した C:\work\my-mcp-server フォルダや仮想環境(.venv)も、不要であれば削除して構いません。
まとめ
本記事では、PythonでMCP Serverを自作し、Codexから使う流れを解説しました。
| 項目 | ポイント |
|---|---|
| なぜ自作するか | 既存にない自分専用の機能(社内DB・CSV集計・独自APIなど)をTool化するため |
| 使うもの | Python仮想環境(venv)+ MCP SDK(mcp[cli])+ FastMCP |
| FastMCPとは | MCP ServerをPythonで簡潔に書く高レベルAPI |
| ツールの作り方 | 関数に @mcp.tool() を付けるだけ |
| Codexへの情報 | 型ヒントとdocstringがツール仕様として伝わる |
| 入力値チェック | 引数はAIから渡される。バリデーションが重要 |
| Codexへの登録 | 仮想環境のPython(.venv\Scripts\python.exe)を明示 |
| stdoutの注意 | プロトコル通信に使われるため、ログは stderr / logging へ |
| 実行確認 | TUIで /mcp、会話でツールを呼び出す |
| DB連携 | DockerのPostgreSQLへ psycopg で接続し、search_products をTool化 |
| DBの安全対策 | パラメータ化クエリ・環境変数管理・SELECT中心・自由なSQLを実行させない |
| 後片付け |
codex mcp remove で登録解除、docker compose down -v でDBを削除 |
この発展編では、「ツールを提供する側」を自分で作り、Codexから呼び出せるようになりました。「足し算」「BMI計算」から始めて、最後にはDockerのPostgreSQLに接続してデータを検索するツールまで作りました。products テーブルを社内の商品DBや在庫DBに置き換えたり、DB検索の部分を「CSV集計」「独自API呼び出し」などに差し替えたりすれば、自分の業務に合わせた専用ツールをCodexに追加できます。
本シリーズの記事一覧は以下の通りです。









