eulerian-marketing-platform 0.2.1__tar.gz → 0.2.3__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.
Files changed (16) hide show
  1. {eulerian_marketing_platform-0.2.1 → eulerian_marketing_platform-0.2.3}/PKG-INFO +1 -1
  2. {eulerian_marketing_platform-0.2.1 → eulerian_marketing_platform-0.2.3}/pyproject.toml +1 -1
  3. {eulerian_marketing_platform-0.2.1 → eulerian_marketing_platform-0.2.3}/setup.cfg +1 -1
  4. {eulerian_marketing_platform-0.2.1 → eulerian_marketing_platform-0.2.3}/src/eulerian_marketing_platform/__init__.py +1 -1
  5. {eulerian_marketing_platform-0.2.1 → eulerian_marketing_platform-0.2.3}/src/eulerian_marketing_platform/server.py +69 -34
  6. {eulerian_marketing_platform-0.2.1 → eulerian_marketing_platform-0.2.3}/src/eulerian_marketing_platform.egg-info/PKG-INFO +1 -1
  7. {eulerian_marketing_platform-0.2.1 → eulerian_marketing_platform-0.2.3}/.env.example +0 -0
  8. {eulerian_marketing_platform-0.2.1 → eulerian_marketing_platform-0.2.3}/LICENSE +0 -0
  9. {eulerian_marketing_platform-0.2.1 → eulerian_marketing_platform-0.2.3}/MANIFEST.in +0 -0
  10. {eulerian_marketing_platform-0.2.1 → eulerian_marketing_platform-0.2.3}/README.md +0 -0
  11. {eulerian_marketing_platform-0.2.1 → eulerian_marketing_platform-0.2.3}/requirements.txt +0 -0
  12. {eulerian_marketing_platform-0.2.1 → eulerian_marketing_platform-0.2.3}/src/eulerian_marketing_platform.egg-info/SOURCES.txt +0 -0
  13. {eulerian_marketing_platform-0.2.1 → eulerian_marketing_platform-0.2.3}/src/eulerian_marketing_platform.egg-info/dependency_links.txt +0 -0
  14. {eulerian_marketing_platform-0.2.1 → eulerian_marketing_platform-0.2.3}/src/eulerian_marketing_platform.egg-info/entry_points.txt +0 -0
  15. {eulerian_marketing_platform-0.2.1 → eulerian_marketing_platform-0.2.3}/src/eulerian_marketing_platform.egg-info/requires.txt +0 -0
  16. {eulerian_marketing_platform-0.2.1 → eulerian_marketing_platform-0.2.3}/src/eulerian_marketing_platform.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: eulerian_marketing_platform
3
- Version: 0.2.1
3
+ Version: 0.2.3
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
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "eulerian_marketing_platform"
7
- version = "0.2.1"
7
+ version = "0.2.3"
8
8
  description = "MCP server for Eulerian Marketing Platform - enables AI assistants to interact with Eulerian's marketing analytics and campaign management APIs"
9
9
  readme = "README.md"
10
10
  authors = [
@@ -1,6 +1,6 @@
1
1
  [metadata]
2
2
  name = eulerian_marketing_platform
3
- version = 0.2.1
3
+ version = 0.2.3
4
4
 
5
5
  [options]
6
6
  package_dir =
@@ -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.1"
7
+ __version__ = "0.2.3"
8
8
  __author__ = "Eulerian Technologies"
9
9
  __all__ = []
10
10
 
@@ -191,57 +191,92 @@ def main() -> None:
191
191
  logger.info(f"Timeout: {float(os.environ.get('EMP_TIMEOUT', '300'))}s")
192
192
  logger.info("Starting stdio proxy - all remote tools will be available")
193
193
 
194
+ # Set stdout to unbuffered mode
195
+ sys.stdout.reconfigure(line_buffering=True)
196
+
194
197
  try:
195
198
  # Read from stdin line by line
196
- for line in sys.stdin:
197
- line = line.strip()
198
- if not line:
199
- continue
200
-
199
+ while True:
201
200
  try:
202
- # Parse request
203
- request_data = json.loads(line)
201
+ line = sys.stdin.readline()
204
202
 
205
- # Forward to remote server
206
- response_data = forward_request(request_data)
203
+ # Check for EOF
204
+ if not line:
205
+ logger.info("EOF received on stdin, exiting")
206
+ break
207
207
 
208
- # Send response to stdout
209
- response_json = json.dumps(response_data)
210
- print(response_json, flush=True)
211
- logger.info(" Response forwarded [OK]")
208
+ line = line.strip()
209
+ if not line:
210
+ continue
212
211
 
213
- except json.JSONDecodeError as e:
214
- logger.error(f"ERROR: Invalid JSON in request - {e}")
215
- error_response = {
216
- "jsonrpc": "2.0",
217
- "id": None,
218
- "error": {
219
- "code": -32700,
220
- "message": f"Parse error: {str(e)}"
212
+ try:
213
+ # Parse request
214
+ request_data = json.loads(line)
215
+
216
+ # Forward to remote server
217
+ response_data = forward_request(request_data)
218
+
219
+ # JSON-RPC notifications MUST NOT be answered
220
+ if "id" in request_data and request_data["id"] is not None:
221
+ response_json = json.dumps(response_data)
222
+ print(response_json, flush=True)
223
+ sys.stdout.flush()
224
+ logger.info(" Response forwarded [OK]")
225
+ else:
226
+ logger.info(" Notification forwarded (no response sent)")
227
+ except json.JSONDecodeError as e:
228
+ logger.error(f"ERROR: Invalid JSON in request - {e}")
229
+ logger.error(f" Problematic line: {line[:200]}")
230
+ error_response = {
231
+ "jsonrpc": "2.0",
232
+ "id": None,
233
+ "error": {
234
+ "code": -32700,
235
+ "message": f"Parse error: {str(e)}"
236
+ }
221
237
  }
222
- }
223
- print(json.dumps(error_response), flush=True)
224
-
238
+ print(json.dumps(error_response), flush=True)
239
+ sys.stdout.flush()
240
+
241
+ except Exception as e:
242
+ logger.error(f"ERROR: Unexpected error processing request - {str(e)}")
243
+ import traceback
244
+ logger.error(f"Traceback: {traceback.format_exc()}")
245
+ error_response = {
246
+ "jsonrpc": "2.0",
247
+ "id": None,
248
+ "error": {
249
+ "code": -32000,
250
+ "message": f"Error: {str(e)}"
251
+ }
252
+ }
253
+ print(json.dumps(error_response), flush=True)
254
+ sys.stdout.flush()
255
+
256
+ except EOFError:
257
+ logger.info("EOF on stdin, exiting")
258
+ break
259
+ except KeyboardInterrupt:
260
+ logger.info("Server stopped by user")
261
+ break
225
262
  except Exception as e:
226
- logger.error(f"ERROR: Unexpected error processing request - {str(e)}")
263
+ logger.error(f"ERROR in main loop: {str(e)}")
227
264
  import traceback
228
265
  logger.error(f"Traceback: {traceback.format_exc()}")
229
- error_response = {
230
- "jsonrpc": "2.0",
231
- "id": None,
232
- "error": {
233
- "code": -32000,
234
- "message": f"Error: {str(e)}"
235
- }
236
- }
237
- print(json.dumps(error_response), flush=True)
266
+ # Don't break - try to continue
267
+ continue
238
268
 
239
269
  except KeyboardInterrupt:
240
270
  logger.info("Server stopped by user")
241
271
  except Exception as e:
242
272
  logger.error(f"Server error: {str(e)}")
273
+ import traceback
274
+ logger.error(f"Traceback: {traceback.format_exc()}")
243
275
  raise
276
+ finally:
277
+ logger.info("=== EULERIAN MCP PROXY SHUTDOWN ===")
244
278
 
245
279
 
246
280
  if __name__ == "__main__":
247
281
  main()
282
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: eulerian-marketing-platform
3
- Version: 0.2.1
3
+ Version: 0.2.3
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