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.
Files changed (28) hide show
  1. friday_framework_mcp-0.1.0a0/.gitignore +24 -0
  2. friday_framework_mcp-0.1.0a0/PKG-INFO +90 -0
  3. friday_framework_mcp-0.1.0a0/README.md +60 -0
  4. friday_framework_mcp-0.1.0a0/pyproject.toml +71 -0
  5. friday_framework_mcp-0.1.0a0/src/friday_mcp/__init__.py +95 -0
  6. friday_framework_mcp-0.1.0a0/src/friday_mcp/client/__init__.py +26 -0
  7. friday_framework_mcp-0.1.0a0/src/friday_mcp/client/adapter.py +212 -0
  8. friday_framework_mcp-0.1.0a0/src/friday_mcp/client/base.py +330 -0
  9. friday_framework_mcp-0.1.0a0/src/friday_mcp/client/manager.py +278 -0
  10. friday_framework_mcp-0.1.0a0/src/friday_mcp/client/sse.py +217 -0
  11. friday_framework_mcp-0.1.0a0/src/friday_mcp/client/stdio.py +206 -0
  12. friday_framework_mcp-0.1.0a0/src/friday_mcp/config.py +175 -0
  13. friday_framework_mcp-0.1.0a0/src/friday_mcp/protocols.py +208 -0
  14. friday_framework_mcp-0.1.0a0/src/friday_mcp/server/__init__.py +24 -0
  15. friday_framework_mcp-0.1.0a0/src/friday_mcp/server/agent_mode.py +252 -0
  16. friday_framework_mcp-0.1.0a0/src/friday_mcp/server/base.py +340 -0
  17. friday_framework_mcp-0.1.0a0/src/friday_mcp/server/sse.py +243 -0
  18. friday_framework_mcp-0.1.0a0/src/friday_mcp/server/stdio.py +121 -0
  19. friday_framework_mcp-0.1.0a0/src/friday_mcp/server/tools_mode.py +198 -0
  20. friday_framework_mcp-0.1.0a0/src/friday_mcp/utils/__init__.py +12 -0
  21. friday_framework_mcp-0.1.0a0/src/friday_mcp/utils/schema.py +86 -0
  22. friday_framework_mcp-0.1.0a0/tests_mcp/__init__.py +2 -0
  23. friday_framework_mcp-0.1.0a0/tests_mcp/client/__init__.py +2 -0
  24. friday_framework_mcp-0.1.0a0/tests_mcp/client/test_adapter.py +175 -0
  25. friday_framework_mcp-0.1.0a0/tests_mcp/conftest.py +143 -0
  26. friday_framework_mcp-0.1.0a0/tests_mcp/server/__init__.py +2 -0
  27. friday_framework_mcp-0.1.0a0/tests_mcp/test_config.py +165 -0
  28. 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