Skip to content

Commit 7a01298

Browse files
ModelContextProtocol (MCP) Full Compatibility (#3547)
* WIP MCP full compatibility layer * implement MCP agent function wrapping and invocation methods * Add `uvx` to docker bin for MCP executions * dev build * prune removed data * Wrap MCP servers to lazy load items to not block the UI Mobile bug fixes * arm64 test build * reset dev builder * remove unused prop
1 parent bd9b7e8 commit 7a01298

File tree

18 files changed

+1666
-49
lines changed

18 files changed

+1666
-49
lines changed

.github/workflows/dev-build.yaml

+6-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ concurrency:
66

77
on:
88
push:
9-
branches: ['3157-feat-prompt-variables'] # put your current branch to create a build. Core team only.
9+
branches: ['3000-mcp-compatibility'] # put your current branch to create a build. Core team only.
1010
paths-ignore:
1111
- '**.md'
1212
- 'cloud-deployments/*'
@@ -43,6 +43,10 @@ jobs:
4343
fi
4444
id: dockerhub
4545

46+
# Uncomment this + add linux/arm64 to platforms if you want to build for arm64 as well
47+
# - name: Set up QEMU
48+
# uses: docker/setup-qemu-action@v3
49+
4650
- name: Set up Docker Buildx
4751
uses: docker/setup-buildx-action@v3
4852
with:
@@ -74,6 +78,7 @@ jobs:
7478
sbom: true
7579
provenance: mode=max
7680
platforms: linux/amd64
81+
# platforms: linux/amd64,linux/arm64
7782
tags: ${{ steps.meta.outputs.tags }}
7883
labels: ${{ steps.meta.outputs.labels }}
7984
cache-from: type=gha

docker/Dockerfile

+12-6
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,16 @@ RUN DEBIAN_FRONTEND=noninteractive apt-get update && \
2424
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg && \
2525
echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list && \
2626
apt-get update && \
27+
# Install node and yarn
2728
apt-get install -yq --no-install-recommends nodejs && \
2829
curl -LO https://github.com/yarnpkg/yarn/releases/download/v1.22.19/yarn_1.22.19_all.deb \
2930
&& dpkg -i yarn_1.22.19_all.deb \
3031
&& rm yarn_1.22.19_all.deb && \
32+
# Install uvx (pinned to 0.6.10) for MCP support
33+
curl -LsSf https://astral.sh/uv/0.6.10/install.sh | sh && \
34+
mv /root/.local/bin/uv /usr/local/bin/uv && \
35+
mv /root/.local/bin/uvx /usr/local/bin/uvx && \
36+
echo "Installed uvx! $(uv --version)" && \
3137
apt-get clean && \
3238
rm -rf /var/lib/apt/lists/*
3339

@@ -84,10 +90,16 @@ RUN DEBIAN_FRONTEND=noninteractive apt-get update && \
8490
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg && \
8591
echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list && \
8692
apt-get update && \
93+
# Install node and yarn
8794
apt-get install -yq --no-install-recommends nodejs && \
8895
curl -LO https://github.com/yarnpkg/yarn/releases/download/v1.22.19/yarn_1.22.19_all.deb \
8996
&& dpkg -i yarn_1.22.19_all.deb \
9097
&& rm yarn_1.22.19_all.deb && \
98+
# Install uvx (pinned to 0.6.10) for MCP support
99+
curl -LsSf https://astral.sh/uv/0.6.10/install.sh | sh && \
100+
mv /root/.local/bin/uv /usr/local/bin/uv && \
101+
mv /root/.local/bin/uvx /usr/local/bin/uvx && \
102+
echo "Installed uvx! $(uv --version)" && \
91103
apt-get clean && \
92104
rm -rf /var/lib/apt/lists/*
93105

@@ -154,12 +166,6 @@ RUN chown -R anythingllm:anythingllm /app/server && \
154166
chown -R anythingllm:anythingllm /app/collector
155167
USER anythingllm
156168

157-
# No longer needed? (deprecated)
158-
# WORKDIR /app/server
159-
# RUN npx prisma generate --schema=./prisma/schema.prisma && \
160-
# npx prisma migrate deploy --schema=./prisma/schema.prisma
161-
# WORKDIR /app
162-
163169
# Setup the environment
164170
ENV NODE_ENV=production
165171
ENV ANYTHING_LLM_RUNTIME=docker
+1
Loading

frontend/src/models/mcpServers.js

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import { API_BASE } from "@/utils/constants";
2+
import { baseHeaders } from "@/utils/request";
3+
4+
const MCPServers = {
5+
/**
6+
* Forces a reload of the MCP Hypervisor and its servers
7+
* @returns {Promise<{success: boolean, error: string | null, servers: Array<{name: string, running: boolean, tools: Array<{name: string, description: string, inputSchema: Object}>, error: string | null, process: {pid: number, cmd: string} | null}>}>}
8+
*/
9+
forceReload: async () => {
10+
return await fetch(`${API_BASE}/mcp-servers/force-reload`, {
11+
method: "GET",
12+
headers: baseHeaders(),
13+
})
14+
.then((res) => res.json())
15+
.catch((e) => ({
16+
servers: [],
17+
success: false,
18+
error: e.message,
19+
}));
20+
},
21+
22+
/**
23+
* List all available MCP servers in the system
24+
* @returns {Promise<{success: boolean, error: string | null, servers: Array<{name: string, running: boolean, tools: Array<{name: string, description: string, inputSchema: Object}>, error: string | null, process: {pid: number, cmd: string} | null}>}>}
25+
*/
26+
listServers: async () => {
27+
return await fetch(`${API_BASE}/mcp-servers/list`, {
28+
method: "GET",
29+
headers: baseHeaders(),
30+
})
31+
.then((res) => res.json())
32+
.catch((e) => ({
33+
success: false,
34+
error: e.message,
35+
servers: [],
36+
}));
37+
},
38+
39+
/**
40+
* Toggle the MCP server (start or stop)
41+
* @param {string} name - The name of the MCP server to toggle
42+
* @returns {Promise<{success: boolean, error: string | null}>}
43+
*/
44+
toggleServer: async (name) => {
45+
return await fetch(`${API_BASE}/mcp-servers/toggle`, {
46+
method: "POST",
47+
headers: baseHeaders(),
48+
body: JSON.stringify({ name }),
49+
})
50+
.then((res) => res.json())
51+
.catch((e) => ({
52+
success: false,
53+
error: e.message,
54+
}));
55+
},
56+
57+
/**
58+
* Delete the MCP server - will also remove it from the config file
59+
* @param {string} name - The name of the MCP server to delete
60+
* @returns {Promise<{success: boolean, error: string | null}>}
61+
*/
62+
deleteServer: async (name) => {
63+
return await fetch(`${API_BASE}/mcp-servers/delete`, {
64+
method: "POST",
65+
headers: baseHeaders(),
66+
body: JSON.stringify({ name }),
67+
})
68+
.then((res) => res.json())
69+
.catch((e) => ({
70+
success: false,
71+
error: e.message,
72+
}));
73+
},
74+
};
75+
76+
export default MCPServers;

frontend/src/pages/Admin/Agents/AgentFlows/index.jsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export default function AgentFlowsList({
2222
}
2323

2424
return (
25-
<div className="bg-theme-bg-secondary text-white rounded-xl min-w-[360px] w-fit">
25+
<div className="bg-theme-bg-secondary text-white rounded-xl w-full md:min-w-[360px]">
2626
{flows.map((flow, index) => (
2727
<div
2828
key={flow.uuid}

frontend/src/pages/Admin/Agents/Imported/SkillList/index.jsx

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { CaretRight } from "@phosphor-icons/react";
2-
import { isMobile } from "react-device-detect";
32
import { sentenceCase } from "text-case";
43

54
export default function ImportedSkillList({
@@ -27,9 +26,7 @@ export default function ImportedSkillList({
2726

2827
return (
2928
<div
30-
className={`bg-theme-bg-secondary text-white rounded-xl ${
31-
isMobile ? "w-full" : "min-w-[360px] w-fit"
32-
}`}
29+
className={`bg-theme-bg-secondary text-white rounded-xl w-full md:min-w-[360px]`}
3330
>
3431
{skills.map((config, index) => (
3532
<div

0 commit comments

Comments
 (0)