traia-iatp 0.1.2__py3-none-any.whl → 0.1.67__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.
Files changed (95) hide show
  1. traia_iatp/__init__.py +105 -8
  2. traia_iatp/cli/main.py +85 -1
  3. traia_iatp/client/__init__.py +28 -3
  4. traia_iatp/client/crewai_a2a_tools.py +32 -12
  5. traia_iatp/client/d402_a2a_client.py +348 -0
  6. traia_iatp/contracts/__init__.py +11 -0
  7. traia_iatp/contracts/data/abis/contract-abis-localhost.json +4091 -0
  8. traia_iatp/contracts/data/abis/contract-abis-sepolia.json +4890 -0
  9. traia_iatp/contracts/data/addresses/contract-addresses.json +17 -0
  10. traia_iatp/contracts/data/addresses/contract-proxies.json +12 -0
  11. traia_iatp/contracts/iatp_contracts_config.py +263 -0
  12. traia_iatp/contracts/wallet_creator.py +369 -0
  13. traia_iatp/core/models.py +17 -3
  14. traia_iatp/d402/MIDDLEWARE_ARCHITECTURE.md +205 -0
  15. traia_iatp/d402/PRICE_BUILDER_USAGE.md +249 -0
  16. traia_iatp/d402/README.md +489 -0
  17. traia_iatp/d402/__init__.py +54 -0
  18. traia_iatp/d402/asgi_wrapper.py +469 -0
  19. traia_iatp/d402/chains.py +102 -0
  20. traia_iatp/d402/client.py +150 -0
  21. traia_iatp/d402/clients/__init__.py +7 -0
  22. traia_iatp/d402/clients/base.py +218 -0
  23. traia_iatp/d402/clients/httpx.py +266 -0
  24. traia_iatp/d402/common.py +114 -0
  25. traia_iatp/d402/encoding.py +28 -0
  26. traia_iatp/d402/examples/client_example.py +197 -0
  27. traia_iatp/d402/examples/server_example.py +171 -0
  28. traia_iatp/d402/facilitator.py +481 -0
  29. traia_iatp/d402/mcp_middleware.py +296 -0
  30. traia_iatp/d402/models.py +116 -0
  31. traia_iatp/d402/networks.py +98 -0
  32. traia_iatp/d402/path.py +43 -0
  33. traia_iatp/d402/payment_introspection.py +126 -0
  34. traia_iatp/d402/payment_signing.py +183 -0
  35. traia_iatp/d402/price_builder.py +164 -0
  36. traia_iatp/d402/servers/__init__.py +61 -0
  37. traia_iatp/d402/servers/base.py +139 -0
  38. traia_iatp/d402/servers/example_general_server.py +140 -0
  39. traia_iatp/d402/servers/fastapi.py +253 -0
  40. traia_iatp/d402/servers/mcp.py +304 -0
  41. traia_iatp/d402/servers/starlette.py +878 -0
  42. traia_iatp/d402/starlette_middleware.py +529 -0
  43. traia_iatp/d402/types.py +300 -0
  44. traia_iatp/mcp/D402_MCP_ADAPTER_FLOW.md +357 -0
  45. traia_iatp/mcp/__init__.py +3 -0
  46. traia_iatp/mcp/d402_mcp_tool_adapter.py +526 -0
  47. traia_iatp/mcp/mcp_agent_template.py +78 -13
  48. traia_iatp/mcp/templates/Dockerfile.j2 +27 -4
  49. traia_iatp/mcp/templates/README.md.j2 +104 -8
  50. traia_iatp/mcp/templates/cursor-rules.md.j2 +194 -0
  51. traia_iatp/mcp/templates/deployment_params.json.j2 +1 -2
  52. traia_iatp/mcp/templates/docker-compose.yml.j2 +13 -3
  53. traia_iatp/mcp/templates/env.example.j2 +60 -0
  54. traia_iatp/mcp/templates/mcp_health_check.py.j2 +2 -2
  55. traia_iatp/mcp/templates/pyproject.toml.j2 +11 -5
  56. traia_iatp/mcp/templates/pyrightconfig.json.j2 +22 -0
  57. traia_iatp/mcp/templates/run_local_docker.sh.j2 +320 -10
  58. traia_iatp/mcp/templates/server.py.j2 +174 -197
  59. traia_iatp/mcp/traia_mcp_adapter.py +182 -20
  60. traia_iatp/registry/__init__.py +47 -12
  61. traia_iatp/registry/atlas_search_indexes.json +108 -54
  62. traia_iatp/registry/iatp_search_api.py +169 -39
  63. traia_iatp/registry/mongodb_registry.py +241 -69
  64. traia_iatp/registry/readmes/EMBEDDINGS_SETUP.md +1 -1
  65. traia_iatp/registry/readmes/IATP_SEARCH_API_GUIDE.md +8 -8
  66. traia_iatp/registry/readmes/MONGODB_X509_AUTH.md +1 -1
  67. traia_iatp/registry/readmes/README.md +3 -3
  68. traia_iatp/registry/readmes/REFACTORING_SUMMARY.md +6 -6
  69. traia_iatp/scripts/__init__.py +2 -0
  70. traia_iatp/scripts/create_wallet.py +244 -0
  71. traia_iatp/server/a2a_server.py +22 -7
  72. traia_iatp/server/iatp_server_template_generator.py +23 -0
  73. traia_iatp/server/templates/.dockerignore.j2 +48 -0
  74. traia_iatp/server/templates/Dockerfile.j2 +23 -1
  75. traia_iatp/server/templates/README.md +2 -2
  76. traia_iatp/server/templates/README.md.j2 +5 -5
  77. traia_iatp/server/templates/__main__.py.j2 +374 -66
  78. traia_iatp/server/templates/agent.py.j2 +12 -11
  79. traia_iatp/server/templates/agent_config.json.j2 +3 -3
  80. traia_iatp/server/templates/agent_executor.py.j2 +45 -27
  81. traia_iatp/server/templates/env.example.j2 +32 -4
  82. traia_iatp/server/templates/gitignore.j2 +7 -0
  83. traia_iatp/server/templates/pyproject.toml.j2 +13 -12
  84. traia_iatp/server/templates/run_local_docker.sh.j2 +143 -11
  85. traia_iatp/server/templates/server.py.j2 +197 -10
  86. traia_iatp/special_agencies/registry_search_agency.py +1 -1
  87. traia_iatp/utils/iatp_utils.py +6 -6
  88. traia_iatp-0.1.67.dist-info/METADATA +320 -0
  89. traia_iatp-0.1.67.dist-info/RECORD +117 -0
  90. traia_iatp-0.1.2.dist-info/METADATA +0 -414
  91. traia_iatp-0.1.2.dist-info/RECORD +0 -72
  92. {traia_iatp-0.1.2.dist-info → traia_iatp-0.1.67.dist-info}/WHEEL +0 -0
  93. {traia_iatp-0.1.2.dist-info → traia_iatp-0.1.67.dist-info}/entry_points.txt +0 -0
  94. {traia_iatp-0.1.2.dist-info → traia_iatp-0.1.67.dist-info}/licenses/LICENSE +0 -0
  95. {traia_iatp-0.1.2.dist-info → traia_iatp-0.1.67.dist-info}/top_level.txt +0 -0
@@ -25,7 +25,31 @@ USER appuser
25
25
  # Copy project files
26
26
  COPY --chown=appuser:appuser . .
27
27
 
28
+ # Copy IATP package if available (for local development only)
29
+ # This Dockerfile works for both local and remote deployments:
30
+ #
31
+ # LOCAL DEPLOYMENT (via run_local_docker.sh):
32
+ # - run_local_docker.sh detects local IATP path in pyproject.toml
33
+ # - Copies IATP to .docker-iatp/IATP before building
34
+ # - Temporarily modifies pyproject.toml to use file:///tmp/IATP
35
+ # - Dockerfile finds .docker-iatp/IATP and copies it to /tmp/IATP
36
+ # - uv install uses the local IATP from /tmp/IATP
37
+ #
38
+ # REMOTE DEPLOYMENT (Cloud Run, etc.):
39
+ # - .docker-iatp/IATP does NOT exist in build context
40
+ # - pyproject.toml has published version (traia-iatp>=0.1.27)
41
+ # - Dockerfile skips IATP copy, uv install uses published package
42
+ #
43
+ RUN if [ -d .docker-iatp/IATP ]; then \
44
+ cp -r .docker-iatp/IATP /tmp/IATP && \
45
+ echo "Using local IATP package (local development mode)"; \
46
+ else \
47
+ echo "Using published IATP package (remote deployment mode)"; \
48
+ fi
49
+
28
50
  # Install Python dependencies
51
+ # - Local mode: pyproject.toml references file:///tmp/IATP (set by run_local_docker.sh)
52
+ # - Remote mode: pyproject.toml references traia-iatp>=0.1.27 (from template)
29
53
  RUN uv venv .venv && \
30
54
  uv pip install -r pyproject.toml
31
55
 
@@ -36,7 +60,6 @@ ENV HOST=0.0.0.0
36
60
  ENV PYTHONUNBUFFERED=1
37
61
  ENV UV_SYSTEM_PYTHON=1
38
62
  ENV STAGE=MAINNET
39
- ENV PORT=8000
40
63
  ENV LOG_LEVEL=INFO
41
64
  {% if environment_variables %}
42
65
  # Additional environment variables
@@ -45,12 +68,12 @@ ENV {{ env_var.name }}="{{ env_var.value }}"
45
68
  {% endfor %}
46
69
  {% endif %}
47
70
 
48
- # Health check
71
+ # Health check - uses dedicated health endpoint
49
72
  HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
50
- CMD curl -f http://localhost:${PORT:-8000}/health || exit 1
73
+ CMD curl -f http://localhost:${PORT:-8080}/health || exit 1
51
74
 
52
75
  # Expose port (uses PORT environment variable with default)
53
- EXPOSE ${PORT:-8000}
76
+ EXPOSE ${PORT:-8080}
54
77
 
55
78
  # Run the application
56
79
  CMD ["uv", "run", "python", "server.py"]
@@ -8,6 +8,8 @@ This is an MCP (Model Context Protocol) server that provides{{ auth_details }} a
8
8
  - 🌐 **Full API Access**: Provides tools for interacting with {{ api_name }} endpoints
9
9
  {% if requires_auth %}
10
10
  - 🔐 **Secure Authentication**: Supports API key authentication via Bearer tokens
11
+ - 💳 **HTTP 402 Payment Protocol**: Dual-mode operation (authenticated or paid access)
12
+ - 🔗 **D402 Integration**: Uses traia_iatp.d402 for blockchain payment verification
11
13
  {% endif %}
12
14
  - 🐳 **Docker Support**: Easy deployment with Docker and Docker Compose
13
15
  - ⚡ **Async Operations**: Built with FastMCP for efficient async handling
@@ -22,7 +24,6 @@ This is an MCP (Model Context Protocol) server that provides{{ auth_details }} a
22
24
  This server provides the following tools:
23
25
 
24
26
  - **`example_tool`**: Placeholder tool (to be implemented)
25
- - **`get_api_info`**: Get information about the API service and authentication status
26
27
 
27
28
  *Note: Replace `example_tool` with actual {{ api_name }} API tools based on the documentation.*
28
29
 
@@ -54,7 +55,18 @@ This server provides the following tools:
54
55
 
55
56
  1. Create a `.env` file with your configuration:
56
57
  ```env
57
- {% if requires_auth %}{{ api_key_env_var }}=your-api-key-here
58
+ {% if requires_auth %}# Server's internal API key (for payment mode)
59
+ {{ api_key_env_var }}=your-api-key-here
60
+
61
+ # Server payment address (for HTTP 402 protocol)
62
+ SERVER_ADDRESS=0x1234567890123456789012345678901234567890
63
+
64
+ # Operator keys (for signing settlement attestations)
65
+ MCP_OPERATOR_PRIVATE_KEY=0x1234567890abcdef...
66
+ MCP_OPERATOR_ADDRESS=0x9876543210fedcba...
67
+
68
+ # Optional: Testing mode (skip settlement for local dev)
69
+ D402_TESTING_MODE=false
58
70
  {% endif %}PORT=8000
59
71
  ```
60
72
 
@@ -118,15 +130,100 @@ with create_mcp_adapter(
118
130
  ```
119
131
 
120
132
  {% if requires_auth %}
121
- ## Authentication
133
+ ## Authentication & Payment (HTTP 402 Protocol)
122
134
 
123
- This server requires API key authentication. Clients must provide their API key in the `Authorization` header:
135
+ This server supports **two modes of operation**:
124
136
 
137
+ ### Mode 1: Authenticated Access (Free)
138
+
139
+ Clients with their own {{ api_name }} API key can use the server for free:
140
+
141
+ ```bash
142
+ # Request with client's API key
143
+ curl -X POST http://localhost:8000/mcp \
144
+ -H "Authorization: Bearer CLIENT_{{ api_key_env_var }}" \
145
+ -H "Content-Type: application/json" \
146
+ -d '{"method":"tools/call","params":{"name":"example_tool","arguments":{"query":"test"}}}'
125
147
  ```
126
- Authorization: Bearer YOUR_API_KEY
148
+
149
+ **Flow**:
150
+ 1. Client provides their {{ api_name }} API key
151
+ 2. Server uses client's API key to call {{ api_name }} API
152
+ 3. No payment required
153
+ 4. Client pays {{ api_name }} directly
154
+
155
+ ### Mode 2: Payment Required (Paid Access)
156
+
157
+ Clients without an API key can pay-per-use via HTTP 402 protocol:
158
+
159
+ ```bash
160
+ # Request with payment proof (x402/d402 protocol)
161
+ curl -X POST http://localhost:8000/mcp \
162
+ -H "X-PAYMENT: <base64_encoded_x402_payment>" \
163
+ -H "Content-Type: application/json" \
164
+ -d '{"method":"tools/call","params":{"name":"example_tool","arguments":{"query":"test"}}}'
165
+ ```
166
+
167
+ **Flow**:
168
+ 1. Client makes initial request without payment
169
+ 2. Server returns HTTP 402 with PaymentRequirements (token, network, amount)
170
+ 3. Client creates EIP-3009 transferWithAuthorization payment signature
171
+ 4. Client base64-encodes payment and sends in X-PAYMENT header
172
+ 5. Server verifies payment via traia_iatp.d402.mcp_middleware
173
+ 6. Server uses its INTERNAL {{ api_name }} API key to call the API
174
+ 7. Client receives result
175
+
176
+ ### D402 Protocol Details
177
+
178
+ This server uses the **traia_iatp.d402** module for payment verification:
179
+
180
+ - **Payment Method**: EIP-3009 transferWithAuthorization (gasless)
181
+ - **Supported Tokens**: USDC, TRAIA, or any ERC20 token
182
+ - **Default Price**: $0.001 per request (configurable via `DEFAULT_PRICE_USD`)
183
+ - **Networks**: Base Sepolia, Sepolia, Polygon, etc.
184
+ - **Facilitator**: d402.org (public) or custom facilitator
185
+
186
+ ### Environment Variables for Payment Mode
187
+
188
+ ```bash
189
+ # Required
190
+ {{ api_key_env_var }}=your_internal_{{ api_slug }}_api_key # Server's API key (for payment mode)
191
+ SERVER_ADDRESS=0x1234567890123456789012345678901234567890 # Server's payment address
192
+
193
+ # Required for Settlement (Production)
194
+ MCP_OPERATOR_PRIVATE_KEY=0x1234... # Private key for signing settlement attestations
195
+ MCP_OPERATOR_ADDRESS=0x5678... # Operator's public address (for verification)
196
+
197
+ # Optional
198
+ D402_FACILITATOR_URL=https://facilitator.d402.net # Facilitator service URL
199
+ D402_FACILITATOR_API_KEY=your_key # For private facilitator
200
+ D402_TESTING_MODE=false # Set to 'true' for local testing without settlement
127
201
  ```
128
202
 
129
- The API key is then used to authenticate requests to the {{ api_name }} API.
203
+ **Operator Keys**:
204
+ - **MCP_OPERATOR_PRIVATE_KEY**: Used to sign settlement attestations (proof of service completion)
205
+ - **MCP_OPERATOR_ADDRESS**: Public address corresponding to the private key
206
+ - Required for on-chain settlement via IATP Settlement Layer
207
+ - Can be the same as SERVER_ADDRESS or a separate operator key
208
+
209
+ **Note on Per-Endpoint Configuration**:
210
+ Each endpoint's payment requirements (token address, network, price) are embedded in the tool code.
211
+ They come from the endpoint configuration when the server is generated.
212
+
213
+ ### How It Works
214
+
215
+ 1. **Client Decision**:
216
+ - Has {{ api_name }} API key? → Mode 1 (Authenticated)
217
+ - No API key but willing to pay? → Mode 2 (Payment)
218
+
219
+ 2. **Server Response**:
220
+ - Mode 1: Uses client's API key (free for client)
221
+ - Mode 2: Uses server's API key (client pays server)
222
+
223
+ 3. **Business Model**:
224
+ - Mode 1: No revenue (passthrough)
225
+ - Mode 2: Revenue from pay-per-use (monetize server's API subscription)
226
+
130
227
  {% endif %}
131
228
 
132
229
  ## Development
@@ -163,8 +260,7 @@ The `deployment_params.json` file contains the deployment configuration for this
163
260
  "api_key_header": "Authorization",
164
261
  {% endif %}"capabilities": [
165
262
  // List all implemented tool names here
166
- "example_tool",
167
- "get_api_info"
263
+ "example_tool"
168
264
  ]
169
265
  },
170
266
  "deployment_method": "cloud_run",
@@ -12,6 +12,200 @@ You are working on implementing the {{ api_name }} MCP (Model Context Protocol)
12
12
  {% endif %}
13
13
  - **Authentication**: {% if requires_auth %}Required - API key via `{{ api_key_env_var }}` environment variable{% else %}Not required{% endif %}
14
14
 
15
+ {% if requires_auth %}
16
+ ## 🔒 HTTP 402 Payment Protocol - Dual-Mode Operation
17
+
18
+ This MCP server implements the **HTTP 402 Payment Required** protocol using the **traia_iatp.d402** module with dual-mode support:
19
+
20
+ ### Mode 1: Authenticated (Free Access)
21
+
22
+ When a client provides their own {{ api_name }} API key:
23
+
24
+ ```
25
+ Request Headers:
26
+ Authorization: Bearer CLIENT_API_KEY
27
+
28
+ Flow:
29
+ 1. Client connects with their {{ api_name }} API key
30
+ 2. MCP server uses client's API key to call {{ api_name }} API
31
+ 3. No payment required
32
+ 4. Client pays {{ api_name }} directly (not the MCP server)
33
+ ```
34
+
35
+ **Use Case**: Clients who already have a {{ api_name }} subscription/API key
36
+
37
+ ### Mode 2: Payment Required (Paid Access)
38
+
39
+ When a client doesn't have their own API key but pays via x402/d402 protocol:
40
+
41
+ ```
42
+ Request Headers:
43
+ X-PAYMENT: <base64_encoded_x402_payment>
44
+
45
+ X402 Payment Header Format (created by x402.clients.base.create_payment_header()):
46
+ {
47
+ "x402Version": 1,
48
+ "scheme": "exact",
49
+ "network": "base-sepolia",
50
+ "payload": {
51
+ "signature": "0x...",
52
+ "authorization": {
53
+ "from": "0xCLIENT_ADDRESS",
54
+ "to": "0xSERVER_ADDRESS",
55
+ "value": "1000", // atomic units (wei)
56
+ "validAfter": "1700000000",
57
+ "validBefore": "1700000300",
58
+ "nonce": "hex..."
59
+ }
60
+ }
61
+ }
62
+
63
+ Flow:
64
+ 1. Client creates EIP-3009 transferWithAuthorization signature
65
+ 2. Client sends Payment header with encoded payment payload
66
+ 3. MCP server verifies payment using traia_iatp.d402.facilitator
67
+ 4. MCP server uses its INTERNAL {{ api_name }} API key to call the API
68
+ 5. Client pays the MCP server (not {{ api_name }})
69
+ ```
70
+
71
+ **Use Case**: Pay-per-use clients without their own {{ api_name }} subscription
72
+
73
+ ### D402 Protocol Integration
74
+
75
+ This server uses the **traia_iatp.d402** module which implements:
76
+ - EIP-3009 transferWithAuthorization for gasless payments
77
+ - Payment verification via IATP Settlement Facilitator
78
+ - On-chain transaction verification
79
+ - Multiple token support (USDC, TRAIA, etc.)
80
+
81
+ **Dependencies** (already in pyproject.toml):
82
+ - `traia-iatp>=0.1.27` - Provides d402 module
83
+ - `web3>=6.15.0` - For blockchain verification
84
+
85
+ ### Implementation Pattern for Tools
86
+
87
+ **For auto-generated tools** (from OpenAPI), the endpoint implementer will generate code like this:
88
+
89
+ ```python
90
+ from traia_iatp.d402.mcp_middleware import EndpointPaymentInfo, verify_endpoint_payment
91
+
92
+ @mcp.tool()
93
+ async def your_tool_name(context: Context, param1: str) -> Dict[str, Any]:
94
+ """Your tool description."""
95
+
96
+ # Get client's API key (if provided)
97
+ api_key = get_session_api_key(context)
98
+
99
+ # If no API key, verify payment for this specific endpoint
100
+ if not api_key:
101
+ # Each endpoint has specific payment requirements
102
+ endpoint_payment = EndpointPaymentInfo(
103
+ settlement_token_address="0xUSDC...", # From endpoint config
104
+ settlement_token_network="base-sepolia", # From endpoint config
105
+ payment_price_float=0.001, # From endpoint config
106
+ payment_price_wei="1000", # From endpoint config
107
+ server_address="0xSERVER..." # Server's payment address
108
+ )
109
+
110
+ # Verify payment matches this endpoint's requirements
111
+ if not verify_endpoint_payment(context, endpoint_payment):
112
+ return {
113
+ "error": "Payment required or insufficient",
114
+ "code": 402,
115
+ "required_payment": {
116
+ "token": "0xUSDC...",
117
+ "network": "base-sepolia",
118
+ "amount": 0.001
119
+ }
120
+ }
121
+
122
+ # Dual-mode: determine which API key to use
123
+ if api_key:
124
+ # MODE 1: Use client's API key (free for client)
125
+ api_key_to_use = api_key
126
+ else:
127
+ # MODE 2: Use server's internal API key (client paid)
128
+ api_key_to_use = os.getenv("{{ api_key_env_var }}")
129
+
130
+ # Call API
131
+ headers = {"Authorization": f"Bearer {api_key_to_use}"}
132
+ response = requests.get("{{ api_url }}/endpoint", headers=headers)
133
+ return response.json()
134
+ ```
135
+
136
+ **Key points**:
137
+ 1. Each tool verifies payment against **its specific endpoint requirements**
138
+ 2. Different endpoints can have different tokens, networks, and prices
139
+ 3. Payment amount/token/network are verified per-endpoint
140
+ 4. The middleware just extracts payment payload globally
141
+
142
+ ### Middleware Chain
143
+
144
+ The server has TWO middleware in sequence:
145
+
146
+ 1. **AuthMiddleware**: Extracts client's API key from Authorization header
147
+ 2. **D402MCPMiddleware**: Extracts and validates payment payload from Payment header
148
+
149
+ ### How Per-Endpoint Payment Works
150
+
151
+ Unlike FastAPI where middleware can be applied per-route, FastMCP has global middleware.
152
+ Therefore:
153
+
154
+ 1. **D402MCPMiddleware**: Extracts payment payload globally, stores in `context.state.payment_payload`
155
+ 2. **Each Tool**: Calls `verify_endpoint_payment()` with its specific requirements
156
+ - Verifies payment token matches endpoint's settlement token
157
+ - Verifies payment amount meets endpoint's price
158
+ - Verifies payment network matches endpoint's network
159
+
160
+ **Result**: Different endpoints can accept different tokens, on different networks, at different prices!
161
+
162
+ ### Environment Variables
163
+
164
+ **Required**:
165
+ - `{{ api_key_env_var }}`: Server's internal {{ api_name }} API key (used when clients pay via 402)
166
+ - `SERVER_ADDRESS`: MCP server's payment address (where 402 payments are sent)
167
+
168
+ **Required for Settlement (Production)**:
169
+ - `MCP_OPERATOR_PRIVATE_KEY`: Private key for signing settlement attestations (proof of service completion)
170
+ - `MCP_OPERATOR_ADDRESS`: Public address corresponding to operator private key (for verification)
171
+
172
+ **Optional**:
173
+ - `D402_FACILITATOR_URL`: Custom d402 facilitator URL (default: "https://facilitator.d402.net")
174
+ - `D402_FACILITATOR_API_KEY`: API key for private facilitator
175
+ - `D402_TESTING_MODE`: Set to "true" for local testing without settlement (default: "false")
176
+
177
+ **Example .env file**:
178
+ ```bash
179
+ # API Authentication (server's internal key for payment mode)
180
+ {{ api_key_env_var }}=your_{{ api_slug }}_api_key_here
181
+
182
+ # Server Payment Address (where 402 payments are received)
183
+ SERVER_ADDRESS=0x1234567890123456789012345678901234567890
184
+
185
+ # Operator Keys (for signing settlement attestations)
186
+ MCP_OPERATOR_PRIVATE_KEY=0x1234567890abcdef... # Keep secure!
187
+ MCP_OPERATOR_ADDRESS=0x9876543210fedcba... # Derived from private key
188
+
189
+ # Optional: Custom facilitator
190
+ D402_FACILITATOR_URL=https://facilitator.d402.net
191
+ D402_FACILITATOR_API_KEY=facilitator_api_key
192
+
193
+ # Optional: Testing mode (skip settlement for local dev)
194
+ D402_TESTING_MODE=false # Set to 'true' for testing without facilitator
195
+ ```
196
+
197
+ **About Operator Keys**:
198
+ - The operator signs settlement attestations after completing each paid request
199
+ - Attestation proves: service was completed + output hash is valid
200
+ - Can use the same key as SERVER_ADDRESS or a separate signing key
201
+ - Required for on-chain settlement via IATP Settlement Layer
202
+
203
+ **Note on Endpoint-Specific Configuration**:
204
+ Each endpoint's payment requirements (token, network, price) are embedded in the tool code.
205
+ These come from the endpoint configuration in the database/OpenAPI schema.
206
+
207
+ {% endif %}
208
+
15
209
  ## Implementation Checklist
16
210
 
17
211
  ### 1. Update Deployment Configuration
@@ -8,8 +8,7 @@
8
8
  {% if requires_auth %}"api_key_header": "Authorization",
9
9
  "api_keys": ["{{ api_key_env_var }}"],
10
10
  {% endif %}"capabilities": [
11
- "example_tool",
12
- "get_api_info"
11
+ "example_tool"
13
12
  ]
14
13
  },
15
14
  "deployment_method": "cloud_run",
@@ -5,19 +5,29 @@ services:
5
5
  build: .
6
6
  container_name: {{ api_slug }}-mcp-server
7
7
  ports:
8
- - "8000:8000"
8
+ - "8080:8080"
9
9
  environment:
10
10
  - PORT=8000
11
11
  - STAGE=${STAGE:-MAINNET}
12
12
  - LOG_LEVEL=${LOG_LEVEL:-INFO}
13
- {% if api_key_env_var %}
13
+ {% if requires_auth %}
14
+ # API Authentication (server's internal key for payment mode)
15
+ # Set this in .env file when deploying (creator provides their master API key)
14
16
  - {{ api_key_env_var }}={% raw %}${{% endraw %}{{ api_key_env_var }}{% raw %}}{% endraw %}
15
17
  {% endif %}
18
+ # D402 Payment Protocol Configuration
19
+ - SERVER_ADDRESS=${SERVER_ADDRESS:-}
20
+ - MCP_OPERATOR_PRIVATE_KEY=${MCP_OPERATOR_PRIVATE_KEY:-} # For signing settlement attestations
21
+ - MCP_OPERATOR_ADDRESS=${MCP_OPERATOR_ADDRESS:-} # Operator's public address (for verification)
22
+ - D402_FACILITATOR_URL=${D402_FACILITATOR_URL:-https://test-facilitator.d402.net}
23
+ - D402_FACILITATOR_API_KEY=${D402_FACILITATOR_API_KEY:-}
24
+ - D402_TESTING_MODE=${D402_TESTING_MODE:-false} # Set to 'true' for local testing without facilitator
25
+ - NETWORK=${NETWORK:-sepolia}
16
26
  volumes:
17
27
  - ./logs:/app/logs
18
28
  restart: unless-stopped
19
29
  healthcheck:
20
- test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
30
+ test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
21
31
  interval: 30s
22
32
  timeout: 10s
23
33
  retries: 3
@@ -0,0 +1,60 @@
1
+ # {{ api_name }} MCP Server Environment Configuration
2
+ #
3
+ # IMPORTANT: These values will be set during deployment (Phase 2)
4
+ # This file is a template - actual .env will be created with real values
5
+
6
+ # ============================================
7
+ # Server Configuration
8
+ # ============================================
9
+ PORT=8080
10
+ STAGE=MAINNET
11
+ LOG_LEVEL=INFO
12
+
13
+ {% if requires_auth %}
14
+ # ============================================
15
+ # API Authentication (Set during deployment)
16
+ # ============================================
17
+ # Server's internal {{ api_name }} API key
18
+ # This is used when clients pay via HTTP 402 (payment mode)
19
+ # Will be provided by MCP server creator during deployment
20
+ {{ api_key_env_var }}=
21
+
22
+ {% endif %}
23
+ # ============================================
24
+ # D402 Payment Protocol (Set during deployment)
25
+ # ============================================
26
+ # MCP server's payment address (IATP wallet contract address)
27
+ # Generated during deployment when IATP wallet contract is created
28
+ SERVER_ADDRESS=
29
+
30
+ # Operator keys for signing settlement attestations
31
+ # Generated during deployment from IATP wallet contract
32
+ MCP_OPERATOR_PRIVATE_KEY=
33
+ MCP_OPERATOR_ADDRESS=
34
+
35
+ # Facilitator configuration
36
+ # Options:
37
+ # - Remote (production): https://test-facilitator.d402.net
38
+ # - Local (development): http://host.docker.internal:7070
39
+ D402_FACILITATOR_URL=https://test-facilitator.d402.net
40
+ D402_FACILITATOR_API_KEY=
41
+
42
+ # Default settlement token configuration
43
+ # Used as defaults for example tools and fallback for endpoints
44
+ DEFAULT_SETTLEMENT_TOKEN=0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238
45
+ DEFAULT_SETTLEMENT_NETWORK=sepolia
46
+
47
+ # Testing mode (set to 'true' to bypass facilitator for local testing)
48
+ D402_TESTING_MODE=false
49
+
50
+ # ============================================
51
+ # Deployment Process
52
+ # ============================================
53
+ # Phase 1 (Completed): Code generation
54
+ # Phase 2 (Next): Deployment via deploy_mcp_lambda_handler
55
+ # 1. Create IATP wallet contract → Get SERVER_ADDRESS
56
+ # 2. Generate operator keys → Get MCP_OPERATOR_PRIVATE_KEY & MCP_OPERATOR_ADDRESS
57
+ # 3. Get API key from creator{% if requires_auth %} → Set {{ api_key_env_var }}{% endif %}
58
+ # 4. Deploy to GCP with actual environment variables
59
+ # 5. Register in MongoDB
60
+
@@ -91,7 +91,7 @@ def check_mcp_server_health(url: str) -> bool:
91
91
  print(f"📋 Available tools: {', '.join(tool_names)}")
92
92
 
93
93
  # Check for expected tools
94
- expected_tools = ["example_tool", "get_api_info"]
94
+ expected_tools = ["example_tool"]
95
95
  missing_tools = [tool for tool in expected_tools if tool not in tool_names]
96
96
 
97
97
  if missing_tools:
@@ -136,7 +136,7 @@ def main():
136
136
 
137
137
  print(f"🚀 {{ api_name }} MCP Server Health Check")
138
138
  print(f"📍 Server URL: {args.url}")
139
- print(f"📰 Expected tools: example_tool, get_api_info")
139
+ print(f"📰 Expected tools: example_tool")
140
140
  print("="*50)
141
141
 
142
142
  if check_mcp_server_health(args.url):
@@ -1,15 +1,18 @@
1
1
  [project]
2
2
  name = "{{ api_slug }}-mcp-server"
3
3
  version = "0.1.0"
4
- description = "MCP server for {{ api_name }} API{% if auth_description %} with authentication support{% endif %}"
4
+ description = "MCP server for {{ api_name }} API with {% if auth_description %} authentication and {% endif %} HTTP 402 payment protocol support"
5
5
  requires-python = ">=3.12"
6
6
  dependencies = [
7
- "crewai-tools[mcp]>=0.48.0",
8
- "fastmcp>=2.10.1",
7
+ "anyio>=4.0.0",
8
+ "mcp>=1.1.2",
9
9
  "python-dotenv>=1.1.1",
10
- "requests>=2.32.4",
11
- "starlette>=0.46.2",
10
+ "requests>=2.32.5",
11
+ "starlette>=0.45.0",
12
12
  "retry>=0.9.2",
13
+ "traia-iatp>=0.1.67", # For d402 payment protocol and RPC fallback support
14
+ "uvicorn>=0.37.0",
15
+ "web3>=6.15.0", # For blockchain payment verification
13
16
  {% if sdk_package %}
14
17
  "{{ sdk_package }}",
15
18
  {% endif %}
@@ -19,6 +22,9 @@ dependencies = [
19
22
  requires = ["hatchling"]
20
23
  build-backend = "hatchling.build"
21
24
 
25
+ [tool.hatch.metadata]
26
+ allow-direct-references = true
27
+
22
28
  [tool.hatch.build.targets.wheel]
23
29
  include = [
24
30
  "server.py",
@@ -0,0 +1,22 @@
1
+ {
2
+ "include": [
3
+ "server.py",
4
+ "mcp_health_check.py"
5
+ ],
6
+ "exclude": [
7
+ "**/__pycache__",
8
+ ".venv",
9
+ "**/*.pyc"
10
+ ],
11
+ "extraPaths": [
12
+ "../../../../IATP/src",
13
+ "/Users/eitanlavi/workspace/traia/IATP/src"
14
+ ],
15
+ "pythonVersion": "3.12",
16
+ "typeCheckingMode": "basic",
17
+ "reportMissingImports": true,
18
+ "reportMissingTypeStubs": false,
19
+ "venvPath": ".",
20
+ "venv": ".venv"
21
+ }
22
+