Skip to content

Commit f3c0d4c

Browse files
Merge pull request #429 from MervinPraison/develop
Add MCP integration for stock price retrieval
2 parents cbc6939 + 5fc8c0b commit f3c0d4c

20 files changed

Lines changed: 1294 additions & 11 deletions

pyproject.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "PraisonAI"
3-
version = "2.0.80"
3+
version = "2.0.81"
44
description = "PraisonAI is an AI Agents Framework with Self Reflection. PraisonAI application combines PraisonAI Agents, AutoGen, and CrewAI into a low-code solution for building and managing multi-agent LLM systems, focusing on simplicity, customisation, and efficient human-agent collaboration."
55
readme = "README.md"
66
license = ""
@@ -12,7 +12,7 @@ dependencies = [
1212
"rich>=13.7",
1313
"markdown>=3.5",
1414
"pyparsing>=3.0.0",
15-
"praisonaiagents>=0.0.65",
15+
"praisonaiagents>=0.0.67",
1616
"python-dotenv>=0.19.0",
1717
"instructor>=1.3.3",
1818
"PyYAML>=6.0",
@@ -102,7 +102,7 @@ python = ">=3.10,<3.13"
102102
rich = ">=13.7"
103103
markdown = ">=3.5"
104104
pyparsing = ">=3.0.0"
105-
praisonaiagents = ">=0.0.65"
105+
praisonaiagents = ">=0.0.67"
106106
python-dotenv = ">=0.19.0"
107107
instructor = ">=1.3.3"
108108
PyYAML = ">=6.0"
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from praisonaiagents import Agent, MCP
2+
3+
agent = Agent(
4+
instructions="""You are a helpful assistant that can check stock prices and perform other tasks.
5+
Use the available tools when relevant to answer user questions.""",
6+
llm="gpt-4o-mini",
7+
tools=MCP(
8+
command="/Users/praison/miniconda3/envs/mcp/bin/python",
9+
args=["/Users/praison/stockprice/app.py"]
10+
)
11+
)
12+
13+
agent.start("What is the stock price of Tesla?")

src/praisonai-agents/mcp-agents.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from praisonaiagents import Agent, MCP
2+
3+
agent = Agent(
4+
instructions="""You are a helpful assistant that can check stock prices and perform other tasks.
5+
Use the available tools when relevant to answer user questions.""",
6+
llm="gpt-4o-mini",
7+
tools = MCP("/Users/praison/miniconda3/envs/mcp/bin/python /Users/praison/stockprice/app.py")
8+
)
9+
10+
agent.start("What is the stock price of Tesla?")

src/praisonai-agents/mcp-basic.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import asyncio
2+
from praisonaiagents import Agent
3+
from mcp import ClientSession, StdioServerParameters
4+
from mcp.client.stdio import stdio_client
5+
6+
# Define server configuration - pointing to your stock price app
7+
server_params = StdioServerParameters(
8+
command="/Users/praison/miniconda3/envs/mcp/bin/python",
9+
args=[
10+
"/Users/praison/stockprice/app.py",
11+
],
12+
)
13+
14+
# Function to get stock price using MCP
15+
async def get_stock_price(symbol):
16+
# Start server and connect client
17+
async with stdio_client(server_params) as (read, write):
18+
async with ClientSession(read, write) as session:
19+
# Initialize the connection
20+
await session.initialize()
21+
22+
# Get tools
23+
tools_result = await session.list_tools()
24+
tools = tools_result.tools
25+
print(f"Available tools: {[tool.name for tool in tools]}")
26+
27+
# Find a tool that can get stock prices
28+
# Assuming there's a tool like "get_stock_price" or similar
29+
stock_tool = None
30+
for tool in tools:
31+
if "stock" in tool.name.lower() or "price" in tool.name.lower():
32+
stock_tool = tool
33+
break
34+
35+
if stock_tool:
36+
print(f"Using tool: {stock_tool.name}")
37+
# Call the tool with the stock symbol
38+
result = await session.call_tool(
39+
stock_tool.name,
40+
arguments={"ticker": symbol}
41+
)
42+
return result
43+
else:
44+
return "No suitable stock price tool found"
45+
46+
# Create a custom tool for the agent
47+
def stock_price_tool(symbol: str) -> str:
48+
"""Get the current stock price for a given symbol"""
49+
# Run the async function to get the stock price
50+
result = asyncio.run(get_stock_price(symbol))
51+
return f"Stock price for {symbol}: {result}"
52+
53+
# Create agent with the stock price tool
54+
agent = Agent(
55+
instructions="You are a helpful assistant that can check stock prices. When asked about stock prices, use the stock_price_tool.",
56+
llm="gpt-4o-mini",
57+
tools=[stock_price_tool]
58+
)
59+
60+
# Start the agent
61+
agent.start("What is the stock price of Tesla?")
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
from praisonaiagents import Agent, MCP
2+
import os
3+
stock_agent = Agent(
4+
instructions="""You are a helpful assistant that can check stock prices and perform other tasks.
5+
Use the available tools when relevant to answer user questions.""",
6+
llm="gpt-4o-mini",
7+
tools=MCP(
8+
command="/Users/praison/miniconda3/envs/mcp/bin/python",
9+
args=["/Users/praison/stockprice/app.py"]
10+
)
11+
)
12+
13+
brave_api_key = os.getenv("BRAVE_API_KEY")
14+
15+
search_agent = Agent(
16+
instructions="""You are a helpful assistant that can search the web for information.
17+
Use the available tools when relevant to answer user questions.""",
18+
llm="gpt-4o-mini",
19+
tools=MCP(f'npx -y @smithery/cli@latest install @smithery-ai/brave-search --client claude --config "{{\\\"braveApiKey\\\":\\\"{brave_api_key}\\\"}}"')
20+
)
21+
22+
stock_agent.start("What is the stock price of Tesla?")
23+
search_agent.start("Search more information about Praison AI")
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from praisonaiagents import Agent
2+
3+
import npx_mcp_wrapper_main
4+
5+
search_agent = Agent(
6+
instructions="""You help book apartments on Airbnb.""",
7+
llm="gpt-4o-mini",
8+
tools=npx_mcp_wrapper_main.MCP(
9+
command="npx",
10+
args=[
11+
"-y",
12+
"@openbnb/mcp-server-airbnb",
13+
"--ignore-robots-txt",
14+
]
15+
)
16+
)
17+
18+
search_agent.start("I want to book an apartment in Paris for 2 nights. 03/28 - 03/30 for 2 adults")
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
from praisonaiagents import Agent, MCP
2+
3+
search_agent = Agent(
4+
instructions="""You help book apartments on Airbnb.""",
5+
llm="gpt-4o-mini",
6+
tools=MCP(
7+
command="npx",
8+
args=[
9+
"-y",
10+
"@openbnb/mcp-server-airbnb",
11+
"--ignore-robots-txt",
12+
]
13+
)
14+
)
15+
16+
search_agent.start("I want to book an apartment in Paris for 2 nights. 03/28 - 03/30 for 2 adults")
17+
18+
agent = Agent(
19+
instructions="""You are a helpful assistant that can check stock prices and perform other tasks.
20+
Use the available tools when relevant to answer user questions.""",
21+
llm="gpt-4o-mini",
22+
tools = MCP("/Users/praison/miniconda3/envs/mcp/bin/python /Users/praison/stockprice/app.py")
23+
)
24+
25+
agent.start("What is the stock price of Tesla?")
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
from praisonaiagents import Agent, MCP
2+
3+
search_agent = Agent(
4+
instructions="""You help book apartments on Airbnb.""",
5+
llm="gpt-4o-mini",
6+
tools=MCP(
7+
command="npx",
8+
args=[
9+
"-y",
10+
"@openbnb/mcp-server-airbnb",
11+
"--ignore-robots-txt",
12+
]
13+
)
14+
)
15+
16+
search_agent.start("I want to book an apartment in Paris for 2 nights. 03/28 - 03/30 for 2 adults")
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
from praisonaiagents import Agent, MCP
2+
3+
search_agent = Agent(
4+
instructions="""You are a helpful assistant that can search the web for information.
5+
Use the available tools when relevant to answer user questions.""",
6+
llm="gpt-4o-mini",
7+
tools=MCP(
8+
command="npx",
9+
args=[
10+
"-y",
11+
"@smithery/cli@latest",
12+
"install",
13+
"@smithery-ai/brave-search",
14+
"--client",
15+
"claude",
16+
"--config",
17+
'{"braveApiKey":"BSANfDaqLKO9wq7e08mrPth9ZlJvKtc"}'
18+
],
19+
timeout=30, # 3 minutes for brave-search
20+
debug=True # Enable detailed logging
21+
)
22+
)
23+
24+
search_agent.start("Search more information about Praison AI")
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
from google import genai
2+
from google.genai import types
3+
from mcp import ClientSession, StdioServerParameters
4+
from mcp.client.stdio import stdio_client
5+
import os
6+
7+
client = genai.Client(
8+
api_key=os.getenv("GEMINI_API_KEY")
9+
) # Replace with your actual API key setup
10+
11+
12+
# Create server parameters for stdio connection
13+
server_params = StdioServerParameters(
14+
command="npx", # Executable
15+
args=[
16+
"-y",
17+
"@openbnb/mcp-server-airbnb",
18+
"--ignore-robots-txt",
19+
], # Optional command line arguments
20+
env=None, # Optional environment variables
21+
)
22+
23+
async def run():
24+
async with stdio_client(server_params) as (read, write):
25+
async with ClientSession(
26+
read,
27+
write,
28+
) as session:
29+
prompt = "I want to book an apartment in Paris for 2 nights. 03/28 - 03/30"
30+
# Initialize the connection
31+
await session.initialize()
32+
33+
# Get tools from MCP session and convert to Gemini Tool objects
34+
mcp_tools = await session.list_tools()
35+
tools = types.Tool(function_declarations=[
36+
{
37+
"name": tool.name,
38+
"description": tool.description,
39+
"parameters": tool.inputSchema,
40+
}
41+
for tool in mcp_tools.tools
42+
])
43+
44+
# Send request with function declarations
45+
response = client.models.generate_content(
46+
model="gemini-2.0-flash", # Or your preferred model supporting function calling
47+
contents=prompt,
48+
config=types.GenerateContentConfig(
49+
temperature=0.7,
50+
tools=[tools],
51+
), # Example other config
52+
)
53+
# Check for a function call
54+
if response.candidates[0].content.parts[0].function_call:
55+
function_call = response.candidates[0].content.parts[0].function_call
56+
print(f"Function to call: {function_call.name}")
57+
print(f"Arguments: {function_call.args}")
58+
# In a real app, you would call your function here:
59+
# result = await session.call_tool(function_call.args, arguments=function_call.args)
60+
# sent new request with function call
61+
else:
62+
print("No function call found in the response.")
63+
print(response.text)
64+
65+
if __name__ == "__main__":
66+
import asyncio
67+
asyncio.run(run())

0 commit comments

Comments
 (0)