-
Notifications
You must be signed in to change notification settings - Fork 580
feat: Bump openai-agents to v0.0.7 and add MCP Server support #647
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
CryptoCultCurt
wants to merge
4
commits into
coinbase:main
Choose a base branch
from
CryptoCultCurt:feature/update-openai-agent
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+265
−5
Open
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
8bb6101
feat: Bump openai-agents to v0.0.7 and add MCP Server support
CryptoCultCurt 41faac5
chore: rename changelog to match PR #647
CryptoCultCurt f6cfe11
Add example of a Fear & Greed MCP server
CryptoCultCurt 3c9a59f
Merge branch 'main' into feature/update-openai-agent
CryptoCultCurt File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
195 changes: 195 additions & 0 deletions
195
...ents-sdk-smart-wallet-chatbot/openai-agents-model-context-protocol-smart-wallet-server.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,195 @@ | ||
| import json | ||
| import os | ||
| import sys | ||
| import asyncio | ||
|
|
||
| from agents import gen_trace_id, trace | ||
|
|
||
| from coinbase_agentkit import ( | ||
| AgentKit, | ||
| AgentKitConfig, | ||
| SmartWalletProvider, | ||
| SmartWalletProviderConfig, | ||
| cdp_api_action_provider, | ||
| erc20_action_provider, | ||
| pyth_action_provider, | ||
| wallet_action_provider, | ||
| weth_action_provider, | ||
| ) | ||
| from coinbase_agentkit_openai_agents_sdk import get_openai_agents_sdk_tools | ||
| from dotenv import load_dotenv | ||
| from eth_account.account import Account | ||
| from agents.agent import Agent | ||
| from agents.run import Runner | ||
| from agents.mcp import MCPServer, MCPServerStdio | ||
|
|
||
| # Configure a file to persist the agent's CDP API Wallet Data. | ||
| wallet_data_file = "wallet_data.txt" | ||
| mcp_server_path = "/Users/curtfluegel/Documents/Development/crypto-feargreed-mcp/" | ||
|
|
||
| load_dotenv() | ||
|
|
||
|
|
||
| async def initialize_agent(mcp_server: MCPServer): | ||
| """Initialize the agent with SmartWalletProvider.""" | ||
| network_id = os.getenv("NETWORK_ID", "base-sepolia") | ||
| wallet_data_file = f"wallet_data_{network_id.replace('-', '_')}.txt" | ||
|
|
||
| # Load wallet data from JSON file | ||
| wallet_data = {"private_key": None, "smart_wallet_address": None} | ||
| if os.path.exists(wallet_data_file): | ||
| try: | ||
| with open(wallet_data_file) as f: | ||
| wallet_data = json.load(f) | ||
| except json.JSONDecodeError: | ||
| print(f"Warning: Invalid wallet data file format for {network_id}. Creating new wallet.") | ||
|
|
||
| # Use private key from env if not in wallet data | ||
| private_key = wallet_data.get("private_key") or os.getenv("PRIVATE_KEY") | ||
| if not private_key: | ||
| acct = Account.create() | ||
| private_key = acct.key.hex() | ||
|
|
||
| signer = Account.from_key(private_key) | ||
|
|
||
| # Initialize Smart Wallet Provider | ||
| wallet_provider = SmartWalletProvider( | ||
| SmartWalletProviderConfig( | ||
| network_id=network_id, | ||
| signer=signer, | ||
| smart_wallet_address=wallet_data.get("smart_wallet_address"), | ||
| paymaster_url=None, # Sponsor transactions: https://docs.cdp.coinbase.com/paymaster/docs/welcome | ||
| ) | ||
| ) | ||
|
|
||
| # Save both private key and smart wallet address | ||
| wallet_data = { | ||
| "private_key": private_key, | ||
| "smart_wallet_address": wallet_provider.get_address(), | ||
| } | ||
| with open(wallet_data_file, "w") as f: | ||
| json.dump(wallet_data, f, indent=2) | ||
|
|
||
| agentkit = AgentKit( | ||
| AgentKitConfig( | ||
| wallet_provider=wallet_provider, | ||
| action_providers=[ | ||
| cdp_api_action_provider(), | ||
| erc20_action_provider(), | ||
| pyth_action_provider(), | ||
| wallet_action_provider(), | ||
| weth_action_provider(), | ||
| ], | ||
| ) | ||
| ) | ||
|
|
||
| # use get_openai_agents_sdk_tools | ||
| tools = get_openai_agents_sdk_tools(agentkit) | ||
|
|
||
| # Create Agent using the OpenAI Agents SDK | ||
| agent = Agent( | ||
| name="CDP Agent", | ||
| instructions=( | ||
| "You are a helpful agent that can interact onchain using the Coinbase Developer Platform AgentKit. " | ||
| "You are empowered to interact onchain using your tools. If you ever need funds, you can request " | ||
| "them from the faucet if you are on network ID 'base-sepolia'. If not, you can provide your wallet " | ||
| "details and request funds from the user. Before executing your first action, get the wallet details " | ||
| "to see what network you're on. If there is a 5XX (internal) HTTP error code, ask the user to try " | ||
| "again later. If someone asks you to do something you can't do with your currently available tools, " | ||
| "you must say so, and encourage them to implement it themselves using the CDP SDK + Agentkit, " | ||
| "recommend they go to docs.cdp.coinbase.com for more information. Be concise and helpful with your " | ||
| "responses. Refrain from restating your tools' descriptions unless it is explicitly requested." | ||
| "Unless asked otherwise, speak in English." | ||
| ), | ||
| tools=tools, | ||
| mcp_servers=[ | ||
| mcp_server | ||
| ], | ||
| ) | ||
|
|
||
| return agent | ||
|
|
||
|
|
||
| # Autonomous Mode | ||
| async def run_autonomous_mode(agent, interval=10): | ||
| """Run the agent autonomously with specified intervals.""" | ||
| print("Starting autonomous mode...") | ||
| while True: | ||
| try: | ||
| thought = ( | ||
| "Be creative and do something interesting on the blockchain. " | ||
| "Choose an action or set of actions and execute it that highlights your abilities." | ||
| ) | ||
|
|
||
| # Run agent in autonomous mode | ||
| output = await Runner.run(agent, thought) | ||
| print(output.final_output) | ||
| print("-------------------") | ||
|
|
||
| # Wait before the next action | ||
| await asyncio.sleep(interval) | ||
|
|
||
| except KeyboardInterrupt: | ||
| print("Goodbye Agent!") | ||
| sys.exit(0) | ||
|
|
||
| # Chat Mode | ||
| async def run_chat_mode(agent): | ||
| """Run the agent interactively based on user input.""" | ||
| print("Starting chat mode... Type 'exit' to end.") | ||
| while True: | ||
| try: | ||
| user_input = input("\nPrompt: ") | ||
| if user_input.lower() == "exit": | ||
| break | ||
|
|
||
| # Run agent with the user's input in chat mode | ||
| output = await Runner.run(agent, user_input) | ||
| print(output.final_output) | ||
| print("-------------------") | ||
|
|
||
| except KeyboardInterrupt: | ||
| print("Goodbye Agent!") | ||
| sys.exit(0) | ||
|
|
||
|
|
||
| # Mode Selection | ||
| def choose_mode(): | ||
| """Choose whether to run in autonomous or chat mode based on user input.""" | ||
| while True: | ||
| print("\nAvailable modes:") | ||
| print("1. chat - Interactive chat mode") | ||
| print("2. auto - Autonomous action mode") | ||
|
|
||
| choice = input("\nChoose a mode (enter number or name): ").lower().strip() | ||
| if choice in ["1", "chat"]: | ||
| return "chat" | ||
| elif choice in ["2", "auto"]: | ||
| return "auto" | ||
| print("Invalid choice. Please try again.") | ||
|
|
||
|
|
||
| async def main(): | ||
| try: | ||
| async with MCPServerStdio( | ||
| params={ | ||
| "command": "uv", | ||
| "args": ["--directory", mcp_server_path, "run", "main.py"] | ||
| }, | ||
| name="crypto-feargreed-mcp" | ||
| ) as server: | ||
| trace_id = gen_trace_id() | ||
| with trace(workflow_name="MCP Filesystem Example", trace_id=trace_id): | ||
| print(f"View trace: https://platform.openai.com/traces/{trace_id}\n") | ||
| # Initialize agent and run chat mode within the server context | ||
| agent = await initialize_agent(server) | ||
| mode = choose_mode() | ||
| if mode == "chat": | ||
| await run_chat_mode(agent=agent) | ||
| elif mode == "auto": | ||
| await run_autonomous_mode(agent=agent) | ||
| except Exception as e: | ||
| print(f"Error running server: {e}") | ||
|
|
||
| if __name__ == "__main__": | ||
| asyncio.run(main()) | ||
10 changes: 10 additions & 0 deletions
10
python/framework-extensions/openai-agents-sdk/changelog.d/647.feature
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| Bump openai-agents to v0.0.7 | ||
| Added support for MCP Servers in OpenAI agents. Users can now integrate MCP servers into their agents with a simple configuration: | ||
|
|
||
| ```python | ||
| agent = Agent( | ||
| name="Assistant", | ||
| instructions="Use the tools to answer any questions.", | ||
| mcp_servers=[mcp_server], | ||
| ) | ||
| ``` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be better to use a remote mcp server here, for example from coingecko: https://docs.coingecko.com/reference/mcp-server#remote-server-public-keyless