diff --git a/README.md b/README.md index c8424c6..9d03a0d 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ Make sure you have the following tools installed: - [argc](https://github.com/sigoden/argc): A bash command-line framework and command runner - [jq](https://github.com/jqlang/jq): A JSON processor +- [yq](https://github.com/mikefarah/yq): A YAML processor ## Getting Started with [AIChat](https://github.com/sigoden/aichat) diff --git a/agents/demo/README.md b/agents/demo/README.md index 7117efe..fbfd148 100644 --- a/agents/demo/README.md +++ b/agents/demo/README.md @@ -1,3 +1,28 @@ # Demo This agent serves as a demo to guide agent development and showcase various agent capabilities. + +It has been modified from the version defined in the base repo to also include details on +how to integrate MCP servers with agents. + +## How MCP Servers Work with Agents +A new `mcp_tools` field was added to the [index.yaml](./index.yaml) file in order to define and configure MCP support for +agents. + +This field allows you to specify the prefixes of the MCP server functions that are generated according to +the MCP servers defined in the [mcp.json](../../mcp.json) file under the `mcpServers` key. + +When `argc mcp start` is executed, it populates the main [`functions.json`](../../functions.json) file with +functions that are all prefixed with the name of the corresponding MCP server in the [mcp.json](../../mcp.json). + +What this fork does is it allows you to specify which MCP servers you specifically want access to in your agent. + +Then, when the `argc mcp start` command is executed, will populate each agent it finds with a non-empty `mcp_tools` field +with all the generated functions from the main `functions.json`. + +When you stop the MCP server with `argc mcp stop`, it will also remove the MCP functions from the agent's `functions.json` file. + +This allows you to use the agent either with MCP or without, so you don't necessarily have to remember to start the bridge +server every time you want to use your agent if you happen to have separate tools or functions defined in the agent's +tools.sh file. + diff --git a/agents/demo/index.yaml b/agents/demo/index.yaml index eeb25cb..888ada1 100644 --- a/agents/demo/index.yaml +++ b/agents/demo/index.yaml @@ -1,6 +1,11 @@ name: Demo description: An AI agent that demonstrates agent capabilities version: 0.1.0 +mcp: true +mcp_tools: + - github + - sqlite + - git instructions: | You are a AI agent designed to demonstrate agent capabilities. @@ -32,4 +37,4 @@ conversation_starters: - How to create an agent? documents: - README.md - - https://github.com/sigoden/llm-functions/blob/main/README.md \ No newline at end of file + - https://github.com/sigoden/llm-functions/blob/main/README.md diff --git a/scripts/mcp.sh b/scripts/mcp.sh index f365f61..556bb95 100755 --- a/scripts/mcp.sh +++ b/scripts/mcp.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash set -e +readarray -t mcp_enabled_agents < <(find . -type f -name index.yaml -exec sh -c 'yq --exit-status ".mcp_tools | length != 0" "$1" > /dev/null 2>&1 && dirname "$1"' _ {} \;) ROOT_DIR="$(cd -- "$( dirname -- "${BASH_SOURCE[0]}" )/.." &> /dev/null && pwd)" BIN_DIR="$ROOT_DIR/bin" MCP_DIR="$ROOT_DIR/cache/__mcp__" @@ -115,6 +116,22 @@ merge-functions() { else printf "%s" "$result" fi + + for agent in "${mcp_enabled_agents[@]}"; do + if [[ -f "${agent}/functions.json" ]]; then + tool_json="$(jq '.' "${agent}/functions.json")" + rm -f "${agent}/functions.json" + else + tool_json='[]' + fi + + mcp_function_prefixes="$(yq -o json '.mcp_tools' "${agent}/index.yaml")" + + jq -s 'add | unique' \ + <(jq '.' <<< "$tool_json") \ + <(jq --argjson prefixes "$mcp_function_prefixes" 'map(select(.name as $s | $prefixes | any(. as $p | $s | startswith($p))))' "$FUNCTIONS_JSON_PATH") \ + >> "${agent}/functions.json" + done } # @cmd Unmerge mcp tools from functions.json @@ -130,6 +147,20 @@ recovery-functions() { else printf "%s" "$result" fi + + for agent in "${mcp_enabled_agents[@]}"; do + if [[ -f "${agent}/functions.json" ]]; then + tool_json="$(jq '.' "${agent}/functions.json")" + rm -f "${agent}/functions.json" + else + tool_json='[]' + fi + + mcp_function_prefixes="$(yq -o json '.mcp_tools' "${agent}/index.yaml")" + + jq --argjson prefixes "$mcp_function_prefixes" 'map(select(.name as $s | $prefixes | any(. as $p | $s | startswith($p))| not))' <<< "$tool_json" \ + >> "${agent}/functions.json" + done } # @cmd Generate function declarations for the mcp tools