Add SMD MCP Server implementation and utilities
Implemented the SMD MCP Server with functionality for AI-driven research and article retrieval via the MCP protocol. Added utilities for prompt creation and enhanced dependency configuration. This serves as a foundation for handling SMD-related queries and data processing.
This commit is contained in:
parent
47c036a973
commit
3b75d04f32
4 changed files with 181 additions and 2 deletions
|
@ -1,6 +1,6 @@
|
||||||
# GPT Researcher dependencies
|
# GPT Researcher dependencies
|
||||||
gpt-researcher>=0.12.16
|
gpt-researcher>=0.12.16
|
||||||
python-dotenv
|
python-dotenv~=1.1.0
|
||||||
|
|
||||||
# MCP dependencies
|
# MCP dependencies
|
||||||
mcp>=1.6.0
|
mcp>=1.6.0
|
||||||
|
@ -10,3 +10,4 @@ pydantic>=2.3.0
|
||||||
|
|
||||||
# Utility dependencies
|
# Utility dependencies
|
||||||
loguru>=0.7.0
|
loguru>=0.7.0
|
||||||
|
requests~=2.32.3
|
8
src/phoenix_technologies/smd/__init__.py
Normal file
8
src/phoenix_technologies/smd/__init__.py
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
"""
|
||||||
|
SMD MCP Server
|
||||||
|
|
||||||
|
This module provides an MCP server implementation for SMD,
|
||||||
|
allowing AI assistants to perform searches and generate reports via the MCP protocol.
|
||||||
|
"""
|
||||||
|
|
||||||
|
__version__ = "0.1.0"
|
121
src/phoenix_technologies/smd/server.py
Normal file
121
src/phoenix_technologies/smd/server.py
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
"""
|
||||||
|
SMD Researcher MCP Server
|
||||||
|
|
||||||
|
This script implements an MCP server for SMD Researcher, allowing AI assistants
|
||||||
|
to conduct research and generate reports via the MCP protocol.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import logging
|
||||||
|
import requests
|
||||||
|
from dotenv import load_dotenv
|
||||||
|
from mcp.server.fastmcp import FastMCP
|
||||||
|
|
||||||
|
# Load environment variables
|
||||||
|
load_dotenv()
|
||||||
|
|
||||||
|
from utils import (
|
||||||
|
create_research_prompt
|
||||||
|
)
|
||||||
|
|
||||||
|
logging.basicConfig(
|
||||||
|
level=logging.INFO,
|
||||||
|
format='[%(asctime)s][%(levelname)s] - %(message)s',
|
||||||
|
)
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
# Initialize FastMCP server
|
||||||
|
mcp = FastMCP("SMD Researcher")
|
||||||
|
|
||||||
|
@mcp.tool()
|
||||||
|
async def smd_detail_article(article_id: str) -> dict:
|
||||||
|
"""
|
||||||
|
Get the Details of an article found by the SMD Research.
|
||||||
|
Use this tool when you need the full content of an article.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
article_id: The ID of the article to get the details for
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
String containing the details of the article
|
||||||
|
"""
|
||||||
|
url = f"https://api.smd.ch/api/documents/{article_id}"
|
||||||
|
headers = {
|
||||||
|
"authorization": f"Bearer {os.getenv('SWISSDOX_BEARER_TOKEN', '')}",
|
||||||
|
"content-type": "application/json",
|
||||||
|
}
|
||||||
|
payload = {"filters": [], "pagination": {"pageSize": 1, "currentPage": 1}}
|
||||||
|
response = requests.post(url, headers=headers, json=payload)
|
||||||
|
if response.status_code == 200:
|
||||||
|
return response.json()
|
||||||
|
else:
|
||||||
|
return {
|
||||||
|
"message": response.text
|
||||||
|
}
|
||||||
|
|
||||||
|
@mcp.tool()
|
||||||
|
async def smd_research(query: dict) -> dict:
|
||||||
|
"""
|
||||||
|
Execute a deep search on a given query using SMD Researcher.
|
||||||
|
Use this tool when you need research on a topic.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
query: The research query or topic
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
String containing research status, ID, and the actual research context
|
||||||
|
"""
|
||||||
|
url = "https://api.swissdox.ch/api/documents/search"
|
||||||
|
headers = {
|
||||||
|
"authorization": f"Bearer {os.getenv('SWISSDOX_BEARER_TOKEN', '')}",
|
||||||
|
"content-type": "application/json",
|
||||||
|
}
|
||||||
|
response = requests.post(url, headers=headers, json=query)
|
||||||
|
if response.status_code == 200:
|
||||||
|
return response.json()
|
||||||
|
else:
|
||||||
|
return {
|
||||||
|
"message": response.text
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@mcp.prompt()
|
||||||
|
def research_query(search_query: str = "Bundesrat", date_from: str = "2024-05-30T22:00:00.000Z", date_to: str = "2025-05-31T21:59:59.999Z") -> dict:
|
||||||
|
"""
|
||||||
|
Create a research query prompt for SMD Researcher.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
search_query: The SMD search query, there are Logical Operators available (AND, OR, NOT) and for a excact match use "+" before the word. For excluding use "-" before the word. For queries with multiple words use quotes.
|
||||||
|
date_from: The date to start research from, in the format YYYY-MM-DDTHH:MM:SS.SSSZ
|
||||||
|
date_to: The date to end research at, in the format YYYY-MM-DDTHH:MM:SS.SSSZ
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A formatted prompt for research
|
||||||
|
"""
|
||||||
|
return create_research_prompt(search_query,date_from,date_to)
|
||||||
|
|
||||||
|
|
||||||
|
def run_server():
|
||||||
|
"""Run the MCP server using FastMCP's built-in event loop handling."""
|
||||||
|
|
||||||
|
# Add startup message
|
||||||
|
logger.info("Starting GPT Researcher MCP Server...")
|
||||||
|
print("🚀 GPT Researcher MCP Server starting... Check researcher_mcp_server.log for details")
|
||||||
|
|
||||||
|
# Let FastMCP handle the event loop
|
||||||
|
try:
|
||||||
|
mcp.run("sse")
|
||||||
|
# Note: If we reach here, the server has stopped
|
||||||
|
logger.info("MCP Server has stopped")
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error running MCP server: {str(e)}")
|
||||||
|
print(f"❌ MCP Server error: {str(e)}")
|
||||||
|
return
|
||||||
|
|
||||||
|
print("✅ MCP Server stopped")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
# Use the non-async approach to avoid asyncio nesting issues
|
||||||
|
run_server()
|
49
src/phoenix_technologies/smd/utils.py
Normal file
49
src/phoenix_technologies/smd/utils.py
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
"""
|
||||||
|
SMD Researcher MCP Server Utilities
|
||||||
|
|
||||||
|
This module provides utility functions and helpers for the SMD Researcher MCP Server.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from loguru import logger
|
||||||
|
|
||||||
|
# Configure logging for console only (no file logging)
|
||||||
|
logger.configure(handlers=[{"sink": sys.stderr, "level": "INFO"}])
|
||||||
|
|
||||||
|
def create_research_prompt(search_query: str = "Bundesrat", date_from: str = "2024-05-30T22:00:00.000Z", date_to: str = "2025-05-31T21:59:59.999Z") -> dict:
|
||||||
|
"""
|
||||||
|
Create a research query prompt for SMD Researcher.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
search_query: The SMD search query, there are Logical Operators available (AND, OR, NOT) and for a excact match use "+" before the word. For excluding use "-" before the word. For queries with multiple words use quotes.
|
||||||
|
date_from: The date to start research from, in the format YYYY-MM-DDTHH:MM:SS.SSSZ
|
||||||
|
date_to: The date to end research at, in the format YYYY-MM-DDTHH:MM:SS.SSSZ
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A formatted prompt for research as a Python dictionary.
|
||||||
|
"""
|
||||||
|
return {
|
||||||
|
"sort": {
|
||||||
|
"field": "score",
|
||||||
|
"direction": "desc"
|
||||||
|
},
|
||||||
|
"filters": [
|
||||||
|
{
|
||||||
|
"field": "datetime",
|
||||||
|
"value": [
|
||||||
|
date_from,
|
||||||
|
date_to
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"field": "query_text",
|
||||||
|
"value": [search_query]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"exact": False,
|
||||||
|
"pagination": {
|
||||||
|
"pageSize": 10,
|
||||||
|
"currentPage": 1
|
||||||
|
},
|
||||||
|
"onlyResults": True
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue