Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion surfsense_backend/app/agents/new_chat/tools/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ async def my_tool(param: str) -> dict:
),
"""

from app.agents.services.mcp_service import MCPService

from collections.abc import Callable
from dataclasses import dataclass, field
from typing import Any
Expand Down Expand Up @@ -167,6 +169,7 @@ def build_tools(
enabled_tools: list[str] | None = None,
disabled_tools: list[str] | None = None,
additional_tools: list[BaseTool] | None = None,
mcp_service: MCPService | None = None,
) -> list[BaseTool]:
"""
Build the list of tools for the agent.
Expand Down Expand Up @@ -219,11 +222,13 @@ def build_tools(
raise ValueError(
f"Tool '{tool_def.name}' requires dependencies: {missing_deps}"
)

# Create the tool
tool = tool_def.factory(dependencies)
tools.append(tool)

if mcp_service:
mcp_tools = await mcp_service.get_tools()
tools.extend(mcp_tools)
# Add any additional custom tools
if additional_tools:
tools.extend(additional_tools)
Expand Down
1 change: 1 addition & 0 deletions surfsense_backend/app/agents/services/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .mcp_service import MCPService
24 changes: 24 additions & 0 deletions surfsense_backend/app/agents/services/mcp_service.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from langchain_core.tools.base import BaseTool
from langchain_mcp_adapters.client import MultiServerMCPClient
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.ext.asyncio import AsyncSession


class MCPService:
def __init__(self, user_id: int, db_session: AsyncSession):
self.user_id = user_id
self.db_session = db_session
self.client = None

async def initialize(self):
servers = await self._load_user_mcp_servers()
if servers:
self.client = MultiServerMCPClient(servers)

async def get_tools(self) -> list[BaseTool]:
if not self.client:
return []
return await self.client.get_tools()

async def _load_user_mcp_servers(self) -> dict:
return {}
25 changes: 25 additions & 0 deletions surfsense_backend/app/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -974,3 +974,28 @@ def get_default_roles_config() -> list[dict]:
"is_system_role": True,
},
]


class MCPServerConfig(Base):
"""
MCP Model for the server configurations which are made by the users.
"""

__tablename__ = "mcp_server_configs"

id = Column(Integer, primary_key=True)
user_id = Column(Integer, ForeignKey("user.id"))
name = Column(String, nullable=False)
# "stdio" or "http"
transport = Column(String)
# for stdio
command = Column(String, nullable=True)
# for stdio
args = Column(JSON, nullable=True)
# for http
url = Column(String, nullable=True)
# for http auth
headers = Column(JSON, nullable=True)
enabled = Column(Boolean, default=True)

user = relationship("User", back_populates="mcp_servers")
1 change: 1 addition & 0 deletions surfsense_backend/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ dependencies = [
"chonkie[all]>=1.5.0",
"langgraph-checkpoint-postgres>=3.0.2",
"psycopg[binary,pool]>=3.3.2",
"langchain-mcp-adapters>=0.2.1",
]

[dependency-groups]
Expand Down
Loading