friday-framework-mcp 0.1.0a0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- friday_framework_mcp-0.1.0a0/.gitignore +24 -0
- friday_framework_mcp-0.1.0a0/PKG-INFO +90 -0
- friday_framework_mcp-0.1.0a0/README.md +60 -0
- friday_framework_mcp-0.1.0a0/pyproject.toml +71 -0
- friday_framework_mcp-0.1.0a0/src/friday_mcp/__init__.py +95 -0
- friday_framework_mcp-0.1.0a0/src/friday_mcp/client/__init__.py +26 -0
- friday_framework_mcp-0.1.0a0/src/friday_mcp/client/adapter.py +212 -0
- friday_framework_mcp-0.1.0a0/src/friday_mcp/client/base.py +330 -0
- friday_framework_mcp-0.1.0a0/src/friday_mcp/client/manager.py +278 -0
- friday_framework_mcp-0.1.0a0/src/friday_mcp/client/sse.py +217 -0
- friday_framework_mcp-0.1.0a0/src/friday_mcp/client/stdio.py +206 -0
- friday_framework_mcp-0.1.0a0/src/friday_mcp/config.py +175 -0
- friday_framework_mcp-0.1.0a0/src/friday_mcp/protocols.py +208 -0
- friday_framework_mcp-0.1.0a0/src/friday_mcp/server/__init__.py +24 -0
- friday_framework_mcp-0.1.0a0/src/friday_mcp/server/agent_mode.py +252 -0
- friday_framework_mcp-0.1.0a0/src/friday_mcp/server/base.py +340 -0
- friday_framework_mcp-0.1.0a0/src/friday_mcp/server/sse.py +243 -0
- friday_framework_mcp-0.1.0a0/src/friday_mcp/server/stdio.py +121 -0
- friday_framework_mcp-0.1.0a0/src/friday_mcp/server/tools_mode.py +198 -0
- friday_framework_mcp-0.1.0a0/src/friday_mcp/utils/__init__.py +12 -0
- friday_framework_mcp-0.1.0a0/src/friday_mcp/utils/schema.py +86 -0
- friday_framework_mcp-0.1.0a0/tests_mcp/__init__.py +2 -0
- friday_framework_mcp-0.1.0a0/tests_mcp/client/__init__.py +2 -0
- friday_framework_mcp-0.1.0a0/tests_mcp/client/test_adapter.py +175 -0
- friday_framework_mcp-0.1.0a0/tests_mcp/conftest.py +143 -0
- friday_framework_mcp-0.1.0a0/tests_mcp/server/__init__.py +2 -0
- friday_framework_mcp-0.1.0a0/tests_mcp/test_config.py +165 -0
- friday_framework_mcp-0.1.0a0/tests_mcp/test_protocols.py +163 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
__pycache__/
|
|
2
|
+
*.pyc
|
|
3
|
+
.env
|
|
4
|
+
.venv/
|
|
5
|
+
.idea/
|
|
6
|
+
.vscode/
|
|
7
|
+
dist/
|
|
8
|
+
build/
|
|
9
|
+
*.egg-info/
|
|
10
|
+
chroma_db/
|
|
11
|
+
.friday/
|
|
12
|
+
/vector/
|
|
13
|
+
/exports/
|
|
14
|
+
tests/integration/memory/vector/*/
|
|
15
|
+
tests/integration/memory/vector/backups/*/
|
|
16
|
+
tests/integration/memory/vector/reorganization_logs/*
|
|
17
|
+
*.gpickle
|
|
18
|
+
keys.txt
|
|
19
|
+
experiments/*/config/runtime.local.yaml
|
|
20
|
+
experiments/*/artifacts/*
|
|
21
|
+
!experiments/*/artifacts/.gitkeep
|
|
22
|
+
scripts/source-friday-chat-example-env.sh
|
|
23
|
+
scripts/pypi.sh
|
|
24
|
+
/docs/reference/PyPI-Recovery-Codes-cichuck-2026-07-20T15_36_49.709334.txt
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: friday-framework-mcp
|
|
3
|
+
Version: 0.1.0a0
|
|
4
|
+
Summary: MCP (Model Context Protocol) integration for Friday Framework
|
|
5
|
+
Project-URL: Homepage, https://github.com/CIChuck/agent-framework
|
|
6
|
+
Project-URL: Repository, https://github.com/CIChuck/agent-framework
|
|
7
|
+
Project-URL: Issues, https://github.com/CIChuck/agent-framework/issues
|
|
8
|
+
Project-URL: Documentation, https://github.com/CIChuck/agent-framework/tree/main/docs
|
|
9
|
+
Project-URL: Source, https://github.com/CIChuck/agent-framework/tree/main/packages/friday-mcp
|
|
10
|
+
Author: Friday Team
|
|
11
|
+
License-Expression: MIT
|
|
12
|
+
Keywords: agents,ai,llm,mcp,model-context-protocol
|
|
13
|
+
Requires-Python: >=3.10
|
|
14
|
+
Requires-Dist: friday-framework-core==0.1.0a0
|
|
15
|
+
Requires-Dist: httpx>=0.25.0
|
|
16
|
+
Requires-Dist: pydantic>=2.0.0
|
|
17
|
+
Provides-Extra: dev
|
|
18
|
+
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
|
|
19
|
+
Requires-Dist: pytest-mock>=3.10.0; extra == 'dev'
|
|
20
|
+
Requires-Dist: pytest>=8.0.0; extra == 'dev'
|
|
21
|
+
Provides-Extra: full
|
|
22
|
+
Requires-Dist: fastapi>=0.100.0; extra == 'full'
|
|
23
|
+
Requires-Dist: friday-framework-agent==0.1.0a0; extra == 'full'
|
|
24
|
+
Requires-Dist: friday-framework-tools==0.1.0a0; extra == 'full'
|
|
25
|
+
Requires-Dist: uvicorn>=0.23.0; extra == 'full'
|
|
26
|
+
Provides-Extra: server
|
|
27
|
+
Requires-Dist: fastapi>=0.100.0; extra == 'server'
|
|
28
|
+
Requires-Dist: uvicorn>=0.23.0; extra == 'server'
|
|
29
|
+
Description-Content-Type: text/markdown
|
|
30
|
+
|
|
31
|
+
# Friday Framework MCP
|
|
32
|
+
|
|
33
|
+
MCP (Model Context Protocol) integration for the Friday Framework.
|
|
34
|
+
|
|
35
|
+
## Features
|
|
36
|
+
|
|
37
|
+
- **MCP Client**: Connect to external MCP servers and consume their tools
|
|
38
|
+
- **MCP Server**: Expose Friday capabilities (agent or tools) via MCP
|
|
39
|
+
- **Transport Support**: Both stdio (subprocess) and SSE (HTTP streaming)
|
|
40
|
+
- **Tool Adaptation**: Seamlessly adapt MCP tools to Friday's ToolDefinition protocol
|
|
41
|
+
|
|
42
|
+
## Installation
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
# Core package
|
|
46
|
+
pip install friday-framework-mcp
|
|
47
|
+
|
|
48
|
+
# With SSE server support
|
|
49
|
+
pip install friday-framework-mcp[server]
|
|
50
|
+
|
|
51
|
+
# Full integration with Friday
|
|
52
|
+
pip install friday-framework-mcp[full]
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Quick Start
|
|
56
|
+
|
|
57
|
+
### Connecting to MCP Servers (Client)
|
|
58
|
+
|
|
59
|
+
```python
|
|
60
|
+
from friday_mcp import MCPClientManager, MCPConfig, MCPServerConfig
|
|
61
|
+
|
|
62
|
+
config = MCPConfig(
|
|
63
|
+
servers=[
|
|
64
|
+
MCPServerConfig(
|
|
65
|
+
name="filesystem",
|
|
66
|
+
command="npx",
|
|
67
|
+
args=["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
|
|
68
|
+
)
|
|
69
|
+
]
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
async with MCPClientManager(config) as manager:
|
|
73
|
+
tools = await manager.get_all_tools()
|
|
74
|
+
# Use tools with Friday's agent
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Exposing Friday as MCP Server
|
|
78
|
+
|
|
79
|
+
```python
|
|
80
|
+
from friday_mcp import StdioMCPServer, MCPServerSettings
|
|
81
|
+
from friday_mcp.server.agent_mode import configure_agent_mode
|
|
82
|
+
|
|
83
|
+
server = StdioMCPServer()
|
|
84
|
+
configure_agent_mode(server, agent, profile, MCPServerSettings())
|
|
85
|
+
await server.start()
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## License
|
|
89
|
+
|
|
90
|
+
MIT
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Friday Framework MCP
|
|
2
|
+
|
|
3
|
+
MCP (Model Context Protocol) integration for the Friday Framework.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **MCP Client**: Connect to external MCP servers and consume their tools
|
|
8
|
+
- **MCP Server**: Expose Friday capabilities (agent or tools) via MCP
|
|
9
|
+
- **Transport Support**: Both stdio (subprocess) and SSE (HTTP streaming)
|
|
10
|
+
- **Tool Adaptation**: Seamlessly adapt MCP tools to Friday's ToolDefinition protocol
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
# Core package
|
|
16
|
+
pip install friday-framework-mcp
|
|
17
|
+
|
|
18
|
+
# With SSE server support
|
|
19
|
+
pip install friday-framework-mcp[server]
|
|
20
|
+
|
|
21
|
+
# Full integration with Friday
|
|
22
|
+
pip install friday-framework-mcp[full]
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Quick Start
|
|
26
|
+
|
|
27
|
+
### Connecting to MCP Servers (Client)
|
|
28
|
+
|
|
29
|
+
```python
|
|
30
|
+
from friday_mcp import MCPClientManager, MCPConfig, MCPServerConfig
|
|
31
|
+
|
|
32
|
+
config = MCPConfig(
|
|
33
|
+
servers=[
|
|
34
|
+
MCPServerConfig(
|
|
35
|
+
name="filesystem",
|
|
36
|
+
command="npx",
|
|
37
|
+
args=["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
|
|
38
|
+
)
|
|
39
|
+
]
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
async with MCPClientManager(config) as manager:
|
|
43
|
+
tools = await manager.get_all_tools()
|
|
44
|
+
# Use tools with Friday's agent
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Exposing Friday as MCP Server
|
|
48
|
+
|
|
49
|
+
```python
|
|
50
|
+
from friday_mcp import StdioMCPServer, MCPServerSettings
|
|
51
|
+
from friday_mcp.server.agent_mode import configure_agent_mode
|
|
52
|
+
|
|
53
|
+
server = StdioMCPServer()
|
|
54
|
+
configure_agent_mode(server, agent, profile, MCPServerSettings())
|
|
55
|
+
await server.start()
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## License
|
|
59
|
+
|
|
60
|
+
MIT
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "friday-framework-mcp"
|
|
3
|
+
version = "0.1.0a0"
|
|
4
|
+
description = "MCP (Model Context Protocol) integration for Friday Framework"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.10"
|
|
7
|
+
license = "MIT"
|
|
8
|
+
authors = [{ name = "Friday Team" }]
|
|
9
|
+
keywords = ["ai", "agents", "mcp", "model-context-protocol", "llm"]
|
|
10
|
+
|
|
11
|
+
dependencies = [
|
|
12
|
+
# Core protocols
|
|
13
|
+
"friday-framework-core==0.1.0a0",
|
|
14
|
+
|
|
15
|
+
# HTTP client for SSE transport
|
|
16
|
+
"httpx>=0.25.0",
|
|
17
|
+
|
|
18
|
+
# Configuration models
|
|
19
|
+
"pydantic>=2.0.0",
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
[project.urls]
|
|
23
|
+
Homepage = "https://github.com/CIChuck/agent-framework"
|
|
24
|
+
Repository = "https://github.com/CIChuck/agent-framework"
|
|
25
|
+
Issues = "https://github.com/CIChuck/agent-framework/issues"
|
|
26
|
+
Documentation = "https://github.com/CIChuck/agent-framework/tree/main/docs"
|
|
27
|
+
Source = "https://github.com/CIChuck/agent-framework/tree/main/packages/friday-mcp"
|
|
28
|
+
|
|
29
|
+
[project.optional-dependencies]
|
|
30
|
+
dev = [
|
|
31
|
+
"pytest>=8.0.0",
|
|
32
|
+
"pytest-asyncio>=0.23.0",
|
|
33
|
+
"pytest-mock>=3.10.0",
|
|
34
|
+
]
|
|
35
|
+
|
|
36
|
+
# SSE server support (FastAPI-based)
|
|
37
|
+
server = [
|
|
38
|
+
"fastapi>=0.100.0",
|
|
39
|
+
"uvicorn>=0.23.0",
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
# Full integration with Friday packages
|
|
43
|
+
full = [
|
|
44
|
+
"friday-framework-mcp[server]==0.1.0a0",
|
|
45
|
+
"friday-framework-tools==0.1.0a0",
|
|
46
|
+
"friday-framework-agent==0.1.0a0",
|
|
47
|
+
]
|
|
48
|
+
|
|
49
|
+
[build-system]
|
|
50
|
+
requires = ["hatchling"]
|
|
51
|
+
build-backend = "hatchling.build"
|
|
52
|
+
|
|
53
|
+
[tool.hatch.build.targets.wheel]
|
|
54
|
+
packages = ["src/friday_mcp"]
|
|
55
|
+
|
|
56
|
+
[tool.pytest.ini_options]
|
|
57
|
+
testpaths = ["tests_mcp"]
|
|
58
|
+
asyncio_mode = "auto"
|
|
59
|
+
asyncio_default_fixture_loop_scope = "function"
|
|
60
|
+
|
|
61
|
+
[tool.uv.sources]
|
|
62
|
+
friday-framework-core = { workspace = true }
|
|
63
|
+
friday-framework-tools = { workspace = true }
|
|
64
|
+
friday-framework-agent = { workspace = true }
|
|
65
|
+
|
|
66
|
+
[tool.ruff]
|
|
67
|
+
line-length = 88
|
|
68
|
+
target-version = "py310"
|
|
69
|
+
|
|
70
|
+
[tool.ruff.lint]
|
|
71
|
+
select = ["E", "F", "I", "UP", "B", "SIM"]
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# mypy: ignore-errors
|
|
2
|
+
"""
|
|
3
|
+
Friday MCP Integration Package.
|
|
4
|
+
|
|
5
|
+
Provides bidirectional Model Context Protocol (MCP) integration:
|
|
6
|
+
- MCP Client: Connect to external MCP servers and consume their tools
|
|
7
|
+
- MCP Server: Expose Friday capabilities (agent or tools) via MCP
|
|
8
|
+
|
|
9
|
+
Example (Client - connecting to MCP servers):
|
|
10
|
+
from friday_mcp import MCPClientManager, MCPConfig, MCPServerConfig
|
|
11
|
+
|
|
12
|
+
config = MCPConfig(
|
|
13
|
+
servers=[
|
|
14
|
+
MCPServerConfig(
|
|
15
|
+
name="filesystem",
|
|
16
|
+
command="npx",
|
|
17
|
+
args=["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
|
|
18
|
+
)
|
|
19
|
+
]
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
async with MCPClientManager(config) as manager:
|
|
23
|
+
tools = await manager.get_all_tools()
|
|
24
|
+
# Register tools with Friday's registry
|
|
25
|
+
|
|
26
|
+
Example (Server - exposing Friday via MCP):
|
|
27
|
+
from friday_mcp import StdioMCPServer, MCPServerSettings
|
|
28
|
+
from friday_mcp.server.agent_mode import configure_agent_mode
|
|
29
|
+
|
|
30
|
+
server = StdioMCPServer()
|
|
31
|
+
configure_agent_mode(server, agent, profile, settings)
|
|
32
|
+
await server.start()
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
from friday_mcp.config import (
|
|
36
|
+
MCPConfig,
|
|
37
|
+
MCPServerConfig,
|
|
38
|
+
MCPServerSettings,
|
|
39
|
+
ServerMode,
|
|
40
|
+
TransportType,
|
|
41
|
+
)
|
|
42
|
+
from friday_mcp.protocols import (
|
|
43
|
+
MCPClient,
|
|
44
|
+
MCPServer,
|
|
45
|
+
MCPTransport,
|
|
46
|
+
ToolAdapter,
|
|
47
|
+
ToolDefinition,
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
__version__ = "0.1.0"
|
|
51
|
+
|
|
52
|
+
__all__ = [
|
|
53
|
+
# Protocols
|
|
54
|
+
"MCPClient",
|
|
55
|
+
"MCPServer",
|
|
56
|
+
"MCPTransport",
|
|
57
|
+
"ToolDefinition",
|
|
58
|
+
"ToolAdapter",
|
|
59
|
+
# Configuration
|
|
60
|
+
"MCPConfig",
|
|
61
|
+
"MCPServerConfig",
|
|
62
|
+
"MCPServerSettings",
|
|
63
|
+
"TransportType",
|
|
64
|
+
"ServerMode",
|
|
65
|
+
]
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
# Lazy imports for client/server implementations
|
|
69
|
+
def __getattr__(name: str):
|
|
70
|
+
"""Lazy import client and server implementations."""
|
|
71
|
+
if name == "MCPClientManager":
|
|
72
|
+
from friday_mcp.client.manager import MCPClientManager
|
|
73
|
+
|
|
74
|
+
return MCPClientManager
|
|
75
|
+
if name == "StdioMCPClient":
|
|
76
|
+
from friday_mcp.client.stdio import StdioMCPClient
|
|
77
|
+
|
|
78
|
+
return StdioMCPClient
|
|
79
|
+
if name == "SSEMCPClient":
|
|
80
|
+
from friday_mcp.client.sse import SSEMCPClient
|
|
81
|
+
|
|
82
|
+
return SSEMCPClient
|
|
83
|
+
if name == "MCPToolAdapter":
|
|
84
|
+
from friday_mcp.client.adapter import MCPToolAdapter
|
|
85
|
+
|
|
86
|
+
return MCPToolAdapter
|
|
87
|
+
if name == "StdioMCPServer":
|
|
88
|
+
from friday_mcp.server.stdio import StdioMCPServer
|
|
89
|
+
|
|
90
|
+
return StdioMCPServer
|
|
91
|
+
if name == "SSEMCPServer":
|
|
92
|
+
from friday_mcp.server.sse import SSEMCPServer
|
|
93
|
+
|
|
94
|
+
return SSEMCPServer
|
|
95
|
+
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# mypy: ignore-errors
|
|
2
|
+
"""
|
|
3
|
+
MCP Client implementations.
|
|
4
|
+
|
|
5
|
+
Provides clients for connecting to external MCP servers:
|
|
6
|
+
- StdioMCPClient: Connect via subprocess stdio
|
|
7
|
+
- SSEMCPClient: Connect via HTTP Server-Sent Events
|
|
8
|
+
- MCPClientManager: Manage multiple server connections
|
|
9
|
+
- MCPToolAdapter: Adapt MCP tools to Friday's ToolDefinition
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from friday_mcp.client.adapter import MCPToolAdapter, MCPToolWrapper
|
|
13
|
+
from friday_mcp.client.base import MCPClientBase, MCPError
|
|
14
|
+
from friday_mcp.client.manager import MCPClientManager
|
|
15
|
+
from friday_mcp.client.sse import SSEMCPClient
|
|
16
|
+
from friday_mcp.client.stdio import StdioMCPClient
|
|
17
|
+
|
|
18
|
+
__all__ = [
|
|
19
|
+
"MCPClientBase",
|
|
20
|
+
"MCPError",
|
|
21
|
+
"StdioMCPClient",
|
|
22
|
+
"SSEMCPClient",
|
|
23
|
+
"MCPClientManager",
|
|
24
|
+
"MCPToolAdapter",
|
|
25
|
+
"MCPToolWrapper",
|
|
26
|
+
]
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
# mypy: ignore-errors
|
|
2
|
+
"""
|
|
3
|
+
MCP Tool Adapter.
|
|
4
|
+
|
|
5
|
+
Adapts MCP tools to Friday's ToolDefinition protocol.
|
|
6
|
+
Follows the pattern from friday-tools/adapters/.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import logging
|
|
12
|
+
from typing import TYPE_CHECKING, Any
|
|
13
|
+
|
|
14
|
+
from friday_core.interfaces.tools import SchemaFormat
|
|
15
|
+
|
|
16
|
+
from friday_mcp.protocols import MCPClient, ToolDefinition
|
|
17
|
+
from friday_mcp.utils.schema import mcp_to_friday_schema
|
|
18
|
+
|
|
19
|
+
if TYPE_CHECKING:
|
|
20
|
+
from friday_mcp.client.base import MCPClientBase
|
|
21
|
+
|
|
22
|
+
logger = logging.getLogger(__name__)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class MCPToolWrapper:
|
|
26
|
+
"""
|
|
27
|
+
Wraps an MCP tool as a Friday ToolDefinition.
|
|
28
|
+
|
|
29
|
+
Similar to LangChainToolWrapper and AnthropicToolWrapper
|
|
30
|
+
in friday-tools/adapters/.
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
def __init__(
|
|
34
|
+
self,
|
|
35
|
+
client: MCPClient,
|
|
36
|
+
tool_def: dict[str, Any],
|
|
37
|
+
name_prefix: str = "",
|
|
38
|
+
):
|
|
39
|
+
"""
|
|
40
|
+
Initialize MCP tool wrapper.
|
|
41
|
+
|
|
42
|
+
Args:
|
|
43
|
+
client: Connected MCP client for executing the tool
|
|
44
|
+
tool_def: MCP tool definition from tools/list
|
|
45
|
+
name_prefix: Optional prefix for tool name
|
|
46
|
+
"""
|
|
47
|
+
self._client = client
|
|
48
|
+
self._tool_def = tool_def
|
|
49
|
+
self._name_prefix = name_prefix
|
|
50
|
+
self._original_name = tool_def.get("name", "unknown")
|
|
51
|
+
|
|
52
|
+
@property
|
|
53
|
+
def name(self) -> str:
|
|
54
|
+
"""Tool name with optional prefix."""
|
|
55
|
+
if self._name_prefix:
|
|
56
|
+
return f"{self._name_prefix}{self._original_name}"
|
|
57
|
+
return self._original_name
|
|
58
|
+
|
|
59
|
+
@property
|
|
60
|
+
def description(self) -> str:
|
|
61
|
+
"""Tool description."""
|
|
62
|
+
return self._tool_def.get("description", f"MCP tool: {self._original_name}")
|
|
63
|
+
|
|
64
|
+
@property
|
|
65
|
+
def parameters_schema(self) -> dict[str, Any]:
|
|
66
|
+
"""Convert MCP inputSchema to Friday parameters_schema."""
|
|
67
|
+
input_schema = self._tool_def.get("inputSchema", {})
|
|
68
|
+
return mcp_to_friday_schema(input_schema)
|
|
69
|
+
|
|
70
|
+
async def execute(self, **kwargs: Any) -> str:
|
|
71
|
+
"""Execute the tool via MCP client."""
|
|
72
|
+
return await self._client.call_tool(self._original_name, kwargs)
|
|
73
|
+
|
|
74
|
+
def to_schema(self, format: str = "plain") -> dict[str, Any]:
|
|
75
|
+
"""
|
|
76
|
+
Convert to JSON schema format for LLM function calling.
|
|
77
|
+
|
|
78
|
+
Args:
|
|
79
|
+
format: Output format - "plain" or "openai".
|
|
80
|
+
|
|
81
|
+
Returns:
|
|
82
|
+
Dictionary suitable for LLM function calling.
|
|
83
|
+
"""
|
|
84
|
+
plain_schema = {
|
|
85
|
+
"name": self.name,
|
|
86
|
+
"description": self.description,
|
|
87
|
+
"parameters": self.parameters_schema,
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if format == SchemaFormat.OPENAI or format == "openai":
|
|
91
|
+
return {
|
|
92
|
+
"type": "function",
|
|
93
|
+
"function": plain_schema,
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return plain_schema
|
|
97
|
+
|
|
98
|
+
def __repr__(self) -> str:
|
|
99
|
+
return f"MCPToolWrapper(name={self.name!r})"
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
class MCPToolAdapter:
|
|
103
|
+
"""
|
|
104
|
+
Adapts MCP tools to Friday's ToolDefinition protocol.
|
|
105
|
+
|
|
106
|
+
Example:
|
|
107
|
+
client = StdioMCPClient(...)
|
|
108
|
+
await client.connect()
|
|
109
|
+
|
|
110
|
+
adapter = MCPToolAdapter(client, prefix="mcp_filesystem_")
|
|
111
|
+
tools = await adapter.get_tools()
|
|
112
|
+
|
|
113
|
+
# Register with Friday's registry
|
|
114
|
+
for tool in tools:
|
|
115
|
+
registry.register(tool)
|
|
116
|
+
"""
|
|
117
|
+
|
|
118
|
+
def __init__(
|
|
119
|
+
self,
|
|
120
|
+
client: MCPClientBase,
|
|
121
|
+
prefix: str = "",
|
|
122
|
+
):
|
|
123
|
+
"""
|
|
124
|
+
Initialize adapter.
|
|
125
|
+
|
|
126
|
+
Args:
|
|
127
|
+
client: Connected MCP client
|
|
128
|
+
prefix: Prefix to add to tool names (e.g., "mcp_filesystem_")
|
|
129
|
+
"""
|
|
130
|
+
self._client = client
|
|
131
|
+
self._prefix = prefix
|
|
132
|
+
self._tools_cache: list[MCPToolWrapper] | None = None
|
|
133
|
+
|
|
134
|
+
async def get_tools(self, refresh: bool = False) -> list[ToolDefinition]:
|
|
135
|
+
"""
|
|
136
|
+
Get all tools from the MCP server as Friday ToolDefinitions.
|
|
137
|
+
|
|
138
|
+
Args:
|
|
139
|
+
refresh: Force refresh of cached tools
|
|
140
|
+
|
|
141
|
+
Returns:
|
|
142
|
+
List of wrapped tools implementing ToolDefinition protocol.
|
|
143
|
+
"""
|
|
144
|
+
if self._tools_cache is not None and not refresh:
|
|
145
|
+
return list(self._tools_cache)
|
|
146
|
+
|
|
147
|
+
mcp_tools = await self._client.list_tools()
|
|
148
|
+
self._tools_cache = [
|
|
149
|
+
MCPToolWrapper(self._client, tool_def, self._prefix)
|
|
150
|
+
for tool_def in mcp_tools
|
|
151
|
+
]
|
|
152
|
+
|
|
153
|
+
logger.debug(f"Adapted {len(self._tools_cache)} tools from {self._client.name}")
|
|
154
|
+
|
|
155
|
+
return list(self._tools_cache)
|
|
156
|
+
|
|
157
|
+
async def get_tool(self, name: str) -> ToolDefinition | None:
|
|
158
|
+
"""
|
|
159
|
+
Get a specific tool by name.
|
|
160
|
+
|
|
161
|
+
Args:
|
|
162
|
+
name: Tool name (with or without prefix)
|
|
163
|
+
|
|
164
|
+
Returns:
|
|
165
|
+
Wrapped tool or None if not found
|
|
166
|
+
"""
|
|
167
|
+
tools = await self.get_tools()
|
|
168
|
+
|
|
169
|
+
# Try exact match first
|
|
170
|
+
for tool in tools:
|
|
171
|
+
if tool.name == name:
|
|
172
|
+
return tool
|
|
173
|
+
|
|
174
|
+
# Try matching original name (without prefix)
|
|
175
|
+
for tool in tools:
|
|
176
|
+
if isinstance(tool, MCPToolWrapper) and tool._original_name == name:
|
|
177
|
+
return tool
|
|
178
|
+
|
|
179
|
+
return None
|
|
180
|
+
|
|
181
|
+
def adapt(self, tool_def: dict[str, Any]) -> ToolDefinition:
|
|
182
|
+
"""
|
|
183
|
+
Adapt a single tool definition.
|
|
184
|
+
|
|
185
|
+
Args:
|
|
186
|
+
tool_def: MCP tool definition
|
|
187
|
+
|
|
188
|
+
Returns:
|
|
189
|
+
Wrapped tool
|
|
190
|
+
"""
|
|
191
|
+
return MCPToolWrapper(self._client, tool_def, self._prefix)
|
|
192
|
+
|
|
193
|
+
def adapt_many(self, tool_defs: list[dict[str, Any]]) -> list[ToolDefinition]:
|
|
194
|
+
"""
|
|
195
|
+
Adapt multiple tool definitions.
|
|
196
|
+
|
|
197
|
+
Args:
|
|
198
|
+
tool_defs: List of MCP tool definitions
|
|
199
|
+
|
|
200
|
+
Returns:
|
|
201
|
+
List of wrapped tools
|
|
202
|
+
"""
|
|
203
|
+
return [self.adapt(tool_def) for tool_def in tool_defs]
|
|
204
|
+
|
|
205
|
+
@property
|
|
206
|
+
def client_name(self) -> str:
|
|
207
|
+
"""Get the name of the underlying client."""
|
|
208
|
+
return self._client.name
|
|
209
|
+
|
|
210
|
+
def clear_cache(self) -> None:
|
|
211
|
+
"""Clear the tools cache."""
|
|
212
|
+
self._tools_cache = None
|