Skip to content

Commit e27fa5d

Browse files
committed
fix (integrations): bugfixes
1 parent d6eaec2 commit e27fa5d

File tree

10 files changed

+515
-5
lines changed

10 files changed

+515
-5
lines changed

src/server/.env.selfhost.template

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ SLACK_CLIENT_ID=<your-slack-oauth-app-client-id>
4545
SLACK_CLIENT_SECRET=<your-slack-oauth-app-client-secret>
4646
NOTION_CLIENT_ID=<your-notion-oauth-app-client-id>
4747
NOTION_CLIENT_SECRET=<your-notion-oauth-app-client-secret>
48+
DISCORD_BOT_TOKEN=<your-discord-bot-token>
4849
DISCORD_CLIENT_ID=<your-discord-oauth-app-client-id>
4950
DISCORD_CLIENT_SECRET=<your-discord-oauth-app-client-secret>
5051
TODOIST_CLIENT_ID=<your-todoist-oauth-app-client-id>

src/server/.env.template

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ SLACK_CLIENT_ID=<your-slack-oauth-app-client-id>
4848
SLACK_CLIENT_SECRET=<your-slack-oauth-app-client-secret>
4949
NOTION_CLIENT_ID=<your-notion-oauth-app-client-id>
5050
NOTION_CLIENT_SECRET=<your-notion-oauth-app-client-secret>
51+
DISCORD_BOT_TOKEN=<your-discord-bot-token>
5152
DISCORD_CLIENT_ID=<your-discord-oauth-app-client-id>
5253
DISCORD_CLIENT_SECRET=<your-discord-oauth-app-client-secret>
5354
TODOIST_CLIENT_ID=<your-todoist-oauth-app-client-id>

src/server/mcp_hub/discord/auth.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
MONGO_DB_NAME = os.getenv("MONGO_DB_NAME")
2222
AES_SECRET_KEY_HEX = os.getenv("AES_SECRET_KEY")
2323
AES_IV_HEX = os.getenv("AES_IV")
24+
DISCORD_BOT_TOKEN = os.getenv("DISCORD_BOT_TOKEN")
2425

2526
AES_SECRET_KEY: Optional[bytes] = bytes.fromhex(AES_SECRET_KEY_HEX) if AES_SECRET_KEY_HEX and len(AES_SECRET_KEY_HEX) == 64 else None
2627
AES_IV: Optional[bytes] = bytes.fromhex(AES_IV_HEX) if AES_IV_HEX and len(AES_IV_HEX) == 32 else None
@@ -68,10 +69,10 @@ async def get_discord_creds(user_id: str) -> Dict[str, str]:
6869
access_token = token_info.get("access_token")
6970
if not access_token:
7071
raise ToolError("Invalid Discord OAuth token data in database. Re-authentication may be required.")
71-
72-
# Discord OAuth for bots also provides a bot token within the main token response if 'bot' scope is used
73-
bot_token = token_info.get("bot", {}).get("token")
72+
73+
# The bot token is static and comes from the environment, not the user's session
74+
bot_token = DISCORD_BOT_TOKEN
7475
if not bot_token:
75-
raise ToolError("Bot token not found in Discord credentials. Ensure 'bot' scope was granted.")
76+
raise ToolError("Discord Bot Token is not configured on the server. Please set DISCORD_BOT_TOKEN.")
7677

7778
return {"access_token": access_token, "bot_token": bot_token}

src/server/mcp_hub/discord/test_client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
}
1010

1111
mcp_server_url = "http://127.0.0.1:9022/sse"
12-
USER_ID = "YOUR_USER_ID_HERE"
12+
USER_ID = "google-oauth2|115437244827618197332"
1313

1414
tools = [{
1515
"mcpServers": {
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import json
2+
from qwen_agent.agents import Assistant
3+
4+
# --- Configuration ---
5+
llm_cfg = {
6+
'model': 'qwen3:4b',
7+
'model_server': 'http://localhost:11434/v1/',
8+
'api_key': 'EMPTY',
9+
}
10+
11+
# Evernote MCP Server Configuration
12+
mcp_server_url = "http://127.0.0.1:9023/sse"
13+
14+
# IMPORTANT: Replace with a valid User ID from your MongoDB that has Evernote credentials
15+
USER_ID = "YOUR_USER_ID_HERE"
16+
17+
# --- Agent Setup ---
18+
tools = [{
19+
"mcpServers": {
20+
"evernote_server": {
21+
"url": mcp_server_url,
22+
"headers": {"X-User-ID": USER_ID},
23+
}
24+
}
25+
}]
26+
27+
print("Initializing Qwen agent for Evernote...")
28+
agent = Assistant(
29+
llm=llm_cfg,
30+
function_list=tools,
31+
name="EvernoteAgent",
32+
description="An agent that can manage Evernote notes.",
33+
system_message=(
34+
"You are a helpful Evernote assistant. Use `list_notebooks` to find a notebook ID before creating a note."
35+
)
36+
)
37+
38+
# --- Interactive Chat Loop ---
39+
def run_agent_interaction():
40+
print("\n--- Evernote Agent Ready ---")
41+
print("You can now interact with your Evernote account.")
42+
print("Type 'quit' or 'exit' to end the session.")
43+
print("\nExample commands:")
44+
print(" - list my notebooks")
45+
print(" - create a note in notebook with ID '...' titled 'My Test Note' with content 'Hello world.'")
46+
print("-" * 25)
47+
48+
messages = []
49+
while True:
50+
try:
51+
print("\nYou: ", end="")
52+
user_input = input()
53+
if user_input.lower() in ["quit", "exit", "q"]:
54+
print("\n👋 Goodbye!")
55+
break
56+
57+
messages.append({'role': 'user', 'content': user_input})
58+
print("\nAgent: ", end="", flush=True)
59+
60+
last_assistant_text = ""
61+
final_response_from_run = None
62+
for response in agent.run(messages=messages):
63+
if isinstance(response, list) and response and response[-1].get("role") == "assistant":
64+
current_text = response[-1].get("content", "")
65+
if isinstance(current_text, str):
66+
delta = current_text[len(last_assistant_text):]
67+
print(delta, end="", flush=True)
68+
last_assistant_text = current_text
69+
final_response_from_run = response
70+
71+
print()
72+
if final_response_from_run:
73+
messages = final_response_from_run
74+
else:
75+
print("I could not process that request.")
76+
messages.pop()
77+
78+
except KeyboardInterrupt:
79+
print("\n👋 Goodbye!")
80+
break
81+
except Exception as e:
82+
print(f"\nAn error occurred: {e}")
83+
84+
if __name__ == "__main__":
85+
run_agent_interaction()
86+
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import json
2+
from qwen_agent.agents import Assistant
3+
4+
# --- Configuration ---
5+
llm_cfg = {
6+
'model': 'qwen3:4b',
7+
'model_server': 'http://localhost:11434/v1/',
8+
'api_key': 'EMPTY',
9+
}
10+
11+
# Progress Updater MCP Server Configuration
12+
mcp_server_url = "http://127.0.0.1:9011/sse"
13+
USER_ID = "test_user"
14+
15+
# --- Agent Setup ---
16+
tools = [{
17+
"mcpServers": {
18+
"progress_updater_server": {
19+
"url": mcp_server_url,
20+
"headers": {"X-User-ID": USER_ID},
21+
}
22+
}
23+
}]
24+
25+
print("Initializing Qwen agent for Progress Updater...")
26+
agent = Assistant(
27+
llm=llm_cfg,
28+
function_list=tools,
29+
name="ProgressUpdaterAgent",
30+
description="An agent that can send progress updates for a task.",
31+
system_message="You are an executor agent. When you perform an action, you must report it using the `update_progress` tool."
32+
)
33+
34+
# --- Interactive Chat Loop ---
35+
def run_agent_interaction():
36+
print("\n--- Progress Updater Agent Ready ---")
37+
print("Simulate an executor agent sending progress updates.")
38+
print("Type 'quit' or 'exit' to end the session.")
39+
print("\nExample command:")
40+
print(" - update progress for task 'task-123' with message 'Step 1 completed successfully.'")
41+
print("-" * 25)
42+
43+
messages = []
44+
while True:
45+
try:
46+
print("\nYou: ", end="")
47+
user_input = input()
48+
if user_input.lower() in ["quit", "exit", "q"]:
49+
print("\n👋 Goodbye!")
50+
break
51+
52+
messages.append({'role': 'user', 'content': user_input})
53+
print("\nAgent: ", end="", flush=True)
54+
55+
last_assistant_text = ""
56+
final_response_from_run = None
57+
for response in agent.run(messages=messages):
58+
if isinstance(response, list) and response and response[-1].get("role") == "assistant":
59+
current_text = response[-1].get("content", "")
60+
if isinstance(current_text, str):
61+
delta = current_text[len(last_assistant_text):]
62+
print(delta, end="", flush=True)
63+
last_assistant_text = current_text
64+
final_response_from_run = response
65+
66+
print()
67+
if final_response_from_run:
68+
messages = final_response_from_run
69+
else:
70+
print("I could not process that request.")
71+
messages.pop()
72+
73+
except KeyboardInterrupt:
74+
print("\n👋 Goodbye!")
75+
break
76+
except Exception as e:
77+
print(f"\nAn error occurred: {e}")
78+
79+
if __name__ == "__main__":
80+
run_agent_interaction()
81+
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import json
2+
from qwen_agent.agents import Assistant
3+
4+
# --- Configuration ---
5+
llm_cfg = {
6+
'model': 'qwen3:4b',
7+
'model_server': 'http://localhost:11434/v1/',
8+
'api_key': 'EMPTY',
9+
}
10+
11+
# Tasks MCP Server Configuration
12+
mcp_server_url = "http://127.0.0.1:9018/sse"
13+
14+
# IMPORTANT: Replace with a valid User ID from your MongoDB
15+
USER_ID = "YOUR_USER_ID_HERE"
16+
17+
# --- Agent Setup ---
18+
tools = [{
19+
"mcpServers": {
20+
"tasks_server": {
21+
"url": mcp_server_url,
22+
"headers": {"X-User-ID": USER_ID},
23+
}
24+
}
25+
}]
26+
27+
print("Initializing Qwen agent for Tasks...")
28+
agent = Assistant(
29+
llm=llm_cfg,
30+
function_list=tools,
31+
name="TaskCreatorAgent",
32+
description="An agent that creates tasks from natural language.",
33+
system_message="You are an assistant that creates tasks. Use the `create_task_from_prompt` tool to do so."
34+
)
35+
36+
# --- Interactive Chat Loop ---
37+
def run_agent_interaction():
38+
print("\n--- Task Creator Agent Ready ---")
39+
print("Describe the task you want to create.")
40+
print("Type 'quit' or 'exit' to end the session.")
41+
print("\nExample commands:")
42+
print(" - create a task to write a blog post about AI for next Friday")
43+
print(" - add a to-do to call the doctor tomorrow morning")
44+
print("-" * 25)
45+
46+
messages = []
47+
while True:
48+
try:
49+
print("\nYou: ", end="")
50+
user_input = input()
51+
if user_input.lower() in ["quit", "exit", "q"]:
52+
print("\n👋 Goodbye!")
53+
break
54+
55+
messages.append({'role': 'user', 'content': user_input})
56+
print("\nAgent: ", end="", flush=True)
57+
58+
last_assistant_text = ""
59+
final_response_from_run = None
60+
for response in agent.run(messages=messages):
61+
if isinstance(response, list) and response and response[-1].get("role") == "assistant":
62+
current_text = response[-1].get("content", "")
63+
if isinstance(current_text, str):
64+
delta = current_text[len(last_assistant_text):]
65+
print(delta, end="", flush=True)
66+
last_assistant_text = current_text
67+
final_response_from_run = response
68+
69+
print()
70+
if final_response_from_run:
71+
messages = final_response_from_run
72+
else:
73+
print("I could not process that request.")
74+
messages.pop()
75+
76+
except KeyboardInterrupt:
77+
print("\n👋 Goodbye!")
78+
break
79+
except Exception as e:
80+
print(f"\nAn error occurred: {e}")
81+
82+
if __name__ == "__main__":
83+
run_agent_interaction()
84+
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# src/server/mcp_hub/todoist/test_client.py
2+
import json
3+
from qwen_agent.agents import Assistant
4+
5+
# --- Configuration ---
6+
llm_cfg = {
7+
'model': 'qwen3:4b',
8+
'model_server': 'http://localhost:11434/v1/',
9+
'api_key': 'EMPTY',
10+
}
11+
12+
# Todoist MCP Server Configuration
13+
mcp_server_url = "http://127.0.0.1:9021/sse"
14+
15+
# IMPORTANT: Replace with a valid User ID from your MongoDB that has Todoist credentials
16+
USER_ID = "google-oauth2|115437244827618197332"
17+
18+
# --- Agent Setup ---
19+
tools = [{
20+
"mcpServers": {
21+
"todoist_server": {
22+
"url": mcp_server_url,
23+
"headers": {"X-User-ID": USER_ID},
24+
}
25+
}
26+
}]
27+
28+
print("Initializing Qwen agent for Todoist...")
29+
agent = Assistant(
30+
llm=llm_cfg,
31+
function_list=tools,
32+
name="TodoistAgent",
33+
description="An agent that can manage Todoist tasks.",
34+
system_message="You are a helpful Todoist assistant. Use the available tools to manage projects and tasks."
35+
)
36+
37+
# --- Interactive Chat Loop ---
38+
def run_agent_interaction():
39+
print("\n--- Todoist Agent Ready ---")
40+
print("You can now manage your Todoist tasks.")
41+
print("Type 'quit' or 'exit' to end the session.")
42+
print("\nExample commands:")
43+
print(" - list my projects")
44+
print(" - what are my tasks for today?")
45+
print(" - add a task 'Buy milk' to my Inbox project")
46+
print(" - complete the task with ID '...'")
47+
print("-" * 25)
48+
49+
messages = []
50+
while True:
51+
try:
52+
print("\nYou: ", end="")
53+
user_input = input()
54+
if user_input.lower() in ["quit", "exit", "q"]:
55+
print("\n👋 Goodbye!")
56+
break
57+
58+
messages.append({'role': 'user', 'content': user_input})
59+
print("\nAgent: ", end="", flush=True)
60+
61+
last_assistant_text = ""
62+
final_response_from_run = None
63+
for response in agent.run(messages=messages):
64+
if isinstance(response, list) and response and response[-1].get("role") == "assistant":
65+
current_text = response[-1].get("content", "")
66+
if isinstance(current_text, str):
67+
delta = current_text[len(last_assistant_text):]
68+
print(delta, end="", flush=True)
69+
last_assistant_text = current_text
70+
final_response_from_run = response
71+
72+
print()
73+
if final_response_from_run:
74+
messages = final_response_from_run
75+
else:
76+
print("I could not process that request.")
77+
messages.pop()
78+
79+
except KeyboardInterrupt:
80+
print("\n👋 Goodbye!")
81+
break
82+
except Exception as e:
83+
print(f"\nAn error occurred: {e}")
84+
85+
if __name__ == "__main__":
86+
run_agent_interaction()
87+

0 commit comments

Comments
 (0)