Compare commits

...

10 Commits

Author SHA1 Message Date
bca8bc2c06 Fixed a bug that made it so any MCP servers with dashes in the name would not be automatically populated for each agent
CI / All (macos-latest) (push) Has been cancelled
CI / All (ubuntu-latest) (push) Has been cancelled
CI / All (windows-latest) (push) Has been cancelled
2025-08-25 18:24:13 -06:00
5b0240b0b4 Added MCP server support to agents 2025-08-22 17:09:09 -06:00
sigoden
616d8d84c5 refactor: scripts/mcp.sh curl add timeout (#203) 2025-06-25 17:46:01 +08:00
sigoden
08e74dec06 fix: scripts/mcp.sh jq error Argument list too long (#199) 2025-06-19 08:39:10 +08:00
sigoden
afe3670038 fix: MCP server cannot start on Window (#187) 2025-05-08 11:37:11 +08:00
sigoden
e5f9a9806c fix: argc build reserve mcp functions (#183) 2025-04-01 19:50:57 +08:00
sigoden
358a539b55 fix: mcp.sh build-bin (#181) 2025-03-28 08:18:37 +08:00
sigoden
5cd7e71a13 refactor: rename argc install to argc link-to-aichat (#171) 2025-02-24 07:53:13 +08:00
Meng Bo
4780ecb39d chore: update README.md (#168) 2025-02-21 12:08:26 +08:00
sigoden
7162e2f295 refactor(agent): improve coder agent (#167) 2025-02-19 19:46:05 +08:00
8 changed files with 99 additions and 23 deletions
+5 -2
View File
@@ -71,6 +71,9 @@ build() {
else else
echo 'Skipped building agents since agents.txt is missing' echo 'Skipped building agents since agents.txt is missing'
fi fi
if [[ -f mcp.json ]]; then
argc mcp merge-functions -S
fi
} }
# @cmd Build tools # @cmd Build tools
@@ -549,8 +552,8 @@ link-code-interpreter() {
_link_tool $1 code_interpreter _link_tool $1 code_interpreter
} }
# @cmd Install this repo to aichat functions_dir # @cmd Link this repo to aichat functions_dir
install() { link-to-aichat() {
functions_dir="$(aichat --info | grep -w functions_dir | awk '{$1=""; print substr($0,2)}')" functions_dir="$(aichat --info | grep -w functions_dir | awk '{$1=""; print substr($0,2)}')"
if [[ -z "$functions_dir" ]]; then if [[ -z "$functions_dir" ]]; then
_die "error: your aichat version don't support function calling" _die "error: your aichat version don't support function calling"
+13 -3
View File
@@ -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 - [argc](https://github.com/sigoden/argc): A bash command-line framework and command runner
- [jq](https://github.com/jqlang/jq): A JSON processor - [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) ## Getting Started with [AIChat](https://github.com/sigoden/aichat)
@@ -25,6 +26,7 @@ Make sure you have the following tools installed:
```sh ```sh
git clone https://github.com/sigoden/llm-functions git clone https://github.com/sigoden/llm-functions
cd llm-functions
``` ```
### 2. Build tools and agents ### 2. Build tools and agents
@@ -82,14 +84,22 @@ argc build
argc check argc check
``` ```
### 3. Install to AIChat ### 3. Link LLM-functions and AIChat
Symlink this repo directory to AIChat's **functions_dir**: AIChat expects LLM-functions to be placed in AIChat's **functions_dir** so that AIChat can use the tools and agents that LLM-functions provides.
You can symlink this repository directory to AIChat's **functions_dir** with:
```sh ```sh
ln -s "$(pwd)" "$(aichat --info | sed -n 's/^functions_dir\s\+//p')" ln -s "$(pwd)" "$(aichat --info | sed -n 's/^functions_dir\s\+//p')"
# OR # OR
argc install argc link-to-aichat
```
Alternatively, you can tell AIChat where the LLM-functions directory is by using an environment variable:
```sh
export AICHAT_FUNCTIONS_DIR="$(pwd)"
``` ```
### 4. Start using the functions ### 4. Start using the functions
+1 -8
View File
@@ -9,7 +9,6 @@ instructions: |
3. Providing architectural insights and applying design patterns 3. Providing architectural insights and applying design patterns
4. Staying current with the latest technologies and best practices 4. Staying current with the latest technologies and best practices
5. Analyzing and manipulating files within the project directory 5. Analyzing and manipulating files within the project directory
6. Performing web searches for up-to-date information
Available tools and their optimal use cases: Available tools and their optimal use cases:
@@ -18,18 +17,12 @@ instructions: |
3. fs_patch: Examine and modify existing files. 3. fs_patch: Examine and modify existing files.
4. fs_cat: View the contents of existing files without making changes. 4. fs_cat: View the contents of existing files without making changes.
5. fs_ls: Understand the current project structure or locate specific files. 5. fs_ls: Understand the current project structure or locate specific files.
6. Analyzing images provided by the user
Tool Usage Guidelines: Tool Usage Guidelines:
- Always use the most appropriate tool for the task at hand. - Always use the most appropriate tool for the task at hand.
- For file modifications, use fs_edit. Read the file first, then apply changes if needed. - For file modifications, use fs_patch. Read the file first, then apply changes if needed.
- After making changes, always review the diff output to ensure accuracy. - After making changes, always review the diff output to ensure accuracy.
Error Handling and Recovery:
- If a tool operation fails, analyze the error message and attempt to resolve the issue.
- For file-related errors, check file paths and permissions before retrying.
- If a search fails, try rephrasing the query or breaking it into smaller, more specific searches.
Project Creation and Management: Project Creation and Management:
1. Start by creating a root folder for new projects. 1. Start by creating a root folder for new projects.
2. Create necessary subdirectories and files within the root folder. 2. Create necessary subdirectories and files within the root folder.
+25
View File
@@ -1,3 +1,28 @@
# Demo # Demo
This agent serves as a demo to guide agent development and showcase various agent capabilities. 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.
+6 -1
View File
@@ -1,6 +1,11 @@
name: Demo name: Demo
description: An AI agent that demonstrates agent capabilities description: An AI agent that demonstrates agent capabilities
version: 0.1.0 version: 0.1.0
mcp: true
mcp_tools:
- github
- sqlite
- git
instructions: | instructions: |
You are a AI agent designed to demonstrate agent capabilities. You are a AI agent designed to demonstrate agent capabilities.
@@ -32,4 +37,4 @@ conversation_starters:
- How to create an agent? - How to create an agent?
documents: documents:
- README.md - README.md
- https://github.com/sigoden/llm-functions/blob/main/README.md - https://github.com/sigoden/llm-functions/blob/main/README.md
+2 -2
View File
@@ -70,8 +70,8 @@ argc link-web-search web_search_tavily.sh
argc link-code-interpreter execute_py_code.py argc link-code-interpreter execute_py_code.py
# -------- Misc -------- # -------- Misc --------
# Install this repo to aichat functions_dir # Link this repo to aichat functions_dir
argc install argc link-to-aichat
# Displays version information for required tools # Displays version information for required tools
argc version argc version
``` ```
+2 -2
View File
@@ -4,7 +4,7 @@ Let external MCP tools be used by LLM-Functions.
## Get Started ## Get Started
### 1. Create a `mpc.json` at `<llm-functions-dir>`. ### 1. Create a `mcp.json` at `<llm-functions-dir>`.
```json ```json
{ {
@@ -52,4 +52,4 @@ argc mcp start
> Run `argc mcp stop` to stop the bridge server, recover functions.json. > Run `argc mcp stop` to stop the bridge server, recover functions.json.
> Run `argc mcp logs` to check the server's logs. > Run `argc mcp logs` to check the server's logs.
+45 -5
View File
@@ -1,6 +1,7 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e 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)" ROOT_DIR="$(cd -- "$( dirname -- "${BASH_SOURCE[0]}" )/.." &> /dev/null && pwd)"
BIN_DIR="$ROOT_DIR/bin" BIN_DIR="$ROOT_DIR/bin"
MCP_DIR="$ROOT_DIR/cache/__mcp__" MCP_DIR="$ROOT_DIR/cache/__mcp__"
@@ -25,7 +26,7 @@ start() {
fi fi
echo "Start MCP Bridge server..." echo "Start MCP Bridge server..."
echo "Install node dependencies..." > "$MCP_LOG_FILE" echo "Install node dependencies..." > "$MCP_LOG_FILE"
npm install --prefix "$ROOT_DIR/mcp/bridge" 1>/dev/null 2>> "$MCP_LOG_FILE" (cd "$ROOT_DIR/mcp/bridge" && npm install 1>/dev/null 2>> "$MCP_LOG_FILE")
nohup node "$index_js" "$llm_functions_dir" >> "$MCP_LOG_FILE" 2>&1 & nohup node "$index_js" "$llm_functions_dir" >> "$MCP_LOG_FILE" 2>&1 &
wait-for-server wait-for-server
echo "Merge MCP tools into functions.json" echo "Merge MCP tools into functions.json"
@@ -89,6 +90,7 @@ logs() {
# @cmd Build tools to bin # @cmd Build tools to bin
build-bin() { build-bin() {
mkdir -p "$BIN_DIR"
tools=( $(generate-declarations | jq -r '.[].name') ) tools=( $(generate-declarations | jq -r '.[].name') )
for tool in "${tools[@]}"; do for tool in "${tools[@]}"; do
if _is_win; then if _is_win; then
@@ -105,12 +107,31 @@ build-bin() {
# @cmd Merge mcp tools into functions.json # @cmd Merge mcp tools into functions.json
# @flag -S --save Save to functions.json # @flag -S --save Save to functions.json
merge-functions() { merge-functions() {
result="$(jq --argjson json1 "$("$0" recovery-functions)" --argjson json2 "$(generate-declarations)" -n '($json1 + $json2)')" local tmpdir="$(mktemp -d)"
"$0" recovery-functions > "$tmpdir/1.json"
generate-declarations > "$tmpdir/2.json"
result="$(jq -s '.[0] + .[1]' "$tmpdir/1.json" "$tmpdir/2.json")"
if [[ -n "$argc_save" ]]; then if [[ -n "$argc_save" ]]; then
printf "%s" "$result" > "$FUNCTIONS_JSON_PATH" printf "%s" "$result" > "$FUNCTIONS_JSON_PATH"
else else
printf "%s" "$result" printf "%s" "$result"
fi 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(.mcp as $mcp | $prefixes | index($mcp)))' "$FUNCTIONS_JSON_PATH") \
>> "${agent}/functions.json"
done
} }
# @cmd Unmerge mcp tools from functions.json # @cmd Unmerge mcp tools from functions.json
@@ -126,17 +147,36 @@ recovery-functions() {
else else
printf "%s" "$result" printf "%s" "$result"
fi 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 # @cmd Generate function declarations for the mcp tools
generate-declarations() { generate-declarations() {
curl -sS http://localhost:$MCP_BRIDGE_PORT/tools pid="$(get-server-pid)"
if [[ -n "$pid" ]]; then
curl -sS http://localhost:$MCP_BRIDGE_PORT/tools
else
echo "[]"
fi
} }
# @cmd Wait for the mcp bridge server to ready # @cmd Wait for the mcp bridge server to ready
wait-for-server() { wait-for-server() {
while true; do while true; do
if [[ "$(curl -fsS http://localhost:$MCP_BRIDGE_PORT/health 2>&1)" == "OK" ]]; then if [[ "$(curl -fsS --max-time 5 http://localhost:$MCP_BRIDGE_PORT/health 2>&1)" == "OK" ]]; then
break; break;
fi fi
sleep 1 sleep 1
@@ -145,7 +185,7 @@ wait-for-server() {
# @cmd Get the server pid # @cmd Get the server pid
get-server-pid() { get-server-pid() {
curl -fsSL http://localhost:$MCP_BRIDGE_PORT/pid 2>/dev/null || true curl -fsS --max-time 5 http://localhost:$MCP_BRIDGE_PORT/pid 2>/dev/null || true
} }
_ask_json_data() { _ask_json_data() {