chatads-mcp-wrapper 0.1.0__tar.gz

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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Chris Shuptrine
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,276 @@
1
+ Metadata-Version: 2.4
2
+ Name: chatads-mcp-wrapper
3
+ Version: 0.1.0
4
+ Summary: Model Context Protocol (MCP) wrapper for ChatAds Affiliate API with async support
5
+ Author-email: ChatAds Team <support@chatads.com>
6
+ License: MIT License
7
+
8
+ Copyright (c) 2025 Chris Shuptrine
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ Project-URL: Homepage, https://github.com/chatads/chatads-mcp-wrapper
29
+ Project-URL: Documentation, https://github.com/chatads/chatads-mcp-wrapper#readme
30
+ Project-URL: Repository, https://github.com/chatads/chatads-mcp-wrapper
31
+ Project-URL: Issues, https://github.com/chatads/chatads-mcp-wrapper/issues
32
+ Project-URL: Changelog, https://github.com/chatads/chatads-mcp-wrapper/blob/main/CHANGELOG.md
33
+ Keywords: mcp,chatads,affiliate,ai,claude,async,model-context-protocol
34
+ Classifier: Development Status :: 4 - Beta
35
+ Classifier: Intended Audience :: Developers
36
+ Classifier: License :: OSI Approved :: MIT License
37
+ Classifier: Programming Language :: Python :: 3
38
+ Classifier: Programming Language :: Python :: 3.10
39
+ Classifier: Programming Language :: Python :: 3.11
40
+ Classifier: Programming Language :: Python :: 3.12
41
+ Classifier: Programming Language :: Python :: 3.13
42
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
43
+ Classifier: Topic :: Internet :: WWW/HTTP
44
+ Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
45
+ Classifier: Framework :: AsyncIO
46
+ Classifier: Typing :: Typed
47
+ Requires-Python: >=3.10
48
+ Description-Content-Type: text/markdown
49
+ License-File: LICENSE
50
+ Requires-Dist: fastmcp>=0.4.1
51
+ Requires-Dist: httpx>=0.27.2
52
+ Requires-Dist: pydantic>=2.12.0
53
+ Requires-Dist: python-json-logger>=2.0.7
54
+ Provides-Extra: dev
55
+ Requires-Dist: pytest>=8.3.3; extra == "dev"
56
+ Requires-Dist: pytest-cov>=6.0.0; extra == "dev"
57
+ Requires-Dist: pytest-asyncio>=0.24.0; extra == "dev"
58
+ Requires-Dist: pytest-httpx>=0.35.0; extra == "dev"
59
+ Requires-Dist: black>=24.10.0; extra == "dev"
60
+ Requires-Dist: ruff>=0.8.4; extra == "dev"
61
+ Requires-Dist: mypy>=1.13.0; extra == "dev"
62
+ Dynamic: license-file
63
+
64
+ # ChatAds MCP Wrapper
65
+
66
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
67
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
68
+ [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
69
+ [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
70
+ [![Checked with mypy](https://www.mypy-lang.org/static/mypy_badge.svg)](https://mypy-lang.org/)
71
+
72
+ This directory houses the Model Context Protocol (MCP) wrapper that exposes the ChatAds Affiliate API to Claude (or any MCP-aware client). The wrapper normalizes responses, hides backend-specific errors, and provides consistent metadata so Claude always receives a predictable envelope.
73
+
74
+ ## Requirements
75
+
76
+ - Python 3.10+
77
+ - `uv` **or** standard `pip`
78
+ - Environment variables:
79
+ - `CHATADS_API_KEY` – your ChatAds API key (required)
80
+ - Optional overrides:
81
+ - `CHATADS_API_BASE_URL` (default: Modal deployment URL)
82
+ - `CHATADS_API_ENDPOINT` (default: /v1/chatads/messages)
83
+ - `CHATADS_MCP_TIMEOUT` (default: 15 seconds)
84
+ - `CHATADS_MCP_MAX_RETRIES` (default: 3)
85
+ - `CHATADS_MCP_BACKOFF` (default: 0.6 seconds)
86
+ - `CHATADS_MAX_REQUEST_SIZE` (default: 10240 bytes / 10KB)
87
+ - `CHATADS_CIRCUIT_BREAKER_THRESHOLD` (default: 5 failures before opening)
88
+ - `CHATADS_CIRCUIT_BREAKER_TIMEOUT` (default: 60 seconds)
89
+ - `CHATADS_QUOTA_WARNING_THRESHOLD` (default: 0.9 / 90%)
90
+ - `LOGLEVEL` (default: INFO, options: DEBUG, INFO, WARNING, ERROR)
91
+ - `CHATADS_LOG_FORMAT` (default: text, options: text, json)
92
+
93
+ ## Installation
94
+
95
+ ### From PyPI (recommended)
96
+
97
+ ```bash
98
+ pip install chatads-mcp-wrapper
99
+ ```
100
+
101
+ ### From source (development)
102
+
103
+ ```bash
104
+ git clone https://github.com/chatads/chatads-mcp-wrapper.git
105
+ cd chatads-mcp-wrapper
106
+ python3 -m venv .venv && source .venv/bin/activate
107
+ pip install -r requirements-dev.txt
108
+ ```
109
+
110
+ Set your API key:
111
+
112
+ ```bash
113
+ export CHATADS_API_KEY=sk_live_...
114
+ ```
115
+
116
+ ## Running the MCP Server
117
+
118
+ ```bash
119
+ chatads-mcp
120
+ # or: python -m chatads_mcp_wrapper
121
+ ```
122
+
123
+ The server provides two MCP tools:
124
+ - `chatads_affiliate_lookup` - Main tool for fetching affiliate recommendations
125
+ - `chatads_health_check` - Health check tool for API status verification
126
+
127
+ ### Claude Desktop integration
128
+
129
+ Add a server entry to `claude_desktop_config.json` (path varies per OS):
130
+
131
+ **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
132
+ **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
133
+ **Linux**: `~/.config/Claude/claude_desktop_config.json`
134
+
135
+ ```json
136
+ {
137
+ "mcpServers": {
138
+ "chatads-affiliate": {
139
+ "command": "chatads-mcp",
140
+ "args": [],
141
+ "env": {
142
+ "CHATADS_API_KEY": "sk_live_your_key_here"
143
+ }
144
+ }
145
+ }
146
+ }
147
+ ```
148
+
149
+ Restart Claude Desktop and the tool will be available.
150
+
151
+ ## Tool Signature
152
+
153
+ ```text
154
+ chatads_affiliate_lookup(
155
+ message: str,
156
+ ip?: str,
157
+ user_agent?: str,
158
+ country?: str,
159
+ language?: str,
160
+ api_key?: str
161
+ ) -> {
162
+ status: "success" | "no_match" | "error",
163
+ matched: bool,
164
+ product?: str,
165
+ affiliate_link?: str,
166
+ category?: str,
167
+ affiliate_message?: str,
168
+ reason?: str,
169
+ error_code?: str,
170
+ error_message?: str,
171
+ metadata: {
172
+ request_id: str,
173
+ timestamp: str,
174
+ latency_ms: float,
175
+ status_code: int,
176
+ source: str,
177
+ country?: str,
178
+ language?: str,
179
+ usage_summary?: {...},
180
+ notes?: str
181
+ }
182
+ }
183
+ ```
184
+
185
+ ## Features
186
+
187
+ ### Circuit Breaker
188
+
189
+ Prevents retry storms when the API is experiencing issues. After N consecutive failures (default: 5), the circuit breaker "opens" and fails fast for a cooldown period (default: 60 seconds) instead of wasting resources.
190
+
191
+ **States:**
192
+ - `CLOSED`: Normal operation
193
+ - `OPEN`: Failing fast, not attempting requests
194
+ - `HALF_OPEN`: Testing if service recovered
195
+
196
+ **Configuration:**
197
+ ```bash
198
+ export CHATADS_CIRCUIT_BREAKER_THRESHOLD=5
199
+ export CHATADS_CIRCUIT_BREAKER_TIMEOUT=60
200
+ ```
201
+
202
+ ### Health Check Tool
203
+
204
+ Use `chatads_health_check()` to verify API connectivity without consuming quota:
205
+
206
+ ```python
207
+ result = chatads_health_check()
208
+ # Returns: status (healthy/degraded/unhealthy), latency, circuit breaker state
209
+ ```
210
+
211
+ Useful for:
212
+ - Deployment verification
213
+ - Monitoring dashboards
214
+ - Pre-flight checks
215
+
216
+ ### Quota Warnings
217
+
218
+ The wrapper automatically checks usage metadata and warns when approaching limits:
219
+ - Monthly quota < 10 requests remaining
220
+ - Daily quota ≥ 90% used (configurable via `CHATADS_QUOTA_WARNING_THRESHOLD`)
221
+ - Minute quota near limit
222
+
223
+ Warnings appear in `metadata.notes` and logs. No client-side state management needed - uses real-time data from backend.
224
+
225
+ ### Monitoring Hooks
226
+
227
+ Integrate with your monitoring system:
228
+
229
+ ```python
230
+ from chatads_mcp_wrapper import set_metric_callback
231
+ import datadog
232
+
233
+ # Configure callback for metrics
234
+ set_metric_callback(datadog.statsd.gauge)
235
+ ```
236
+
237
+ Emitted metrics:
238
+ - `chatads.request.latency_ms` - Request latency
239
+ - `chatads.circuit_breaker.state_change` - Circuit breaker transitions
240
+
241
+ ## Best Practices
242
+
243
+ - **Validate prompts**: ensure `message` is non-empty and under 100 words to avoid upstream validation errors.
244
+ - **Monitor quota warnings**: Check `metadata.notes` for quota warnings to avoid hitting limits.
245
+ - **Use health checks**: Verify API availability before critical operations.
246
+ - **Honor circuit breaker**: When circuit is open, wait for cooldown period before retrying.
247
+ - **Log metadata**: persist `metadata.request_id` and `metadata.usage_summary` for debugging and analytics.
248
+ - **Handle `no_match`**: treat `status="no_match"` as a graceful fallback—use `reason` to explain why no ad was returned.
249
+ - **Override cautiously**: only pass `country`/`language` when you have high-confidence signals; otherwise let ChatAds infer them.
250
+ - **Secure API keys**: prefer environment variables; only use the `api_key` argument for per-request overrides inside trusted contexts.
251
+
252
+ ## Troubleshooting
253
+
254
+ | Symptom | Likely Cause | Resolution |
255
+ | --- | --- | --- |
256
+ | `CONFIGURATION_ERROR` | Missing `CHATADS_API_KEY` | Export the key or pass `api_key` argument. |
257
+ | `FORBIDDEN` / `UNAUTHORIZED` | Invalid or revoked key | Verify the key in Supabase / dashboard; rotate if needed. |
258
+ | `MINUTE_QUOTA_EXCEEDED` / `DAILY_QUOTA_EXCEEDED` / `QUOTA_EXCEEDED` | Hitting rate or hard caps | Respect `metadata.notes` and retry after the implied window or upgrade the plan. |
259
+ | `CIRCUIT_BREAKER_OPEN` | Too many consecutive failures | Circuit breaker is protecting against failed requests. Wait 60 seconds or check API health with `chatads_health_check()`. |
260
+ | `UPSTREAM_UNAVAILABLE` | Network outage or repeated 5xx | Wait/backoff; confirm Modal deployment health; consider raising `CHATADS_MCP_MAX_RETRIES`. |
261
+ | `INVALID_INPUT` | Empty message or <2 words | Provide more descriptive user text; sanitize before sending. |
262
+ | `REQUEST_TOO_LARGE` | Payload exceeds size limit | Reduce message length or increase `CHATADS_MAX_REQUEST_SIZE`. |
263
+
264
+ Enable debug logging if deeper insight is needed:
265
+
266
+ ```bash
267
+ # Text logging (default)
268
+ LOGLEVEL=DEBUG chatads-mcp
269
+
270
+ # JSON structured logging (recommended for production)
271
+ CHATADS_LOG_FORMAT=json LOGLEVEL=INFO chatads-mcp
272
+ ```
273
+
274
+ JSON logging outputs structured logs compatible with log aggregation systems (CloudWatch, Datadog, etc.).
275
+
276
+ Logs include upstream latency, retry attempts, and normalized error payloads without exposing internal stack traces or API keys to Claude.
@@ -0,0 +1,213 @@
1
+ # ChatAds MCP Wrapper
2
+
3
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+ [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
6
+ [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
7
+ [![Checked with mypy](https://www.mypy-lang.org/static/mypy_badge.svg)](https://mypy-lang.org/)
8
+
9
+ This directory houses the Model Context Protocol (MCP) wrapper that exposes the ChatAds Affiliate API to Claude (or any MCP-aware client). The wrapper normalizes responses, hides backend-specific errors, and provides consistent metadata so Claude always receives a predictable envelope.
10
+
11
+ ## Requirements
12
+
13
+ - Python 3.10+
14
+ - `uv` **or** standard `pip`
15
+ - Environment variables:
16
+ - `CHATADS_API_KEY` – your ChatAds API key (required)
17
+ - Optional overrides:
18
+ - `CHATADS_API_BASE_URL` (default: Modal deployment URL)
19
+ - `CHATADS_API_ENDPOINT` (default: /v1/chatads/messages)
20
+ - `CHATADS_MCP_TIMEOUT` (default: 15 seconds)
21
+ - `CHATADS_MCP_MAX_RETRIES` (default: 3)
22
+ - `CHATADS_MCP_BACKOFF` (default: 0.6 seconds)
23
+ - `CHATADS_MAX_REQUEST_SIZE` (default: 10240 bytes / 10KB)
24
+ - `CHATADS_CIRCUIT_BREAKER_THRESHOLD` (default: 5 failures before opening)
25
+ - `CHATADS_CIRCUIT_BREAKER_TIMEOUT` (default: 60 seconds)
26
+ - `CHATADS_QUOTA_WARNING_THRESHOLD` (default: 0.9 / 90%)
27
+ - `LOGLEVEL` (default: INFO, options: DEBUG, INFO, WARNING, ERROR)
28
+ - `CHATADS_LOG_FORMAT` (default: text, options: text, json)
29
+
30
+ ## Installation
31
+
32
+ ### From PyPI (recommended)
33
+
34
+ ```bash
35
+ pip install chatads-mcp-wrapper
36
+ ```
37
+
38
+ ### From source (development)
39
+
40
+ ```bash
41
+ git clone https://github.com/chatads/chatads-mcp-wrapper.git
42
+ cd chatads-mcp-wrapper
43
+ python3 -m venv .venv && source .venv/bin/activate
44
+ pip install -r requirements-dev.txt
45
+ ```
46
+
47
+ Set your API key:
48
+
49
+ ```bash
50
+ export CHATADS_API_KEY=sk_live_...
51
+ ```
52
+
53
+ ## Running the MCP Server
54
+
55
+ ```bash
56
+ chatads-mcp
57
+ # or: python -m chatads_mcp_wrapper
58
+ ```
59
+
60
+ The server provides two MCP tools:
61
+ - `chatads_affiliate_lookup` - Main tool for fetching affiliate recommendations
62
+ - `chatads_health_check` - Health check tool for API status verification
63
+
64
+ ### Claude Desktop integration
65
+
66
+ Add a server entry to `claude_desktop_config.json` (path varies per OS):
67
+
68
+ **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
69
+ **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
70
+ **Linux**: `~/.config/Claude/claude_desktop_config.json`
71
+
72
+ ```json
73
+ {
74
+ "mcpServers": {
75
+ "chatads-affiliate": {
76
+ "command": "chatads-mcp",
77
+ "args": [],
78
+ "env": {
79
+ "CHATADS_API_KEY": "sk_live_your_key_here"
80
+ }
81
+ }
82
+ }
83
+ }
84
+ ```
85
+
86
+ Restart Claude Desktop and the tool will be available.
87
+
88
+ ## Tool Signature
89
+
90
+ ```text
91
+ chatads_affiliate_lookup(
92
+ message: str,
93
+ ip?: str,
94
+ user_agent?: str,
95
+ country?: str,
96
+ language?: str,
97
+ api_key?: str
98
+ ) -> {
99
+ status: "success" | "no_match" | "error",
100
+ matched: bool,
101
+ product?: str,
102
+ affiliate_link?: str,
103
+ category?: str,
104
+ affiliate_message?: str,
105
+ reason?: str,
106
+ error_code?: str,
107
+ error_message?: str,
108
+ metadata: {
109
+ request_id: str,
110
+ timestamp: str,
111
+ latency_ms: float,
112
+ status_code: int,
113
+ source: str,
114
+ country?: str,
115
+ language?: str,
116
+ usage_summary?: {...},
117
+ notes?: str
118
+ }
119
+ }
120
+ ```
121
+
122
+ ## Features
123
+
124
+ ### Circuit Breaker
125
+
126
+ Prevents retry storms when the API is experiencing issues. After N consecutive failures (default: 5), the circuit breaker "opens" and fails fast for a cooldown period (default: 60 seconds) instead of wasting resources.
127
+
128
+ **States:**
129
+ - `CLOSED`: Normal operation
130
+ - `OPEN`: Failing fast, not attempting requests
131
+ - `HALF_OPEN`: Testing if service recovered
132
+
133
+ **Configuration:**
134
+ ```bash
135
+ export CHATADS_CIRCUIT_BREAKER_THRESHOLD=5
136
+ export CHATADS_CIRCUIT_BREAKER_TIMEOUT=60
137
+ ```
138
+
139
+ ### Health Check Tool
140
+
141
+ Use `chatads_health_check()` to verify API connectivity without consuming quota:
142
+
143
+ ```python
144
+ result = chatads_health_check()
145
+ # Returns: status (healthy/degraded/unhealthy), latency, circuit breaker state
146
+ ```
147
+
148
+ Useful for:
149
+ - Deployment verification
150
+ - Monitoring dashboards
151
+ - Pre-flight checks
152
+
153
+ ### Quota Warnings
154
+
155
+ The wrapper automatically checks usage metadata and warns when approaching limits:
156
+ - Monthly quota < 10 requests remaining
157
+ - Daily quota ≥ 90% used (configurable via `CHATADS_QUOTA_WARNING_THRESHOLD`)
158
+ - Minute quota near limit
159
+
160
+ Warnings appear in `metadata.notes` and logs. No client-side state management needed - uses real-time data from backend.
161
+
162
+ ### Monitoring Hooks
163
+
164
+ Integrate with your monitoring system:
165
+
166
+ ```python
167
+ from chatads_mcp_wrapper import set_metric_callback
168
+ import datadog
169
+
170
+ # Configure callback for metrics
171
+ set_metric_callback(datadog.statsd.gauge)
172
+ ```
173
+
174
+ Emitted metrics:
175
+ - `chatads.request.latency_ms` - Request latency
176
+ - `chatads.circuit_breaker.state_change` - Circuit breaker transitions
177
+
178
+ ## Best Practices
179
+
180
+ - **Validate prompts**: ensure `message` is non-empty and under 100 words to avoid upstream validation errors.
181
+ - **Monitor quota warnings**: Check `metadata.notes` for quota warnings to avoid hitting limits.
182
+ - **Use health checks**: Verify API availability before critical operations.
183
+ - **Honor circuit breaker**: When circuit is open, wait for cooldown period before retrying.
184
+ - **Log metadata**: persist `metadata.request_id` and `metadata.usage_summary` for debugging and analytics.
185
+ - **Handle `no_match`**: treat `status="no_match"` as a graceful fallback—use `reason` to explain why no ad was returned.
186
+ - **Override cautiously**: only pass `country`/`language` when you have high-confidence signals; otherwise let ChatAds infer them.
187
+ - **Secure API keys**: prefer environment variables; only use the `api_key` argument for per-request overrides inside trusted contexts.
188
+
189
+ ## Troubleshooting
190
+
191
+ | Symptom | Likely Cause | Resolution |
192
+ | --- | --- | --- |
193
+ | `CONFIGURATION_ERROR` | Missing `CHATADS_API_KEY` | Export the key or pass `api_key` argument. |
194
+ | `FORBIDDEN` / `UNAUTHORIZED` | Invalid or revoked key | Verify the key in Supabase / dashboard; rotate if needed. |
195
+ | `MINUTE_QUOTA_EXCEEDED` / `DAILY_QUOTA_EXCEEDED` / `QUOTA_EXCEEDED` | Hitting rate or hard caps | Respect `metadata.notes` and retry after the implied window or upgrade the plan. |
196
+ | `CIRCUIT_BREAKER_OPEN` | Too many consecutive failures | Circuit breaker is protecting against failed requests. Wait 60 seconds or check API health with `chatads_health_check()`. |
197
+ | `UPSTREAM_UNAVAILABLE` | Network outage or repeated 5xx | Wait/backoff; confirm Modal deployment health; consider raising `CHATADS_MCP_MAX_RETRIES`. |
198
+ | `INVALID_INPUT` | Empty message or <2 words | Provide more descriptive user text; sanitize before sending. |
199
+ | `REQUEST_TOO_LARGE` | Payload exceeds size limit | Reduce message length or increase `CHATADS_MAX_REQUEST_SIZE`. |
200
+
201
+ Enable debug logging if deeper insight is needed:
202
+
203
+ ```bash
204
+ # Text logging (default)
205
+ LOGLEVEL=DEBUG chatads-mcp
206
+
207
+ # JSON structured logging (recommended for production)
208
+ CHATADS_LOG_FORMAT=json LOGLEVEL=INFO chatads-mcp
209
+ ```
210
+
211
+ JSON logging outputs structured logs compatible with log aggregation systems (CloudWatch, Datadog, etc.).
212
+
213
+ Logs include upstream latency, retry attempts, and normalized error payloads without exposing internal stack traces or API keys to Claude.