-
Notifications
You must be signed in to change notification settings - Fork 54
feat: mcp tool support #122
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
Merged
Merged
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
5c3bd4d
chore(mcp): move, simplify and add to example mcp servers
adi-wan-askui 7c7a953
feat(chat): add mcp configs api
adi-wan-askui a325ec7
feat(agent)!: integrate mcp tools
adi-wan-askui 0348474
feat(chat)!: use mcp tools from all configured servers with all agents
adi-wan-askui 50f26d6
fix(mcp): use stdio tools with library
adi-wan-askui 5ef1d12
docs(mcp): add documentation for MCP server support
adi-wan-askui 2892306
fix: fix using time.sleep in async code
adi-wan-askui e13535f
Update src/askui/models/shared/tools.py
adi-wan-askui b4220ea
chore: pin asyncer version
adi-wan-askui 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
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,167 @@ | ||
| # MCP | ||
|
|
||
| ## What is MCP? | ||
|
|
||
| The Model Context Protocol (MCP) is a standardized way to provide context and tools to Large Language Models (LLMs). It acts as a universal interface - often described as "the USB-C port for AI" - that allows LLMs to connect to external resources and functionality in a secure, standardized manner. | ||
|
|
||
| MCP servers can: | ||
| - **Expose data** through `Resources` (similar to GET endpoints for loading information into the LLM's context) | ||
| - **Provide functionality** through `Tools` (similar to POST endpoints for executing code or producing side effects) | ||
| - **Define interaction patterns** through `Prompts` (reusable templates for LLM interactions) | ||
|
|
||
| For more information, see the [MCP specification](https://modelcontextprotocol.io/docs/getting-started/intro). | ||
|
|
||
| ## Our MCP Support | ||
|
|
||
| We currently support the use of tools from MCP servers both through the library `AgentBase.act()` (and extending classes, e.g., `VisionAgent.act()`, `AndroidVisionAgent.act()`) and through the Chat API. | ||
|
|
||
| The use of tools is comprised of listing the tools available, passing them on to the model and calling them if the model requests them to be called. | ||
|
|
||
| The Chat API builds on top of the library which in turn uses [`fastmcp`](https://gofastmcp.com/getting-started/welcome). | ||
|
|
||
| ## How to Use MCP with AskUI | ||
|
|
||
| ### With the Library | ||
|
|
||
| You can integrate MCP tools directly into your AskUI agents by creating an MCP client and passing it to the `ToolCollection`: | ||
|
|
||
| ```python | ||
| from fastmcp import Client | ||
| from fastmcp.mcp_config import MCPConfig, RemoteMCPServer | ||
|
|
||
| from askui.agent import VisionAgent | ||
| from askui.models.shared.agent_message_param import MessageParam | ||
| from askui.models.shared.agent_on_message_cb import OnMessageCbParam | ||
| from askui.models.shared.tools import ToolCollection | ||
| from askui.tools.mcp.config import StdioMCPServer | ||
|
|
||
| # Create MCP configuration | ||
| mcp_config = MCPConfig( | ||
| mcpServers={ | ||
| # Make sure to use our patch of StdioMCPServer as we don't support the official one | ||
| "test_stdio_server": StdioMCPServer( | ||
| command="python", args=["-m", "askui.tools.mcp.servers.stdio"] | ||
| ), | ||
| "test_sse_server": RemoteMCPServer(url="http://127.0.0.1:8001/sse/"), | ||
| } | ||
| ) | ||
|
|
||
| # Create MCP client | ||
| mcp_client = Client(mcp_config) | ||
|
|
||
| # Create tool collection with MCP tools | ||
| tools = ToolCollection(mcp_client=mcp_client) | ||
|
|
||
|
|
||
| def on_message(param: OnMessageCbParam) -> MessageParam | None: | ||
| print(param.message.model_dump_json()) | ||
| return param.message | ||
|
|
||
|
|
||
| # Use with VisionAgent | ||
| with VisionAgent() as agent: | ||
| agent.act( | ||
| "Use the `test_stdio_server_test_stdio_tool`", | ||
| tools=tools, | ||
| on_message=on_message, | ||
| ) | ||
| ``` | ||
|
|
||
| Tools are appended to the default tools of the agent, potentially, overriding them. | ||
|
|
||
| For different ways to construct `Client`s see the [fastmcp documentation](https://gofastmcp.com/clients/client). | ||
|
|
||
| Notice that the tool name (`test_stdio_tool`) is prefixed with the server name (`test_stdio_server`) to avoid conflicts. | ||
| This differs between Chat API and library. In the Chat API, the tool name is prefixed with the id of the MCP config. | ||
| More about that later. | ||
|
|
||
|
|
||
| If you would like to try out the `test_sse_server` you can run the following command before executing the code above: | ||
|
|
||
| ```bash | ||
| python -m askui.tools.mcp.servers.sse | ||
| ``` | ||
|
|
||
| **Caveats and limmitations** | ||
|
|
||
| - **No Tool Selection/Filtering**: All MCP tools from connected servers are automatically available | ||
| - **Synchronous Code Requirement**: MCP tools must be run from within synchronous code contexts (no `async` or `await` allowed) | ||
| - **Limited Tool Response Content Types**: Only text and images (JPEG, PNG, GIF, WebP) are supported | ||
| - **Complexity Limits**: Tools are limited in number and complexity by the model's context window | ||
|
|
||
| ### With Chat | ||
|
|
||
| To use MCP servers or, more specifically, the tools they provide with the Chat (API), you need to create MCP configs. All agents are going to have access to the servers specified within the configs if it possible to connect to them. | ||
|
|
||
| #### Creating MCP Configs | ||
|
|
||
| An MCP configuration can be created with either stdio or remote server similar with what is used when constructing the `MCPConfig` in the library example above | ||
adi-wan-askui marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| ```bash | ||
adi-wan-askui marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| curl -X 'POST' \ | ||
| 'http://localhost:9261/v1/mcp-configs' \ | ||
| -H 'accept: application/json' \ | ||
| -H 'Content-Type: application/json' \ | ||
| -d '{ | ||
| "name": "test_stdio_server", | ||
| "mcp_server": { | ||
| "command": "python", | ||
| "args": [ | ||
| "-m", "askui.tools.mcp.servers.stdio" | ||
| ] | ||
| } | ||
| }' | ||
| curl -X 'POST' \ | ||
| 'http://localhost:9261/v1/mcp-configs' \ | ||
| -H 'accept: application/json' \ | ||
| -H 'Content-Type: application/json' \ | ||
| -d '{ | ||
| "name": "test_sse_server", | ||
| "mcp_server": { | ||
| "url": "http://127.0.0.1:8001/sse/" | ||
| } | ||
| }' | ||
| ``` | ||
|
|
||
| Notice that each server needs to be created separately and is managed as a separate entity. For other endpoints to manage MCP configs, start the chat api using `python -m askui.chat.api` and see the [Chat API documentation](http://localhost:9261/docs#/mcp-configs). | ||
|
|
||
| #### Caveats of Using MCP with Chat | ||
|
|
||
| When using MCP through the Chat API, consider these limitations: | ||
|
|
||
| - **Configuration Limit**: Maximum of 100 MCP configurations allowed | ||
| - **Universal Availability**: All servers are currently passed to all available agents | ||
| - **No Filtering**: No way to filter servers or tools for specific use cases | ||
| - **Tool Name Prefixing**: Tool names are automatically prefixed with the MCP config ID | ||
| - **Server Availability**: When a server is not available (Chat API cannot connect), it is silently ignored | ||
adi-wan-askui marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| ## How to Define Your Own MCP Server | ||
|
|
||
| ### Different Frameworks | ||
|
|
||
| You can build MCP servers using various frameworks and languages: | ||
|
|
||
| #### FastMCP (Python) - Recommended | ||
|
|
||
| FastMCP provides the most Pythonic and straightforward way to build MCP servers: | ||
|
|
||
| ```python | ||
| from fastmcp import FastMCP | ||
|
|
||
| mcp = FastMCP("My Server") | ||
|
|
||
| @mcp.tool | ||
| def my_tool(param: str) -> str: | ||
| """My custom tool description.""" | ||
| return f"Processed: {param}" | ||
|
|
||
| if __name__ == "__main__": | ||
| mcp.run(transport="stdio") # For AskUI integration | ||
| # or | ||
| mcp.run(transport="sse", port=8001) # For remote access | ||
| ``` | ||
|
|
||
| #### Official MCP SDKs | ||
|
|
||
| The official MCP specification provides SDKs for multiple languages: | ||
| [https://modelcontextprotocol.io/docs/sdk](https://modelcontextprotocol.io/docs/sdk) | ||
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.
Uh oh!
There was an error while loading. Please reload this page.