簡易的にMCP Serverを立てたいとき、inline script metadata(PEP723)で単一ファイルに依存関係を記述したPythonファイルでサーバーを立てて置き、コンテナで立ち上げるのが楽だと思います。
main.py
# /// script
# requires-python = ">=3.14"
# dependencies = [
# "mcp[cli]>=2.2.0",
# ]
# ///
import os
from mcp.server import MCPServer
mcp = MCPServer("DemoMCP")
@mcp.tool()
def get_weather(prefecture: str) -> str:
return "晴れ時々曇り"
if __name__ == "__main__":
port = int(os.environ.get("PORT", "8000"))
mcp.run(
transport="streamable-http",
port=port,
host="0.0.0.0",
)
あとは、お好みで.envに環境変数を記述します。
$ echo "PORT=8000" > .env
コンテナを使えばホストにPythonの用意は必要ありません。PodmanでもDockerでも好きなものを使って起動します。
$ set -a && source .env && set +a
$ podman run --rm \
--volume "$PWD/main.py:/app/main.py:ro,Z" \
--volume uv-cache:/root/.cache/uv \
--env "PORT=${PORT:-8000}" \
--publish "${PORT:-8000}:${PORT:-8000}" \
ghcr.io/astral-sh/uv:python3.14-alpine \
uv run --script /app/main.py
もしmiseを使っている場合は、以下のようなmise.tomlを置いておくと、コマンドひとつで起動できるようになります。
mise.toml
[env]
_.file = ".env"
[tasks.up]
run = '''
podman run --rm \
--volume "$PWD/main.py:/app/main.py:ro,Z" \
--volume uv-cache:/root/.cache/uv \
--env "PORT=${PORT:-8000}" \
--publish "${PORT:-8000}:${PORT:-8000}" \
ghcr.io/astral-sh/uv:python3.14-alpine \
uv run --script /app/main.py
'''
実際にMCPを利用するときは、たとえばClaude Codeなら以下のようにしてMCPを追加できます。
$ claude mcp add --scope project --transport http demo http://localhost:8000/mcp
通常こういう簡易的な用途はMCP Serverを立てずにAgent Skillsで十分な場合が多いと思います。ですが、スクリプト自体をAIエージェントから隠したい場合(シークレット情報を扱うプロキシなど)は、このように簡易的なMCP Serverを立てる方が簡単かつ安全に使える時もあります。
環境
- podman version 4.9.3
- mise 2026.7.7 linux-arm64 (2026-07-15)