mcp-clean-architecture
FastMCP Clean Architecture — MCP App UI テンプレート
MCP サーバーと MCP アプリを Python と FastMCP で構築するための、クリーンアーキテクチャ、依存性逆転、関心の分離、そして現代的な Python のプラクティスに従った、本番指向のテンプレートです。
このプロジェクトは、C# / .NET から来た開発者向けの学習リファレンスとしても意図されています。
目標は、動作する MCP サーバーを構築することだけではなく、保守可能で、テスト可能で、拡張可能で、外部フレームワークやサービスから独立したものを構築することです。
目標
このテンプレートは、以下の要素で MCP アプリケーションを構築する方法を示します。
Python
FastMCP
Streamable HTTP トランスポート
ステートレス HTTP
MCP ツール
MCP リソース
MCP プロンプト
MCP アプリ / アプリ UI
クリーンアーキテクチャ
依存性逆転
リポジトリパターン
ユースケース
Pydantic モデル
外部 REST API 統合
環境ベースの設定
非同期 HTTP 通信
依存性注入 / コンポジション
集中エラーハンドリング
構造化アプリケーションエラー
ロギング
単体テスト
統合テスト
サンプルドメインはeコマースアプリケーションです。
製品は公開外部 API から取得され、MCP を通じて公開されます。
アプリケーションは、以下のようなアクションをサポートするように進化します。
製品の検索
製品詳細の表示
製品をカートに追加
カートの表示
カートから製品を削除
MCP アプリ UI は、互換性のある MCP ホスト内でインタラクティブな体験を提供します。
アーキテクチャ
このプロジェクトはクリーンアーキテクチャの原則に従います。
MCP HOST
Claude / Copilot / etc.
|
| MCP over HTTP
v
+---------------------------------------------------------+
| PRESENTATION |
| |
| FastMCP Server |
| MCP Tools |
| MCP Resources |
| MCP Prompts |
| MCP App UI |
| Error Boundary |
+---------------------------+-----------------------------+
|
v
+---------------------------------------------------------+
| APPLICATION |
| |
| Use Cases |
| |
| GetProductUseCase |
| SearchProductsUseCase |
| AddProductToCartUseCase |
| GetCartUseCase |
+---------------------------+-----------------------------+
|
v
+---------------------------------------------------------+
| DOMAIN |
| |
| Entities / Models |
| |
| Product |
| Cart |
| |
| Repository Contracts |
| |
| ProductRepository |
| CartRepository |
| |
| Domain Errors |
+---------------------------+-----------------------------+
^
|
+---------------------------+-----------------------------+
| INFRASTRUCTURE |
| |
| External API implementations |
| HTTP clients |
| Configuration |
| Persistence adapters |
| |
| DummyJsonProductRepository |
| DummyJsonCartRepository |
+---------------------------+-----------------------------+
|
v
External REST API依存性のルール
最も重要なルールは次のとおりです。
Presentation ---> Application ---> Domain
^
|
Infrastructure ----------+依存関係はコアアプリケーションを指します。
ドメインは決して依存してはなりません:
FastMCP
HTTP libraries
Uvicorn
DummyJSON
Claude
Copilot
databases
environment variables
MCP App UI例えば:
MCP Tool
|
v
GetProductUseCase
|
v
ProductRepository
^
|
DummyJsonProductRepository
|
v
DummyJSON REST APIGetProductUseCase は ProductRepository の抽象化を知っています。
製品が HTTP または DummyJSON を使用して取得されることを知りません。
これにより、以下が可能になります:
DummyJSON後で以下に置き換えることができます:
SQL Server
PostgreSQL
MongoDB
another REST API
mock repositoryアプリケーションのユースケースを変更することなく。
プロジェクト構造
プロジェクトは次の構造に向かって進化します:
mcp-clean-architecture/
|
|-- src/
| |
| |-- domain/
| | |
| | |-- entities/
| | | |-- __init__.py
| | | |-- product.py
| | | `-- cart.py
| | |
| | |-- repositories/
| | | |-- __init__.py
| | | |-- product_repository.py
| | | `-- cart_repository.py
| | |
| | `-- errors/
| | |-- __init__.py
| | `-- domain_errors.py
| |
| |-- application/
| | |
| | |-- use_cases/
| | | |-- __init__.py
| | | |-- get_product.py
| | | |-- search_products.py
| | | |-- add_product_to_cart.py
| | | `-- get_cart.py
| | |
| | `-- errors/
| | |-- __init__.py
| | `-- application_errors.py
| |
| |-- infrastructure/
| | |
| | |-- config/
| | | |-- __init__.py
| | | `-- environment.py
| | |
| | |-- http/
| | |
| | |-- repositories/
| | | |-- __init__.py
| | | |-- dummy_json_product_repository.py
| | | `-- dummy_json_cart_repository.py
| | |
| | `-- errors/
| | |-- __init__.py
| | `-- infrastructure_errors.py
| |
| `-- presentation/
| |
| `-- mcp/
| |-- __init__.py
| |-- server.py
| |
| |-- tools/
| |
| |-- resources/
| |
| |-- prompts/
| |
| `-- apps/
|
|-- tests/
| |
| |-- unit/
| `-- integration/
|
|-- .env.example
|-- .gitignore
|-- .python-version
|-- pyproject.toml
|-- uv.lock
`-- README.mdフォルダは、実際の責任があるときに導入されるべきです。
テンプレートは、単により多くのレイヤーを持つためだけに抽象化を作成すべきではありません。
レイヤーの責任
Related MCP server: NitroStack
ドメイン
コアなビジネス概念と契約を含みます。
例:
Product
Cart
ProductRepository
CartRepository
ProductNotFoundError
CartErrorドメインは、外部世界がアプリケーションとどのように通信するかを知らずに、ビジネス概念を含むべきです。
アプリケーション
アプリケーション固有のワークフローとユースケースを含みます。
例:
GetProductUseCase
SearchProductsUseCase
AddProductToCartUseCase
GetCartUseCaseユースケースはドメインの抽象化を調整します。
外部 API を直接呼び出すべきではありません。
悪い例
class GetProductUseCase:
def execute(self, product_id: int):
requests.get(
f"https://external-api/products/{product_id}"
)ユースケースは今、以下を知っています:
HTTP が存在すること
どの HTTP ライブラリが使用されているか
どの外部プロバイダーが使用されているか
プロバイダーの URL がどのように機能するか
推奨例
class GetProductUseCase:
def __init__(self, repository: ProductRepository):
self.repository = repository
def execute(self, product_id: int) -> Product:
return self.repository.get_by_id(product_id)今、ユースケースは契約のみを知っています:
ProductRepositoryインフラストラクチャ
外部の技術的関心事の実装を含みます。
例:
HTTP clients
REST APIs
repositories
databases
cache
environment configuration
external service adapters例えば:
ProductRepository
^
|
DummyJsonProductRepositoryインフラストラクチャはドメインの抽象化を実装します。
ドメインはインフラストラクチャに依存しません。
プレゼンテーション
MCP 固有のエントリポイントを含みます。
例:
FastMCP Server
MCP Tools
MCP Resources
MCP Prompts
MCP AppsMCP ツールは薄く保つべきです。
その責任は主に次のとおりです:
MCP Request
|
v
Validate / map input
|
v
Use Case
|
v
Map result
|
v
MCP Responseビジネスロジックは MCP デコレータ内に存在すべきではありません。
MCP アーキテクチャ
MCP と FastMCP は異なる概念です。
MCP
|
`-- Protocol
FastMCP
|
`-- Python framework implementing MCPアプリケーションは Streamable HTTP 上で MCP を使用します。
MCP Host
|
| Streamable HTTP
v
http://localhost:8000/mcp
|
v
FastMCP Serverサーバーはデフォルトでステートレス HTTP で実行されるように設定されています。
MCP コンポーネント
ツール
モデルが実行できるアクション。
例:
get_product
search_products
add_product_to_cart
get_cart
remove_product_from_cart概念的には:
LLM
|
| tool call
v
MCP Tool
|
v
Use Caseリソース
リソースは、MCP ホストが読み取れるデータまたはコンテキストを公開します。
アプリケーションのビジネスロジックの代替になるべきではありません。
プロンプト
プロンプトは、MCP を通じて再利用可能なプロンプトテンプレートを提供します。
これらは MCP / プレゼンテーション境界に属します。
MCP アプリ UI
MCP アプリは、互換性のある MCP ホストが MCP 機能に関連するインタラクティブな UI を表示できるようにします。
私たちの eコマースの例は、最終的に概念的には次のようなものをレンダリングします:
+--------------------------------+
| Product |
| |
| Smartphone |
| |
| $799.99 |
| |
| [ Add to cart ] |
+---------------+----------------+
|
v
MCP Tool Call
|
v
AddProductToCartUseCase
|
v
CartRepository重要なアーキテクチャのルールは次のとおりです:
MCP アプリ UI はプレゼンテーションの関心事です。
UI はビジネスルールを実装すべきではありません。
例えば、クリック:
[ Add to cart ]結果は次のようになるべきです:
MCP App UI
|
v
MCP Tool
|
v
AddProductToCartUseCase
|
v
CartRepositoryUI はインフラストラクチャを直接操作しません。
環境設定
実行時設定は、ハードコードされるのではなく、環境変数から取得する必要があります。
現在の変数:
MCP_SERVER_TRANSPORT
MCP_SERVER_HOST
MCP_SERVER_PORT
MCP_STATELESS_HTTP例:
$env:MCP_SERVER_PORT="9000"設定フローは次のとおりです:
Operating System / Container
|
| Environment Variables
v
EnvironmentSettings
|
v
server.py
|
v
FastMCPこれにより、同じアプリケーションコードが以下で実行できます:
Local
Development
Test
Staging
Production
Docker
Kubernetes
Cloud environments異なる設定で。
シークレットは Git にコミットしてはなりません。
Python パッケージ規約
__init__.py は、Python パッケージの公開 API を定義するために使用できます。
例えば:
from infrastructure.config.environment import EnvironmentSettings
__all__ = [
"EnvironmentSettings",
]コンシューマは次を使用できます:
from infrastructure.config import EnvironmentSettings代わりに:
from infrastructure.config.environment import EnvironmentSettingsこれにより、内部ファイル構造への結合が減少します。
概念的には、これは TypeScript の:
index.tsバレルエクスポートとして使用されるものと似ています。
__all__ は意図された公開 API を定義します。
これは C# の public や private のようなアクセス修飾子ではありません。
Python / C# リファレンス
このプロジェクトは、.NET 開発者が Python を学ぶのを助けるためにも設計されています。
Python | C# の概念 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| おおよそ |
|
|
|
|
|
|
リポジトリ | しばしば |
| おおよそ |
|
|
|
|
|
|
| コンストラクタ |
| パッケージ初期化 / バレルエクスポートと同様の目的 |
Pydantic | 型付きモデル + 検証/シリアライゼーション |
| 使用状況に応じて属性/ミドルウェアの動作と概念的に類似 |
新しい Python の概念が導入されたとき、その C# 相当物は有用な場合に文書化されるべきです。
ドメインモデル
構造化モデルは、検証とシリアライゼーションが有用な場所で Pydantic を使用します。
例:
from typing import Annotated
from pydantic import BaseModel
class Product(BaseModel):
id: Annotated[int, "Product identifier"]
title: Annotated[str, "Product title"]
description: Annotated[str, "Product description"]
price: Annotated[float, "Product price"]
thumbnail: Annotated[str, "Product thumbnail URL"]Pydantic は以下を提供します:
validation
type coercion
serialization
JSON-compatible output
JSON Schema generationリポジトリパターン
リポジトリは、データまたは外部システムに対する抽象化を表します。
例:
from abc import ABC, abstractmethod
from domain.entities import Product
class ProductRepository(ABC):
@abstractmethod
def get_by_id(self, product_id: int) -> Product:
passC# 開発者にとって、これは概念的に次と似ています:
public interface IProductRepository
{
Product GetById(int productId);
}具体的なインフラストラクチャ実装は、実際の動作を提供できます:
ProductRepository
^
|
DummyJsonProductRepository外部 API
外部 API はインフラストラクチャからアクセスされる必要があります。
初期実装は、eコマースの例に公開 DummyJSON API を使用します。
アーキテクチャは、アプリケーションのユースケースが DummyJSON に直接依存することを防ぎます。
Application
|
v
ProductRepository
^
|
Infrastructure implementation
|
v
DummyJSONこれにより、外部プロバイダーは、アプリケーションまたはドメインレイヤーを書き直すことなく、後で置き換えることができます。
エラーハンドリング戦略
このプロジェクトは、クリーンアーキテクチャと一般的な .NET 例外処理パターンに触発された集中例外階層を使用します。
目標は、以下を区別することです:
expected business failures
vs
technical/infrastructure failures一方で、共通の構造化エラー契約を提供します。
エラー階層
AppError
|
|-- DomainError
| |
| |-- ProductNotFoundError
| `-- CartError
|
|-- ValidationError
|
`-- InfrastructureError
|
|-- ExternalAPIError
`-- ExternalAPITimeoutErrorすべての既知のアプリケーションエラーは、最終的に次から派生します:
AppError基本アプリケーションエラー
from typing import Any
class AppError(Exception):
error_code: str = "UNKNOWN_ERROR"
def __init__(
self,
message: str,
details: dict[str, Any] | None = None,
):
self.message = message
self.details = details or {}
super().__init__(message)
def to_dict(self) -> dict:
return {
"error_code": self.error_code,
"error_type": self.__class__.__name__,
"message": self.message,
"details": self.details,
}概念的には、これは C# と似ています:
public abstract class AppException : Exception
{
public string ErrorCode { get; }
protected AppException(
string message,
string errorCode)
: base(message)
{
ErrorCode = errorCode;
}
}ドメインエラー
ドメインエラーは、期待されるビジネス障害を表します。
例:
Product does not exist
Cart is empty
Product cannot be added to the cart
Requested quantity violates a business rule例:
class DomainError(AppError):
error_code = "DOMAIN_ERROR"
class ProductNotFoundError(DomainError):
error_code = "PRODUCT_NOT_FOUND"
def __init__(self, product_id: int):
super().__init__(
message=f"Product '{product_id}' was not found.",
details={
"product_id": product_id,
},
)概念的に類似:
public class ProductNotFoundException : DomainException
{
public int ProductId { get; }
public ProductNotFoundException(int productId)
: base($"Product '{productId}' was not found.")
{
ProductId = productId;
}
}検証エラー
検証エラーは、無効なアプリケーション入力または違反された制約を表します。
例:
Invalid product ID
Quantity must be greater than zero
Missing required input
Invalid cart operationこれらは期待される障害です。
MCP ホストまたは LLM が何を修正する必要があるかを理解するのに十分な構造化情報を提供する必要があります。
インフラストラクチャエラー
インフラストラクチャエラーは、技術的な依存関係を含む障害を表します。
例:
External API unavailable
HTTP timeout
Connection failure
Unexpected downstream response
Database unavailable例えば:
class InfrastructureError(AppError):
error_code = "INFRASTRUCTURE_ERROR"
class ExternalAPIError(InfrastructureError):
error_code = "EXTERNAL_API_ERROR"ドメインはインフラストラクチャの例外に依存してはなりません。
生のライブラリ例外は、アプリケーション全体に漏れてはなりません。
例えば:
httpx.TimeoutException
|
v
ExternalAPITimeoutError
|
v
Application / Presentation代わりに:
httpx.TimeoutException
|
+---------------------> MCP Hostエラー変換
インフラストラクチャは、必要に応じて低レベルの技術的障害を変換する責任があります。
例えば:
HTTP 404 from product provider
|
v
ProductNotFoundError
HTTP timeout
|
v
ExternalAPITimeoutError
HTTP 500
|
v
ExternalAPIErrorこれにより、アプリケーションの残りが特定の HTTP ライブラリに結合されるのを防ぎます。
プレゼンテーションエラー境界
MCP ツールは、重複したエラーハンドリングを含むべきではありません。
避ける:
@mcp.tool
def tool_one():
try:
...
except AppError:
...
@mcp.tool
def tool_two():
try:
...
except AppError:
...
@mcp.tool
def tool_three():
try:
...
except AppError:
...望ましいアーキテクチャは次のとおりです:
MCP Host
|
v
Presentation Error Boundary
|
v
MCP Tool
|
v
Use Case
|
v
Domain / Repository既知のアプリケーションエラーは、構造化された MCP フレンドリーなエラーに変換できます。
予期しない例外は次のようにすべきです:
logged
|
v
converted to generic internal error
|
v
returned without sensitive detailsこれは概念的には ASP.NET Core と似ています:
Python / MCP ASP.NET Core
AppError AppException
DomainError DomainException
InfrastructureError InfrastructureException
central error boundary IExceptionHandler / Middleware
raise throw
except catch構造化エラー
エラーは、有用な場合に構造化情報を含むべきです。
例:
{
"error_code": "PRODUCT_NOT_FOUND",
"error_type": "ProductNotFoundError",
"message": "Product '123' was not found.",
"details": {
"product_id": 123
}
}構造化エラーは以下を改善します:
MCP クライアントの動作
LLM の推論
ロギング
可観測性
自動テスト
デバッグ
エラーハンドリングルール
生のインフラストラクチャ例外を MCP クライアントに直接公開しないでください。
すべての MCP ツールで
try/exceptブロックを複製しないでください。期待されるビジネス障害には特定のドメインエラーを使用してください。
無効な入力と違反された制約には検証エラーを使用してください。
外部の技術的障害をアプリケーション固有のエラーに変換してください。
detailsを通じて有用な構造化コンテキストを保持してください。アプリケーション境界で予期しない例外をログに記録してください。
シークレット、トークン、スタックトレース、または機密のインフラストラクチャ詳細を MCP クライアントに公開しないでください。
エラーコードを安定させ、クライアントと自動テストがそれらに依存できるようにしてください。
プレゼンテーションは、アプリケーションエラーを MCP フレンドリーな応答に変換する責任があります。
依存性注入とコンポジション
依存関係は明示的であるべきです。
例えば:
DummyJsonProductRepository
|
v
GetProductUseCase
|
v
MCP Toolコンポジション/ルート配線は、ドメイン内ではなく、アプリケーションのエントリポイントの近くに属します。
プロジェクトは、実用的な場合に隠れたグローバル依存関係を避けるべきです。
これは、アプリケーションが成長するにつれて段階的に導入されます。
テスト戦略
アーキテクチャは、ビジネス動作を以下なしでテストできるようにする必要があります:
starting FastMCP
calling DummyJSON
opening an HTTP port
running MCP App UI例えば:
Unit Test
|
v
GetProductUseCase
|
v
FakeProductRepositoryこれにより、ユースケースは独立してテスト可能になります。
単体テスト
単体テストは以下に焦点を当てるべきです:
Domain behavior
Use Cases
Validation
Error handlingフェイクまたはモックの依存関係を使用します。
統合テスト
統合テストは、境界を個別に検証できます:
Infrastructure
|
v
DummyJSON APIそして:
MCP Client
|
v
FastMCP Serverこの分離により、外部 API の動作がすべてのビジネステストを信頼性の低いものにすることがなくなります。
開発セットアップ
要件:
Python 3.12+
uv依存関係をインストール/同期:
uv syncMCP サーバーを実行:
uv run python -m presentation.mcp.serverデフォルトエンドポイント:
http://localhost:8000/mcp仮想環境
プロジェクトは以下を使用します:
.venv/分離された Python 依存関係のため。
uv はプロジェクト環境を自動的に管理します。
コマンドは通常、次を使用して実行します:
uv run ...例:
uv run python --versionこれにより、グローバルにインストールされたプロジェクト依存関係に依存することを回避できます。
開発原則
このテンプレートを拡張する場合:
MCP固有のコードはPresentationに保持します。
ビジネスワークフローはApplicationに保持します。
ビジネスモデルと契約は、実用的な範囲でフレームワークから独立させます。
外部統合はInfrastructureに保持します。
具体的なInfrastructure実装ではなく抽象化に依存します。
MCPツールは薄く保ちます。
環境固有の設定をハードコードしないでください。
シークレットをコミットしないでください。
型付きPythonを優先します。
システム境界で外部データを検証します。
外部API DTOは、構造が異なる場合はドメインモデルとは別に保持します。
ユースケースを独立してテスト可能にします。
隠れたグローバル状態よりも明示的な依存関係を優先します。
実際のアーキテクチャ上の問題を解決する場合に抽象化を追加します。
ドメインをFastMCPから独立させます。
インフラストラクチャの障害は、境界外に公開する前に変換します。
安定した構造化エラーコードを使用します。
MCPアプリのUIはプレゼンテーションとインタラクションに焦点を当てます。
MCPデコレータ内にビジネスロジックを置かないでください。
外部APIを置き換え可能に保ちます。
計画された学習フロー
テンプレートは段階的に構築されています。
FastMCP Server
|
v
HTTP Transport
|
v
Environment Configuration
|
v
Python Package Structure
|
v
Pydantic Models
|
v
Domain Entities
|
v
Repository Contracts
|
v
Error Hierarchy
|
v
Infrastructure / External API
|
v
Application Use Cases
|
v
MCP Tools
|
v
Dependency Composition
|
v
Centralized Error Handling
|
v
MCP Resources
|
v
MCP Prompts
|
v
MCP App UI
|
v
Interactive MCP Actions
|
v
Unit Tests
|
v
Integration Tests
|
v
Claude / Copilot integration最終目標
最終プロジェクトは完全なフローを示す必要があります:
Claude / Copilot
|
| MCP over HTTP
v
FastMCP Server
|
v
MCP App UI
|
| user action
v
MCP Tool
|
v
Application Use Case
|
v
Domain Contract
|
v
Infrastructure Adapter
|
| HTTP
v
External Serviceエラーが安全に逆方向に流れるようにします:
External failure
|
v
Infrastructure Error
|
v
Application / Domain Error
|
v
Presentation Error Boundary
|
v
Structured MCP Error
|
v
Claude / Copilot目的
このリポジトリは、クリーンアーキテクチャを使用して本番品質のFastMCPサーバーとMCPアプリを作成するための再利用可能なテンプレートおよび学習リファレンスとなることを目的としています。
このプロジェクトは、MCP固有の関心事がコードベース全体に広がるのを許すのではなく、MCPをアプリケーション境界として扱う方法を示しています。
コアビジネスロジックは以下から独立している必要があります:
FastMCP
MCP transport
MCP App UI
Claude
Copilot
HTTP providers
databases
external APIsこれにより、アプリケーションは以下のことが容易になります:
maintain
test
extend
replace integrations
run in different environments
connect to different MCP hosts明確なアーキテクチャ境界を維持しながら。
This server cannot be deployed
Maintenance
Related MCP Connectors
FastMCP commerce server starter: product catalog, search, and checkout. Deploy to Vercel in 5 min.
Unified MCP server for 70+ eCommerce platforms: products, orders, customers, and more.
- MaShop MCPOAuthapp.mashop
Build, deploy and manage MaShop e-commerce projects from Claude, Cursor or any MCP client.
Hosted MCP for e-commerce: live product catalog, stock, and pricing for AI agents.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceA Model Context Protocol server that enables AI assistants to interact with a complete e-commerce application, providing authentication, product browsing, and shopping cart management through standardized MCP tools.-

NitroStackofficial
FlicenseNot gradedqualityBmaintenanceA Python framework for building MCP servers with modular architecture, dependency injection, and built-in authentication. Enables creating scalable, testable MCP services with features like pipeline interceptors and background tasks.4-- AlicenseNot gradedqualityDmaintenanceA production-ready template for developing Model Context Protocol (MCP) servers using Python and FastMCP.Apache 2.0
- FlicenseNot gradedqualityDmaintenanceThis enterprise MCP server template provides a production-ready, architecture-first foundation for building MCP servers in Python, with capability registry, dependency injection, and Docker support.-