eulerian-marketing-platform 0.2.2__py3-none-any.whl → 0.2.4__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.
@@ -4,7 +4,7 @@ This package provides a Model Context Protocol (MCP) server that enables
4
4
  AI assistants to interact with Eulerian Marketing Platform APIs.
5
5
  """
6
6
 
7
- __version__ = "0.2.2"
7
+ __version__ = "0.2.4"
8
8
  __author__ = "Eulerian Technologies"
9
9
  __all__ = []
10
10
 
@@ -74,12 +74,13 @@ def forward_request(request_data: dict) -> dict:
74
74
  request_data: The JSON-RPC request to forward
75
75
 
76
76
  Returns:
77
- The JSON-RPC response from the remote server
77
+ The JSON-RPC response from the remote server, or None for notifications
78
78
  """
79
79
  timeout = float(os.environ.get("EMP_TIMEOUT", "300"))
80
80
 
81
81
  request_id = request_data.get("id")
82
82
  method = request_data.get("method")
83
+ is_notification = request_id is None
83
84
 
84
85
  logger.info(f">>> REQUEST: {method} (id: {request_id})")
85
86
  logger.debug(f" Full request: {json.dumps(request_data)[:200]}...")
@@ -104,6 +105,11 @@ def forward_request(request_data: dict) -> dict:
104
105
  error_msg = f"HTTP {response.status_code}: {response.reason_phrase}"
105
106
  logger.error(f" Error: {response.text[:200]}")
106
107
 
108
+ # For notifications, don't return error responses
109
+ if is_notification:
110
+ logger.info(" Notification error - no response sent")
111
+ return None
112
+
107
113
  return {
108
114
  "jsonrpc": "2.0",
109
115
  "id": request_id,
@@ -118,6 +124,11 @@ def forward_request(request_data: dict) -> dict:
118
124
  response_data = response.json()
119
125
  logger.debug(f" Response: {json.dumps(response_data)[:200]}...")
120
126
 
127
+ # For notifications, we should not send back any response, regardless of what the remote server returns
128
+ if is_notification:
129
+ logger.info(" Notification processed - no response sent")
130
+ return None
131
+
121
132
  # Validate JSON-RPC response
122
133
  if "jsonrpc" not in response_data:
123
134
  logger.warning(" WARNING: Missing 'jsonrpc' field")
@@ -131,6 +142,12 @@ def forward_request(request_data: dict) -> dict:
131
142
 
132
143
  except json.JSONDecodeError as e:
133
144
  logger.error(f" ERROR: Invalid JSON - {e}")
145
+
146
+ # For notifications, don't return error responses
147
+ if is_notification:
148
+ logger.info(" Notification JSON error - no response sent")
149
+ return None
150
+
134
151
  return {
135
152
  "jsonrpc": "2.0",
136
153
  "id": request_id,
@@ -142,6 +159,12 @@ def forward_request(request_data: dict) -> dict:
142
159
 
143
160
  except httpx.TimeoutException:
144
161
  logger.error("ERROR: Request timeout")
162
+
163
+ # For notifications, don't return error responses
164
+ if is_notification:
165
+ logger.info(" Notification timeout - no response sent")
166
+ return None
167
+
145
168
  return {
146
169
  "jsonrpc": "2.0",
147
170
  "id": request_id,
@@ -153,6 +176,12 @@ def forward_request(request_data: dict) -> dict:
153
176
 
154
177
  except httpx.RequestError as e:
155
178
  logger.error(f"ERROR: Request failed - {str(e)}")
179
+
180
+ # For notifications, don't return error responses
181
+ if is_notification:
182
+ logger.info(" Notification request error - no response sent")
183
+ return None
184
+
156
185
  return {
157
186
  "jsonrpc": "2.0",
158
187
  "id": request_id,
@@ -166,6 +195,12 @@ def forward_request(request_data: dict) -> dict:
166
195
  logger.error(f"ERROR: Unexpected error - {str(e)}")
167
196
  import traceback
168
197
  logger.error(f"Traceback: {traceback.format_exc()}")
198
+
199
+ # For notifications, don't return error responses
200
+ if is_notification:
201
+ logger.info(" Notification unexpected error - no response sent")
202
+ return None
203
+
169
204
  return {
170
205
  "jsonrpc": "2.0",
171
206
  "id": request_id,
@@ -216,12 +251,15 @@ def main() -> None:
216
251
  # Forward to remote server
217
252
  response_data = forward_request(request_data)
218
253
 
219
- # Send response to stdout
220
- response_json = json.dumps(response_data)
221
- print(response_json, flush=True)
222
- sys.stdout.flush() # Extra flush for safety
223
- logger.info(" Response forwarded [OK]")
224
-
254
+ # Only send response for non-notifications (when response_data is not None)
255
+ if response_data is not None:
256
+ response_json = json.dumps(response_data)
257
+ print(response_json, flush=True)
258
+ sys.stdout.flush()
259
+ logger.info(" Response forwarded [OK]")
260
+ else:
261
+ logger.info(" Notification processed (no response sent)")
262
+
225
263
  except json.JSONDecodeError as e:
226
264
  logger.error(f"ERROR: Invalid JSON in request - {e}")
227
265
  logger.error(f" Problematic line: {line[:200]}")
@@ -277,4 +315,3 @@ def main() -> None:
277
315
 
278
316
  if __name__ == "__main__":
279
317
  main()
280
-
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: eulerian-marketing-platform
3
- Version: 0.2.2
3
+ Version: 0.2.4
4
4
  Summary: MCP server for Eulerian Marketing Platform - enables AI assistants to interact with Eulerian's marketing analytics and campaign management APIs
5
5
  Author-email: Eulerian Technologies <mathieu@eulerian.com>
6
6
  License: MIT
@@ -385,6 +385,9 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
385
385
 
386
386
  ## Changelog
387
387
 
388
+ ### 0.2.3
389
+ - fixes disconnection issue with notifications
390
+
388
391
  ### 0.2.0
389
392
  - Move to full Proxy mode
390
393
  - Remove instructions for uvx deployment
@@ -0,0 +1,8 @@
1
+ eulerian_marketing_platform/__init__.py,sha256=yW4kcvFCxjR0QpXlCWce62Rff9dLCyAFopXCzhoca7U,428
2
+ eulerian_marketing_platform/server.py,sha256=KbzP27uGEBW07R-OGl7qzmYOhcWsz4GbM5l1_NOiQ0Q,11306
3
+ eulerian_marketing_platform-0.2.4.dist-info/LICENSE,sha256=eIqBqE_fRsqQJ8F-2v0e-8WzZqdshsCqnzmqLAWrNHU,1078
4
+ eulerian_marketing_platform-0.2.4.dist-info/METADATA,sha256=mhmd4RcV0ftcm1le6Reg-UVTwDhNd8e0sizOSq0rV28,12169
5
+ eulerian_marketing_platform-0.2.4.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92
6
+ eulerian_marketing_platform-0.2.4.dist-info/entry_points.txt,sha256=rrPZptATSS9PUtH9gzCYq0WuP6eahkF-DkdUP1FaYfk,88
7
+ eulerian_marketing_platform-0.2.4.dist-info/top_level.txt,sha256=nidh3T6fw-mLjUqZwQ8AiMScS4usuH0WXW4ZgG4HYCo,28
8
+ eulerian_marketing_platform-0.2.4.dist-info/RECORD,,
@@ -1,8 +0,0 @@
1
- eulerian_marketing_platform/__init__.py,sha256=nixrhgx4yNj_Iy4OorDr_UTciCpEXPjuJoCLngubna8,428
2
- eulerian_marketing_platform/server.py,sha256=FnuFvs_yCIaHfDT5Q8LJb--88gZ58iUYQ7bNYYMFRYg,9710
3
- eulerian_marketing_platform-0.2.2.dist-info/LICENSE,sha256=eIqBqE_fRsqQJ8F-2v0e-8WzZqdshsCqnzmqLAWrNHU,1078
4
- eulerian_marketing_platform-0.2.2.dist-info/METADATA,sha256=AjQoC4KAd5cGFwGagKSUohxzzoCY9JGGJT5KUlVTxu0,12111
5
- eulerian_marketing_platform-0.2.2.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92
6
- eulerian_marketing_platform-0.2.2.dist-info/entry_points.txt,sha256=rrPZptATSS9PUtH9gzCYq0WuP6eahkF-DkdUP1FaYfk,88
7
- eulerian_marketing_platform-0.2.2.dist-info/top_level.txt,sha256=nidh3T6fw-mLjUqZwQ8AiMScS4usuH0WXW4ZgG4HYCo,28
8
- eulerian_marketing_platform-0.2.2.dist-info/RECORD,,