Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "PraisonAI"
version = "2.0.80"
version = "2.0.81"
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."
readme = "README.md"
license = ""
Expand All @@ -12,7 +12,7 @@ dependencies = [
"rich>=13.7",
"markdown>=3.5",
"pyparsing>=3.0.0",
"praisonaiagents>=0.0.65",
"praisonaiagents>=0.0.67",
"python-dotenv>=0.19.0",
"instructor>=1.3.3",
"PyYAML>=6.0",
Expand Down Expand Up @@ -102,7 +102,7 @@ python = ">=3.10,<3.13"
rich = ">=13.7"
markdown = ">=3.5"
pyparsing = ">=3.0.0"
praisonaiagents = ">=0.0.65"
praisonaiagents = ">=0.0.67"
python-dotenv = ">=0.19.0"
instructor = ">=1.3.3"
PyYAML = ">=6.0"
Expand Down
13 changes: 13 additions & 0 deletions src/praisonai-agents/mcp-agents-detailed.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from praisonaiagents import Agent, MCP

agent = Agent(
instructions="""You are a helpful assistant that can check stock prices and perform other tasks.
Use the available tools when relevant to answer user questions.""",
llm="gpt-4o-mini",
tools=MCP(
command="/Users/praison/miniconda3/envs/mcp/bin/python",
args=["/Users/praison/stockprice/app.py"]
Comment on lines +8 to +9
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The command and args are hardcoded. Consider using environment variables or a configuration file to make this more configurable and portable.

Suggested change
command="/Users/praison/miniconda3/envs/mcp/bin/python",
args=["/Users/praison/stockprice/app.py"]
command=os.getenv("MCP_PYTHON_PATH", "/Users/praison/miniconda3/envs/mcp/bin/python"),
args=[os.getenv("STOCKPRICE_APP_PATH", "/Users/praison/stockprice/app.py")]

)
)

agent.start("What is the stock price of Tesla?")
10 changes: 10 additions & 0 deletions src/praisonai-agents/mcp-agents.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from praisonaiagents import Agent, MCP

agent = Agent(
instructions="""You are a helpful assistant that can check stock prices and perform other tasks.
Use the available tools when relevant to answer user questions.""",
llm="gpt-4o-mini",
tools = MCP("/Users/praison/miniconda3/envs/mcp/bin/python /Users/praison/stockprice/app.py")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This path is hardcoded. Consider using environment variables or a configuration file to make this more configurable and portable.

Suggested change
tools = MCP("/Users/praison/miniconda3/envs/mcp/bin/python /Users/praison/stockprice/app.py")
tools = MCP(os.getenv("MCP_COMMAND", "/Users/praison/miniconda3/envs/mcp/bin/python /Users/praison/stockprice/app.py"))

)

agent.start("What is the stock price of Tesla?")
61 changes: 61 additions & 0 deletions src/praisonai-agents/mcp-basic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import asyncio
from praisonaiagents import Agent
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client

# Define server configuration - pointing to your stock price app
server_params = StdioServerParameters(
command="/Users/praison/miniconda3/envs/mcp/bin/python",
args=[
"/Users/praison/stockprice/app.py",
],
Comment on lines +8 to +11
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

These paths are hardcoded. Consider using environment variables or a configuration file to make this more configurable and portable.

Suggested change
command="/Users/praison/miniconda3/envs/mcp/bin/python",
args=[
"/Users/praison/stockprice/app.py",
],
command=os.getenv("MCP_PYTHON_PATH", "/Users/praison/miniconda3/envs/mcp/bin/python"),
args=[
os.getenv("STOCKPRICE_APP_PATH", "/Users/praison/stockprice/app.py"),
],

)

# Function to get stock price using MCP
async def get_stock_price(symbol):
# Start server and connect client
async with stdio_client(server_params) as (read, write):
async with ClientSession(read, write) as session:
# Initialize the connection
await session.initialize()

# Get tools
tools_result = await session.list_tools()
tools = tools_result.tools
print(f"Available tools: {[tool.name for tool in tools]}")

# Find a tool that can get stock prices
# Assuming there's a tool like "get_stock_price" or similar
stock_tool = None
for tool in tools:
if "stock" in tool.name.lower() or "price" in tool.name.lower():
stock_tool = tool
break
Comment on lines +30 to +33
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This tool discovery mechanism is not very robust. It relies on string matching, which could lead to incorrect tool selection. A more reliable method would be to use tool schemas or annotations to identify the correct tool.

            # Find a tool that can get stock prices based on schema or annotations
            stock_tool = next((tool for tool in tools if tool.inputSchema and "ticker" in tool.inputSchema.get("properties", {})), None)


if stock_tool:
print(f"Using tool: {stock_tool.name}")
# Call the tool with the stock symbol
result = await session.call_tool(
stock_tool.name,
arguments={"ticker": symbol}
)
return result
else:
return "No suitable stock price tool found"

# Create a custom tool for the agent
def stock_price_tool(symbol: str) -> str:
"""Get the current stock price for a given symbol"""
# Run the async function to get the stock price
result = asyncio.run(get_stock_price(symbol))
return f"Stock price for {symbol}: {result}"
Comment on lines +47 to +51
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Using asyncio.run here blocks the event loop. It would be better to use asyncio.create_task or a similar mechanism to run the asynchronous function in a non-blocking manner. Consider refactoring to use await directly within an async context if possible.

    # Run the async function to get the stock price
    loop = asyncio.get_event_loop()
    result = loop.run_until_complete(get_stock_price(symbol))
    return f"Stock price for {symbol}: {result}"


# Create agent with the stock price tool
agent = Agent(
instructions="You are a helpful assistant that can check stock prices. When asked about stock prices, use the stock_price_tool.",
llm="gpt-4o-mini",
tools=[stock_price_tool]
)

# Start the agent
agent.start("What is the stock price of Tesla?")
23 changes: 23 additions & 0 deletions src/praisonai-agents/mcp-multiagents.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from praisonaiagents import Agent, MCP
import os
stock_agent = Agent(
instructions="""You are a helpful assistant that can check stock prices and perform other tasks.
Use the available tools when relevant to answer user questions.""",
llm="gpt-4o-mini",
tools=MCP(
command="/Users/praison/miniconda3/envs/mcp/bin/python",
args=["/Users/praison/stockprice/app.py"]
Comment on lines +8 to +9
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The command and args are hardcoded. Consider using environment variables or a configuration file to make this more configurable and portable.

Suggested change
command="/Users/praison/miniconda3/envs/mcp/bin/python",
args=["/Users/praison/stockprice/app.py"]
command=os.getenv("MCP_PYTHON_PATH", "/Users/praison/miniconda3/envs/mcp/bin/python"),
args=[os.getenv("STOCKPRICE_APP_PATH", "/Users/praison/stockprice/app.py")]

)
)

brave_api_key = os.getenv("BRAVE_API_KEY")

search_agent = Agent(
instructions="""You are a helpful assistant that can search the web for information.
Use the available tools when relevant to answer user questions.""",
llm="gpt-4o-mini",
tools=MCP(f'npx -y @smithery/cli@latest install @smithery-ai/brave-search --client claude --config "{{\\\"braveApiKey\\\":\\\"{brave_api_key}\\\"}}"')
)

stock_agent.start("What is the stock price of Tesla?")
search_agent.start("Search more information about Praison AI")
18 changes: 18 additions & 0 deletions src/praisonai-agents/mcp-npx-airbnb-agent-direct.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from praisonaiagents import Agent

import npx_mcp_wrapper_main

search_agent = Agent(
instructions="""You help book apartments on Airbnb.""",
llm="gpt-4o-mini",
tools=npx_mcp_wrapper_main.MCP(
command="npx",
args=[
"-y",
"@openbnb/mcp-server-airbnb",
"--ignore-robots-txt",
]
)
)

search_agent.start("I want to book an apartment in Paris for 2 nights. 03/28 - 03/30 for 2 adults")
25 changes: 25 additions & 0 deletions src/praisonai-agents/mcp-npx-airbnb-stockprice.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from praisonaiagents import Agent, MCP

search_agent = Agent(
instructions="""You help book apartments on Airbnb.""",
llm="gpt-4o-mini",
tools=MCP(
command="npx",
args=[
"-y",
"@openbnb/mcp-server-airbnb",
"--ignore-robots-txt",
]
)
)

search_agent.start("I want to book an apartment in Paris for 2 nights. 03/28 - 03/30 for 2 adults")

agent = Agent(
instructions="""You are a helpful assistant that can check stock prices and perform other tasks.
Use the available tools when relevant to answer user questions.""",
llm="gpt-4o-mini",
tools = MCP("/Users/praison/miniconda3/envs/mcp/bin/python /Users/praison/stockprice/app.py")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Remove hardcoded absolute paths

Using absolute paths specific to a user's system will prevent the code from working on other machines. Consider using relative paths or environment variables.

-    tools = MCP("/Users/praison/miniconda3/envs/mcp/bin/python /Users/praison/stockprice/app.py")
+    tools = MCP("python", args=["stockprice/app.py"])

Alternatively, use environment variables:

import os
...
python_path = os.environ.get("MCP_PYTHON_PATH", "python")
app_path = os.environ.get("STOCKPRICE_APP_PATH", "stockprice/app.py")
tools = MCP(python_path, args=[app_path])

)

agent.start("What is the stock price of Tesla?")
16 changes: 16 additions & 0 deletions src/praisonai-agents/mcp-npx-airbnb.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from praisonaiagents import Agent, MCP

search_agent = Agent(
instructions="""You help book apartments on Airbnb.""",
llm="gpt-4o-mini",
tools=MCP(
command="npx",
args=[
"-y",
"@openbnb/mcp-server-airbnb",
"--ignore-robots-txt",
]
)
)

search_agent.start("I want to book an apartment in Paris for 2 nights. 03/28 - 03/30 for 2 adults")
24 changes: 24 additions & 0 deletions src/praisonai-agents/mcp-npx-brave.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from praisonaiagents import Agent, MCP

search_agent = Agent(
instructions="""You are a helpful assistant that can search the web for information.
Use the available tools when relevant to answer user questions.""",
llm="gpt-4o-mini",
tools=MCP(
command="npx",
args=[
"-y",
"@smithery/cli@latest",
"install",
"@smithery-ai/brave-search",
"--client",
"claude",
"--config",
'{"braveApiKey":"BSANfDaqLKO9wq7e08mrPth9ZlJvKtc"}'
],
timeout=30, # 3 minutes for brave-search
debug=True # Enable detailed logging
)
)

search_agent.start("Search more information about Praison AI")
67 changes: 67 additions & 0 deletions src/praisonai-agents/mcp_airbnb_client_direct.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
from google import genai
from google.genai import types
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
import os

client = genai.Client(
api_key=os.getenv("GEMINI_API_KEY")
) # Replace with your actual API key setup


# Create server parameters for stdio connection
server_params = StdioServerParameters(
command="npx", # Executable
args=[
"-y",
"@openbnb/mcp-server-airbnb",
"--ignore-robots-txt",
], # Optional command line arguments
env=None, # Optional environment variables
)

async def run():
async with stdio_client(server_params) as (read, write):
async with ClientSession(
read,
write,
) as session:
prompt = "I want to book an apartment in Paris for 2 nights. 03/28 - 03/30"
# Initialize the connection
await session.initialize()

# Get tools from MCP session and convert to Gemini Tool objects
mcp_tools = await session.list_tools()
tools = types.Tool(function_declarations=[
{
"name": tool.name,
"description": tool.description,
"parameters": tool.inputSchema,
}
for tool in mcp_tools.tools
])

# Send request with function declarations
response = client.models.generate_content(
model="gemini-2.0-flash", # Or your preferred model supporting function calling
contents=prompt,
config=types.GenerateContentConfig(
temperature=0.7,
tools=[tools],
), # Example other config
)
# Check for a function call
if response.candidates[0].content.parts[0].function_call:
function_call = response.candidates[0].content.parts[0].function_call
print(f"Function to call: {function_call.name}")
print(f"Arguments: {function_call.args}")
# In a real app, you would call your function here:
# result = await session.call_tool(function_call.args, arguments=function_call.args)
# sent new request with function call
else:
print("No function call found in the response.")
print(response.text)

if __name__ == "__main__":
import asyncio
asyncio.run(run())
Loading
Loading