eulerian-marketing-platform 0.1.1__tar.gz → 0.1.2__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.
- {eulerian_marketing_platform-0.1.1 → eulerian_marketing_platform-0.1.2}/PKG-INFO +1 -1
- {eulerian_marketing_platform-0.1.1 → eulerian_marketing_platform-0.1.2}/pyproject.toml +1 -1
- {eulerian_marketing_platform-0.1.1 → eulerian_marketing_platform-0.1.2}/setup.cfg +1 -1
- {eulerian_marketing_platform-0.1.1 → eulerian_marketing_platform-0.1.2}/src/eulerian_marketing_platform/__init__.py +8 -4
- {eulerian_marketing_platform-0.1.1 → eulerian_marketing_platform-0.1.2}/src/eulerian_marketing_platform/server.py +75 -129
- {eulerian_marketing_platform-0.1.1 → eulerian_marketing_platform-0.1.2}/src/eulerian_marketing_platform.egg-info/PKG-INFO +1 -1
- {eulerian_marketing_platform-0.1.1 → eulerian_marketing_platform-0.1.2}/.env.example +0 -0
- {eulerian_marketing_platform-0.1.1 → eulerian_marketing_platform-0.1.2}/LICENSE +0 -0
- {eulerian_marketing_platform-0.1.1 → eulerian_marketing_platform-0.1.2}/MANIFEST.in +0 -0
- {eulerian_marketing_platform-0.1.1 → eulerian_marketing_platform-0.1.2}/README.md +0 -0
- {eulerian_marketing_platform-0.1.1 → eulerian_marketing_platform-0.1.2}/requirements.txt +0 -0
- {eulerian_marketing_platform-0.1.1 → eulerian_marketing_platform-0.1.2}/src/eulerian_marketing_platform.egg-info/SOURCES.txt +0 -0
- {eulerian_marketing_platform-0.1.1 → eulerian_marketing_platform-0.1.2}/src/eulerian_marketing_platform.egg-info/dependency_links.txt +0 -0
- {eulerian_marketing_platform-0.1.1 → eulerian_marketing_platform-0.1.2}/src/eulerian_marketing_platform.egg-info/entry_points.txt +0 -0
- {eulerian_marketing_platform-0.1.1 → eulerian_marketing_platform-0.1.2}/src/eulerian_marketing_platform.egg-info/requires.txt +0 -0
- {eulerian_marketing_platform-0.1.1 → eulerian_marketing_platform-0.1.2}/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.1.
|
|
3
|
+
Version: 0.1.2
|
|
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.1.
|
|
7
|
+
version = "0.1.2"
|
|
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 = [
|
|
@@ -4,8 +4,12 @@ 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
|
-
|
|
8
|
-
|
|
9
|
-
__version__ = "0.1.1"
|
|
7
|
+
__version__ = "0.1.2"
|
|
10
8
|
__author__ = "Eulerian Technologies"
|
|
11
|
-
__all__ = [
|
|
9
|
+
__all__ = []
|
|
10
|
+
|
|
11
|
+
# Import main only when explicitly requested
|
|
12
|
+
def get_main():
|
|
13
|
+
"""Lazy import of main function to avoid side effects."""
|
|
14
|
+
from .server import main
|
|
15
|
+
return main
|
|
@@ -37,15 +37,20 @@ log_dir = os.path.dirname(LOG_FILE)
|
|
|
37
37
|
if log_dir: # Only create if there's a directory part
|
|
38
38
|
os.makedirs(log_dir, exist_ok=True)
|
|
39
39
|
|
|
40
|
-
# Configure logging to file and stderr
|
|
40
|
+
# Configure logging to file and stderr with UTF-8 encoding for cross-platform compatibility
|
|
41
|
+
file_handler = logging.FileHandler(LOG_FILE, encoding='utf-8')
|
|
42
|
+
file_handler.setLevel(logging.INFO)
|
|
43
|
+
file_handler.setFormatter(logging.Formatter("[%(asctime)s] %(levelname)s: %(message)s", datefmt="%Y-%m-%d %H:%M:%S"))
|
|
44
|
+
|
|
45
|
+
# For stderr, use system encoding with error handling
|
|
46
|
+
stream_handler = logging.StreamHandler(sys.stderr)
|
|
47
|
+
stream_handler.setLevel(logging.INFO)
|
|
48
|
+
stream_handler.setFormatter(logging.Formatter("[%(asctime)s] %(levelname)s: %(message)s", datefmt="%Y-%m-%d %H:%M:%S"))
|
|
49
|
+
|
|
50
|
+
# Configure root logger
|
|
41
51
|
logging.basicConfig(
|
|
42
52
|
level=logging.INFO,
|
|
43
|
-
|
|
44
|
-
datefmt="%Y-%m-%d %H:%M:%S",
|
|
45
|
-
handlers=[
|
|
46
|
-
logging.FileHandler(LOG_FILE),
|
|
47
|
-
logging.StreamHandler(sys.stderr)
|
|
48
|
-
]
|
|
53
|
+
handlers=[file_handler, stream_handler]
|
|
49
54
|
)
|
|
50
55
|
logger = logging.getLogger(__name__)
|
|
51
56
|
|
|
@@ -156,137 +161,78 @@ class EulerianMCPProxy:
|
|
|
156
161
|
raise Exception(f"Invalid JSON response: {str(e)}")
|
|
157
162
|
|
|
158
163
|
|
|
159
|
-
# Create global proxy instance
|
|
160
|
-
proxy = EulerianMCPProxy()
|
|
161
|
-
|
|
162
|
-
# Create FastMCP server
|
|
163
|
-
mcp = FastMCP("eulerian-marketing-platform")
|
|
164
|
-
|
|
165
|
-
|
|
166
164
|
# Dynamically fetch and register tools from remote server
|
|
167
|
-
|
|
168
|
-
async def list_remote_tools() -> dict[str, Any]:
|
|
169
|
-
"""List all available tools from the remote Eulerian MCP server.
|
|
170
|
-
|
|
171
|
-
This tool queries the remote MCP server to discover what tools are available.
|
|
172
|
-
Use this to see what operations you can perform on the Eulerian platform.
|
|
173
|
-
|
|
174
|
-
Returns:
|
|
175
|
-
Dictionary containing the list of available tools with their descriptions
|
|
176
|
-
"""
|
|
177
|
-
try:
|
|
178
|
-
result = await proxy.forward_request("tools/list")
|
|
179
|
-
return result
|
|
180
|
-
except Exception as e:
|
|
181
|
-
logger.error(f"Failed to list tools: {str(e)}")
|
|
182
|
-
return {"error": str(e), "tools": []}
|
|
165
|
+
# (Tools are registered in main() to avoid running on import)
|
|
183
166
|
|
|
184
167
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
This is a generic tool that forwards requests to the remote Eulerian platform.
|
|
190
|
-
First use list_remote_tools() to see what tools are available, then call them
|
|
191
|
-
using this function.
|
|
192
|
-
|
|
193
|
-
Args:
|
|
194
|
-
tool_name: The name of the tool to call on the remote server
|
|
195
|
-
arguments: Dictionary of arguments to pass to the tool (optional)
|
|
196
|
-
|
|
197
|
-
Returns:
|
|
198
|
-
The result from the remote tool execution
|
|
199
|
-
|
|
200
|
-
Example:
|
|
201
|
-
To call a tool named "search_goal" with no arguments:
|
|
202
|
-
>>> call_eulerian_tool("search_goal")
|
|
203
|
-
|
|
204
|
-
To call a tool with arguments:
|
|
205
|
-
>>> call_eulerian_tool("update_goal", {"action-id": "12345","action-name":"test-mcp"})
|
|
206
|
-
"""
|
|
207
|
-
if arguments is None:
|
|
208
|
-
arguments = {}
|
|
168
|
+
def main() -> None:
|
|
169
|
+
"""Entry point for the MCP proxy server."""
|
|
170
|
+
# Validate configuration before starting
|
|
171
|
+
validate_config()
|
|
209
172
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
}
|
|
215
|
-
result = await proxy.forward_request("tools/call", params)
|
|
216
|
-
return result
|
|
217
|
-
except Exception as e:
|
|
218
|
-
logger.error(f"Failed to call tool '{tool_name}': {str(e)}")
|
|
219
|
-
return {"error": str(e), "tool": tool_name}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
@mcp.tool()
|
|
223
|
-
async def get_eulerian_resources() -> dict[str, Any]:
|
|
224
|
-
"""List all available resources from the remote Eulerian MCP server.
|
|
173
|
+
# Create proxy and server instances (moved here to avoid running on import)
|
|
174
|
+
global proxy, mcp
|
|
175
|
+
proxy = EulerianMCPProxy()
|
|
176
|
+
mcp = FastMCP("eulerian-marketing-platform")
|
|
225
177
|
|
|
226
|
-
|
|
227
|
-
|
|
178
|
+
# Register tools
|
|
179
|
+
@mcp.tool()
|
|
180
|
+
async def list_remote_tools() -> dict[str, Any]:
|
|
181
|
+
"""List all available tools from the remote Eulerian MCP server."""
|
|
182
|
+
try:
|
|
183
|
+
result = await proxy.forward_request("tools/list")
|
|
184
|
+
return result
|
|
185
|
+
except Exception as e:
|
|
186
|
+
logger.error(f"Failed to list tools: {str(e)}")
|
|
187
|
+
return {"error": str(e), "tools": []}
|
|
228
188
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
async def read_eulerian_resource(uri: str) -> dict[str, Any]:
|
|
242
|
-
"""Read a specific resource from the remote Eulerian MCP server.
|
|
189
|
+
@mcp.tool()
|
|
190
|
+
async def call_eulerian_tool(tool_name: str, arguments: dict[str, Any] = None) -> dict[str, Any]:
|
|
191
|
+
"""Call a tool on the remote Eulerian MCP server."""
|
|
192
|
+
if arguments is None:
|
|
193
|
+
arguments = {}
|
|
194
|
+
try:
|
|
195
|
+
params = {"name": tool_name, "arguments": arguments}
|
|
196
|
+
result = await proxy.forward_request("tools/call", params)
|
|
197
|
+
return result
|
|
198
|
+
except Exception as e:
|
|
199
|
+
logger.error(f"Failed to call tool '{tool_name}': {str(e)}")
|
|
200
|
+
return {"error": str(e), "tool": tool_name}
|
|
243
201
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
try:
|
|
254
|
-
params = {"uri": uri}
|
|
255
|
-
result = await proxy.forward_request("resources/read", params)
|
|
256
|
-
return result
|
|
257
|
-
except Exception as e:
|
|
258
|
-
logger.error(f"Failed to read resource '{uri}': {str(e)}")
|
|
259
|
-
return {"error": str(e), "uri": uri}
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
@mcp.tool()
|
|
263
|
-
async def get_server_info() -> dict[str, Any]:
|
|
264
|
-
"""Get information about the remote Eulerian MCP server.
|
|
202
|
+
@mcp.tool()
|
|
203
|
+
async def get_eulerian_resources() -> dict[str, Any]:
|
|
204
|
+
"""List all available resources from the remote Eulerian MCP server."""
|
|
205
|
+
try:
|
|
206
|
+
result = await proxy.forward_request("resources/list")
|
|
207
|
+
return result
|
|
208
|
+
except Exception as e:
|
|
209
|
+
logger.error(f"Failed to list resources: {str(e)}")
|
|
210
|
+
return {"error": str(e), "resources": []}
|
|
265
211
|
|
|
266
|
-
|
|
212
|
+
@mcp.tool()
|
|
213
|
+
async def read_eulerian_resource(uri: str) -> dict[str, Any]:
|
|
214
|
+
"""Read a specific resource from the remote Eulerian MCP server."""
|
|
215
|
+
try:
|
|
216
|
+
params = {"uri": uri}
|
|
217
|
+
result = await proxy.forward_request("resources/read", params)
|
|
218
|
+
return result
|
|
219
|
+
except Exception as e:
|
|
220
|
+
logger.error(f"Failed to read resource '{uri}': {str(e)}")
|
|
221
|
+
return {"error": str(e), "uri": uri}
|
|
267
222
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
except Exception as e:
|
|
282
|
-
logger.error(f"Failed to get server info: {str(e)}")
|
|
283
|
-
return {"error": str(e)}
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
def main() -> None:
|
|
287
|
-
"""Entry point for the MCP proxy server."""
|
|
288
|
-
# Validate configuration before starting
|
|
289
|
-
validate_config()
|
|
223
|
+
@mcp.tool()
|
|
224
|
+
async def get_server_info() -> dict[str, Any]:
|
|
225
|
+
"""Get information about the remote Eulerian MCP server."""
|
|
226
|
+
try:
|
|
227
|
+
result = await proxy.forward_request("initialize", {
|
|
228
|
+
"protocolVersion": "2024-11-05",
|
|
229
|
+
"capabilities": {},
|
|
230
|
+
"clientInfo": {"name": "eulerian-mcp-proxy", "version": "0.1.1"}
|
|
231
|
+
})
|
|
232
|
+
return result
|
|
233
|
+
except Exception as e:
|
|
234
|
+
logger.error(f"Failed to get server info: {str(e)}")
|
|
235
|
+
return {"error": str(e)}
|
|
290
236
|
|
|
291
237
|
logger.info("Starting Eulerian MCP Proxy Server...")
|
|
292
238
|
logger.info("Available tools:")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: eulerian-marketing-platform
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|