traia-iatp 0.1.29__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of traia-iatp might be problematic. Click here for more details.
- traia_iatp/README.md +368 -0
- traia_iatp/__init__.py +54 -0
- traia_iatp/cli/__init__.py +5 -0
- traia_iatp/cli/main.py +483 -0
- traia_iatp/client/__init__.py +10 -0
- traia_iatp/client/a2a_client.py +274 -0
- traia_iatp/client/crewai_a2a_tools.py +335 -0
- traia_iatp/client/d402_a2a_client.py +293 -0
- traia_iatp/client/grpc_a2a_tools.py +349 -0
- traia_iatp/client/root_path_a2a_client.py +1 -0
- traia_iatp/contracts/__init__.py +12 -0
- traia_iatp/contracts/iatp_contracts_config.py +263 -0
- traia_iatp/contracts/wallet_creator.py +255 -0
- traia_iatp/core/__init__.py +43 -0
- traia_iatp/core/models.py +172 -0
- traia_iatp/d402/__init__.py +55 -0
- traia_iatp/d402/chains.py +102 -0
- traia_iatp/d402/client.py +150 -0
- traia_iatp/d402/clients/__init__.py +7 -0
- traia_iatp/d402/clients/base.py +218 -0
- traia_iatp/d402/clients/httpx.py +219 -0
- traia_iatp/d402/common.py +114 -0
- traia_iatp/d402/encoding.py +28 -0
- traia_iatp/d402/examples/client_example.py +197 -0
- traia_iatp/d402/examples/server_example.py +171 -0
- traia_iatp/d402/facilitator.py +453 -0
- traia_iatp/d402/fastapi_middleware/__init__.py +6 -0
- traia_iatp/d402/fastapi_middleware/middleware.py +225 -0
- traia_iatp/d402/fastmcp_middleware.py +147 -0
- traia_iatp/d402/mcp_middleware.py +434 -0
- traia_iatp/d402/middleware.py +193 -0
- traia_iatp/d402/models.py +116 -0
- traia_iatp/d402/networks.py +98 -0
- traia_iatp/d402/path.py +43 -0
- traia_iatp/d402/payment_introspection.py +104 -0
- traia_iatp/d402/payment_signing.py +178 -0
- traia_iatp/d402/paywall.py +119 -0
- traia_iatp/d402/starlette_middleware.py +326 -0
- traia_iatp/d402/template.py +1 -0
- traia_iatp/d402/types.py +300 -0
- traia_iatp/mcp/__init__.py +18 -0
- traia_iatp/mcp/client.py +201 -0
- traia_iatp/mcp/d402_mcp_tool_adapter.py +361 -0
- traia_iatp/mcp/mcp_agent_template.py +481 -0
- traia_iatp/mcp/templates/Dockerfile.j2 +80 -0
- traia_iatp/mcp/templates/README.md.j2 +310 -0
- traia_iatp/mcp/templates/cursor-rules.md.j2 +520 -0
- traia_iatp/mcp/templates/deployment_params.json.j2 +20 -0
- traia_iatp/mcp/templates/docker-compose.yml.j2 +32 -0
- traia_iatp/mcp/templates/dockerignore.j2 +47 -0
- traia_iatp/mcp/templates/env.example.j2 +57 -0
- traia_iatp/mcp/templates/gitignore.j2 +77 -0
- traia_iatp/mcp/templates/mcp_health_check.py.j2 +150 -0
- traia_iatp/mcp/templates/pyproject.toml.j2 +32 -0
- traia_iatp/mcp/templates/pyrightconfig.json.j2 +22 -0
- traia_iatp/mcp/templates/run_local_docker.sh.j2 +390 -0
- traia_iatp/mcp/templates/server.py.j2 +175 -0
- traia_iatp/mcp/traia_mcp_adapter.py +543 -0
- traia_iatp/preview_diagrams.html +181 -0
- traia_iatp/registry/__init__.py +26 -0
- traia_iatp/registry/atlas_search_indexes.json +280 -0
- traia_iatp/registry/embeddings.py +298 -0
- traia_iatp/registry/iatp_search_api.py +846 -0
- traia_iatp/registry/mongodb_registry.py +771 -0
- traia_iatp/registry/readmes/ATLAS_SEARCH_INDEXES.md +252 -0
- traia_iatp/registry/readmes/ATLAS_SEARCH_SETUP.md +134 -0
- traia_iatp/registry/readmes/AUTHENTICATION_UPDATE.md +124 -0
- traia_iatp/registry/readmes/EMBEDDINGS_SETUP.md +172 -0
- traia_iatp/registry/readmes/IATP_SEARCH_API_GUIDE.md +257 -0
- traia_iatp/registry/readmes/MONGODB_X509_AUTH.md +208 -0
- traia_iatp/registry/readmes/README.md +251 -0
- traia_iatp/registry/readmes/REFACTORING_SUMMARY.md +191 -0
- traia_iatp/scripts/__init__.py +2 -0
- traia_iatp/scripts/create_wallet.py +244 -0
- traia_iatp/server/__init__.py +15 -0
- traia_iatp/server/a2a_server.py +219 -0
- traia_iatp/server/example_template_usage.py +72 -0
- traia_iatp/server/iatp_server_agent_generator.py +237 -0
- traia_iatp/server/iatp_server_template_generator.py +235 -0
- traia_iatp/server/templates/.dockerignore.j2 +48 -0
- traia_iatp/server/templates/Dockerfile.j2 +49 -0
- traia_iatp/server/templates/README.md +137 -0
- traia_iatp/server/templates/README.md.j2 +425 -0
- traia_iatp/server/templates/__init__.py +1 -0
- traia_iatp/server/templates/__main__.py.j2 +565 -0
- traia_iatp/server/templates/agent.py.j2 +94 -0
- traia_iatp/server/templates/agent_config.json.j2 +22 -0
- traia_iatp/server/templates/agent_executor.py.j2 +279 -0
- traia_iatp/server/templates/docker-compose.yml.j2 +23 -0
- traia_iatp/server/templates/env.example.j2 +84 -0
- traia_iatp/server/templates/gitignore.j2 +78 -0
- traia_iatp/server/templates/grpc_server.py.j2 +218 -0
- traia_iatp/server/templates/pyproject.toml.j2 +78 -0
- traia_iatp/server/templates/run_local_docker.sh.j2 +103 -0
- traia_iatp/server/templates/server.py.j2 +243 -0
- traia_iatp/special_agencies/__init__.py +4 -0
- traia_iatp/special_agencies/registry_search_agency.py +392 -0
- traia_iatp/utils/__init__.py +10 -0
- traia_iatp/utils/docker_utils.py +251 -0
- traia_iatp/utils/general.py +64 -0
- traia_iatp/utils/iatp_utils.py +126 -0
- traia_iatp-0.1.29.dist-info/METADATA +423 -0
- traia_iatp-0.1.29.dist-info/RECORD +107 -0
- traia_iatp-0.1.29.dist-info/WHEEL +5 -0
- traia_iatp-0.1.29.dist-info/entry_points.txt +2 -0
- traia_iatp-0.1.29.dist-info/licenses/LICENSE +21 -0
- traia_iatp-0.1.29.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
{{ api_name }} MCP Server - FastMCP with D402 Transport Wrapper
|
|
4
|
+
|
|
5
|
+
Uses FastMCP from official MCP SDK with D402MCPTransport wrapper for HTTP 402.
|
|
6
|
+
|
|
7
|
+
Architecture:
|
|
8
|
+
- FastMCP for tool decorators and Context objects
|
|
9
|
+
- D402MCPTransport wraps the /mcp route for HTTP 402 interception
|
|
10
|
+
- Proper HTTP 402 status codes (not JSON-RPC wrapped)
|
|
11
|
+
|
|
12
|
+
Generated from OpenAPI: {{ docs_url }}
|
|
13
|
+
|
|
14
|
+
Environment Variables:
|
|
15
|
+
{% if requires_auth %}- {{ api_key_env_var }}: Server's internal API key (for paid requests)
|
|
16
|
+
{% endif %}- SERVER_ADDRESS: Payment address (IATP wallet contract)
|
|
17
|
+
- MCP_OPERATOR_PRIVATE_KEY: Operator signing key
|
|
18
|
+
- D402_TESTING_MODE: Skip facilitator (default: true)
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
import os
|
|
22
|
+
import logging
|
|
23
|
+
import sys
|
|
24
|
+
from typing import Dict, Any, Optional
|
|
25
|
+
from datetime import datetime
|
|
26
|
+
|
|
27
|
+
import requests
|
|
28
|
+
from retry import retry
|
|
29
|
+
from dotenv import load_dotenv
|
|
30
|
+
import uvicorn
|
|
31
|
+
|
|
32
|
+
load_dotenv()
|
|
33
|
+
|
|
34
|
+
# Configure logging
|
|
35
|
+
logging.basicConfig(
|
|
36
|
+
level=os.getenv("LOG_LEVEL", "INFO").upper(),
|
|
37
|
+
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
|
|
38
|
+
)
|
|
39
|
+
logger = logging.getLogger('{{ api_slug }}_mcp')
|
|
40
|
+
|
|
41
|
+
# FastMCP from official SDK
|
|
42
|
+
from mcp.server.fastmcp import FastMCP, Context
|
|
43
|
+
from starlette.requests import Request
|
|
44
|
+
from starlette.responses import JSONResponse
|
|
45
|
+
|
|
46
|
+
# D402 payment protocol - using Starlette middleware
|
|
47
|
+
from traia_iatp.d402.starlette_middleware import D402PaymentMiddleware
|
|
48
|
+
from traia_iatp.d402.mcp_middleware import require_payment_for_tool, get_active_api_key
|
|
49
|
+
from traia_iatp.d402.payment_introspection import extract_payment_configs_from_mcp
|
|
50
|
+
from traia_iatp.d402.types import TokenAmount, TokenAsset, EIP712Domain
|
|
51
|
+
|
|
52
|
+
# Configuration
|
|
53
|
+
STAGE = os.getenv("STAGE", "MAINNET").upper()
|
|
54
|
+
PORT = int(os.getenv("PORT", "8000"))
|
|
55
|
+
SERVER_ADDRESS = os.getenv("SERVER_ADDRESS")
|
|
56
|
+
if not SERVER_ADDRESS:
|
|
57
|
+
raise ValueError("SERVER_ADDRESS required for payment protocol")
|
|
58
|
+
|
|
59
|
+
{% if requires_auth %}
|
|
60
|
+
API_KEY = os.getenv("{{ api_key_env_var }}")
|
|
61
|
+
if not API_KEY:
|
|
62
|
+
logger.warning(f"⚠️ {{ api_key_env_var }} not set - payment required for all requests")
|
|
63
|
+
{% else %}
|
|
64
|
+
API_KEY = None
|
|
65
|
+
{% endif %}
|
|
66
|
+
|
|
67
|
+
logger.info("="*80)
|
|
68
|
+
logger.info(f"{{ api_name }} MCP Server (FastMCP + D402 Wrapper)")
|
|
69
|
+
logger.info(f"API: {{ api_url }}")
|
|
70
|
+
logger.info(f"Payment: {SERVER_ADDRESS}")
|
|
71
|
+
{% if requires_auth %}
|
|
72
|
+
logger.info(f"API Key: {'✅' if API_KEY else '❌ Payment required'}")
|
|
73
|
+
{% endif %}
|
|
74
|
+
logger.info("="*80)
|
|
75
|
+
|
|
76
|
+
# Create FastMCP server
|
|
77
|
+
mcp = FastMCP("{{ api_name }} MCP Server")
|
|
78
|
+
|
|
79
|
+
logger.info(f"✅ FastMCP server created")
|
|
80
|
+
|
|
81
|
+
# ============================================================================
|
|
82
|
+
# TOOL IMPLEMENTATIONS
|
|
83
|
+
# ============================================================================
|
|
84
|
+
# Tool implementations will be added here by endpoint_implementer_crew
|
|
85
|
+
# Each tool will use the @mcp.tool() and @require_payment_for_tool() decorators
|
|
86
|
+
# TODO: Add your API-specific functions here
|
|
87
|
+
|
|
88
|
+
# ============================================================================
|
|
89
|
+
# APPLICATION SETUP WITH STARLETTE MIDDLEWARE
|
|
90
|
+
# ============================================================================
|
|
91
|
+
|
|
92
|
+
def create_app_with_middleware():
|
|
93
|
+
"""
|
|
94
|
+
Create Starlette app with d402 payment middleware.
|
|
95
|
+
|
|
96
|
+
Strategy:
|
|
97
|
+
1. Get FastMCP's Starlette app via streamable_http_app()
|
|
98
|
+
2. Extract payment configs from @require_payment_for_tool decorators
|
|
99
|
+
3. Add Starlette middleware with extracted configs
|
|
100
|
+
4. Single source of truth - no duplication!
|
|
101
|
+
"""
|
|
102
|
+
logger.info("🔧 Creating FastMCP app with middleware...")
|
|
103
|
+
|
|
104
|
+
# Get FastMCP's Starlette app
|
|
105
|
+
app = mcp.streamable_http_app()
|
|
106
|
+
logger.info(f"✅ Got FastMCP Starlette app")
|
|
107
|
+
|
|
108
|
+
# Extract payment configs from decorators (single source of truth!)
|
|
109
|
+
tool_payment_configs = extract_payment_configs_from_mcp(mcp, SERVER_ADDRESS)
|
|
110
|
+
logger.info(f"📊 Extracted {len(tool_payment_configs)} payment configs from @require_payment_for_tool decorators")
|
|
111
|
+
|
|
112
|
+
# Add D402 payment middleware with extracted configs
|
|
113
|
+
app.add_middleware(
|
|
114
|
+
D402PaymentMiddleware,
|
|
115
|
+
tool_payment_configs=tool_payment_configs,
|
|
116
|
+
server_address=SERVER_ADDRESS,
|
|
117
|
+
{% if requires_auth %}
|
|
118
|
+
requires_auth=True, # Extracts API keys + checks payment
|
|
119
|
+
internal_api_key=API_KEY, # Server's internal key (for Mode 2: paid access)
|
|
120
|
+
{% else %}
|
|
121
|
+
requires_auth=False, # Only checks payment
|
|
122
|
+
{% endif %}
|
|
123
|
+
testing_mode=os.getenv("D402_TESTING_MODE", "true").lower() == "true",
|
|
124
|
+
facilitator_url=os.getenv("D402_FACILITATOR_URL"),
|
|
125
|
+
facilitator_api_key=os.getenv("D402_FACILITATOR_API_KEY")
|
|
126
|
+
)
|
|
127
|
+
logger.info("✅ Added D402PaymentMiddleware")
|
|
128
|
+
{% if requires_auth %}
|
|
129
|
+
logger.info(" - Auth extraction: Enabled")
|
|
130
|
+
logger.info(" - Dual mode: API key OR payment")
|
|
131
|
+
{% else %}
|
|
132
|
+
logger.info(" - Payment-only mode")
|
|
133
|
+
{% endif %}
|
|
134
|
+
|
|
135
|
+
# Add health check endpoint (bypasses middleware)
|
|
136
|
+
@app.route("/health", methods=["GET"])
|
|
137
|
+
async def health_check(request: Request) -> JSONResponse:
|
|
138
|
+
"""Health check endpoint for container orchestration."""
|
|
139
|
+
return JSONResponse(
|
|
140
|
+
content={
|
|
141
|
+
"status": "healthy",
|
|
142
|
+
"service": "{{ api_slug }}-mcp-server",
|
|
143
|
+
"timestamp": datetime.now().isoformat()
|
|
144
|
+
}
|
|
145
|
+
)
|
|
146
|
+
logger.info("✅ Added /health endpoint")
|
|
147
|
+
|
|
148
|
+
return app
|
|
149
|
+
|
|
150
|
+
if __name__ == "__main__":
|
|
151
|
+
logger.info("="*80)
|
|
152
|
+
logger.info(f"Starting {{ api_name }} MCP Server")
|
|
153
|
+
logger.info("="*80)
|
|
154
|
+
logger.info("Architecture:")
|
|
155
|
+
logger.info(" 1. D402PaymentMiddleware intercepts requests")
|
|
156
|
+
{% if requires_auth %}
|
|
157
|
+
logger.info(" - Extracts API keys from Authorization header")
|
|
158
|
+
logger.info(" - Checks payment → HTTP 402 if no API key AND no payment")
|
|
159
|
+
{% else %}
|
|
160
|
+
logger.info(" - Checks payment → HTTP 402 if missing")
|
|
161
|
+
{% endif %}
|
|
162
|
+
logger.info(" 2. FastMCP processes valid requests with tool decorators")
|
|
163
|
+
logger.info("="*80)
|
|
164
|
+
|
|
165
|
+
# Create app with middleware
|
|
166
|
+
app = create_app_with_middleware()
|
|
167
|
+
|
|
168
|
+
# Run with uvicorn
|
|
169
|
+
uvicorn.run(
|
|
170
|
+
app,
|
|
171
|
+
host="0.0.0.0",
|
|
172
|
+
port=PORT,
|
|
173
|
+
log_level=os.getenv("LOG_LEVEL", "info").lower()
|
|
174
|
+
)
|
|
175
|
+
|