sunholo 0.143.3__py3-none-any.whl → 0.143.7__py3-none-any.whl

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.
sunholo/__init__.py CHANGED
@@ -15,7 +15,10 @@ from . import invoke
15
15
  from . import langfuse
16
16
  from . import llamaindex
17
17
  from . import lookup
18
- from . import mcp
18
+ try:
19
+ from . import mcp
20
+ except ImportError:
21
+ mcp = None
19
22
  from . import ollama
20
23
  from . import pubsub
21
24
  from . import qna
@@ -38,12 +38,14 @@ except ImportError:
38
38
 
39
39
  try:
40
40
  from ...mcp.vac_mcp_server import VACMCPServer
41
- from mcp.server.models import InitializationOptions
42
- from mcp import JSONRPCMessage, ErrorData, INTERNAL_ERROR
41
+ from mcp.server import Server
42
+ from mcp.types import JSONRPCMessage, ErrorData, INTERNAL_ERROR
43
43
  except ImportError:
44
44
  VACMCPServer = None
45
- InitializationOptions = None
45
+ Server = None
46
46
  JSONRPCMessage = None
47
+ ErrorData = None
48
+ INTERNAL_ERROR = None
47
49
 
48
50
  try:
49
51
  from ...a2a.vac_a2a_agent import VACA2AAgent
@@ -1062,11 +1064,8 @@ if __name__ == "__main__":
1062
1064
 
1063
1065
  try:
1064
1066
  # Process the request through the server
1065
- await server.run(
1066
- read_messages(),
1067
- write_queue,
1068
- InitializationOptions() if InitializationOptions else None
1069
- )
1067
+ # Use the server's run method with HTTP transport
1068
+ await server.run()
1070
1069
  except Exception as e:
1071
1070
  log.error(f"Error processing MCP request: {e}")
1072
1071
  await write_queue.put(None)
@@ -1084,15 +1083,8 @@ if __name__ == "__main__":
1084
1083
  loop = asyncio.new_event_loop()
1085
1084
  asyncio.set_event_loop(loop)
1086
1085
  try:
1087
- responses = loop.run_until_complete(process_request())
1088
-
1089
- # Parse and return the response
1090
- if responses:
1091
- # The response should be a single JSON-RPC response
1092
- response_data = json_module.loads(responses[0])
1093
- return jsonify(response_data)
1094
- else:
1095
- return jsonify({"error": "No response from MCP server"}), 500
1086
+ response_data = loop.run_until_complete(process_request())
1087
+ return jsonify(response_data)
1096
1088
 
1097
1089
  except Exception as e:
1098
1090
  log.error(f"MCP server error: {str(e)}")
sunholo/mcp/__init__.py CHANGED
@@ -14,7 +14,16 @@
14
14
 
15
15
  """MCP (Model Context Protocol) integration for Sunholo."""
16
16
 
17
- from .mcp_manager import MCPClientManager
18
- from .vac_mcp_server import VACMCPServer
17
+ try:
18
+ from .mcp_manager import MCPClientManager
19
+ except ImportError as e:
20
+ print(f"Warning: MCPClientManager not available - {e}")
21
+ MCPClientManager = None
22
+
23
+ try:
24
+ from .vac_mcp_server import VACMCPServer
25
+ except ImportError as e:
26
+ print(f"Warning: VACMCPServer not available - {e}")
27
+ VACMCPServer = None
19
28
 
20
29
  __all__ = ['MCPClientManager', 'VACMCPServer']
@@ -4,11 +4,34 @@ This shows how to integrate MCP servers with your Flask/VACRoutes application.
4
4
  """
5
5
 
6
6
  from typing import Dict, Any, List, Optional
7
+ import asyncio
7
8
 
8
- # Official MCP imports
9
- from mcp import StdioServerParameters, ClientSession
10
- from mcp.client.stdio import stdio_client
11
- from mcp.types import Tool, Resource, TextContent, CallToolResult
9
+ # MCP SDK imports - try different import paths
10
+ try:
11
+ from mcp.client.stdio import StdioClientTransport
12
+ from mcp.client.session import ClientSession
13
+ except ImportError:
14
+ try:
15
+ # Alternative import paths
16
+ from mcp.client import StdioClientTransport, ClientSession
17
+ except ImportError:
18
+ try:
19
+ # Another alternative
20
+ from mcp import StdioClientTransport, ClientSession
21
+ except ImportError:
22
+ StdioClientTransport = None
23
+ ClientSession = None
24
+
25
+ try:
26
+ from mcp.types import Tool, Resource, TextContent, CallToolResult
27
+ except ImportError:
28
+ try:
29
+ from mcp import Tool, Resource, TextContent, CallToolResult
30
+ except ImportError:
31
+ Tool = None
32
+ Resource = None
33
+ TextContent = None
34
+ CallToolResult = None
12
35
 
13
36
 
14
37
  class MCPClientManager:
@@ -23,41 +46,42 @@ class MCPClientManager:
23
46
  if server_name in self.sessions:
24
47
  return self.sessions[server_name]
25
48
 
26
- # Create server parameters
27
- server_params = StdioServerParameters(
49
+ if not StdioClientTransport or not ClientSession:
50
+ raise ImportError("MCP client dependencies not available")
51
+
52
+ # Create transport and session
53
+ transport = StdioClientTransport(
28
54
  command=command,
29
55
  args=args or []
30
56
  )
57
+ session = ClientSession(transport)
58
+ await session.initialize()
31
59
 
32
- # Connect to the server
33
- async with stdio_client(server_params) as (read, write):
34
- # Create and initialize client session directly
35
- session = ClientSession(read, write)
36
- await session.initialize()
37
- self.sessions[server_name] = session
38
- self.server_configs[server_name] = {
39
- "command": command,
40
- "args": args
41
- }
42
- return session
60
+ self.sessions[server_name] = session
61
+ self.server_configs[server_name] = {
62
+ "command": command,
63
+ "args": args
64
+ }
65
+ return session
43
66
 
44
67
  async def list_tools(self, server_name: Optional[str] = None) -> List[Tool]:
45
68
  """List available tools from one or all connected servers."""
46
69
  if server_name:
47
70
  session = self.sessions.get(server_name)
48
71
  if session:
49
- return await session.list_tools()
72
+ result = await session.list_tools()
73
+ return result.tools
50
74
  return []
51
75
 
52
76
  # List from all servers
53
77
  all_tools = []
54
78
  for name, session in self.sessions.items():
55
- tools = await session.list_tools()
79
+ result = await session.list_tools()
56
80
  # Add server name to tool metadata
57
- for tool in tools:
81
+ for tool in result.tools:
58
82
  tool.metadata = tool.metadata or {}
59
83
  tool.metadata["server"] = name
60
- all_tools.extend(tools)
84
+ all_tools.extend(result.tools)
61
85
  return all_tools
62
86
 
63
87
  async def call_tool(self, server_name: str, tool_name: str, arguments: Dict[str, Any]) -> CallToolResult:
@@ -67,7 +91,13 @@ class MCPClientManager:
67
91
  raise ValueError(f"Not connected to server: {server_name}")
68
92
 
69
93
  # Call the tool
70
- result = await session.call_tool(tool_name, arguments)
94
+ try:
95
+ from mcp.types import CallToolRequest
96
+ request = CallToolRequest(name=tool_name, arguments=arguments)
97
+ result = await session.call_tool(request)
98
+ except ImportError:
99
+ # Try direct call if Request types not available
100
+ result = await session.call_tool(tool_name, arguments)
71
101
  return result
72
102
 
73
103
  async def list_resources(self, server_name: Optional[str] = None) -> List[Resource]:
@@ -75,17 +105,18 @@ class MCPClientManager:
75
105
  if server_name:
76
106
  session = self.sessions.get(server_name)
77
107
  if session:
78
- return await session.list_resources()
108
+ result = await session.list_resources()
109
+ return result.resources
79
110
  return []
80
111
 
81
112
  # List from all servers
82
113
  all_resources = []
83
114
  for name, session in self.sessions.items():
84
- resources = await session.list_resources()
85
- for resource in resources:
115
+ result = await session.list_resources()
116
+ for resource in result.resources:
86
117
  resource.metadata = resource.metadata or {}
87
118
  resource.metadata["server"] = name
88
- all_resources.extend(resources)
119
+ all_resources.extend(result.resources)
89
120
  return all_resources
90
121
 
91
122
  async def read_resource(self, server_name: str, uri: str) -> List[TextContent]:
@@ -94,5 +125,12 @@ class MCPClientManager:
94
125
  if not session:
95
126
  raise ValueError(f"Not connected to server: {server_name}")
96
127
 
97
- result = await session.read_resource(uri)
98
- return result.contents
128
+ try:
129
+ from mcp.types import ReadResourceRequest
130
+ request = ReadResourceRequest(uri=uri)
131
+ result = await session.read_resource(request)
132
+ except ImportError:
133
+ # Try direct call if Request types not available
134
+ result = await session.read_resource(uri)
135
+
136
+ return result.contents if hasattr(result, 'contents') else result
@@ -22,13 +22,8 @@ import json
22
22
  import asyncio
23
23
  from functools import partial
24
24
 
25
- try:
26
- from mcp.server import Server
27
- from mcp.types import Tool, TextContent, ImageContent, EmbeddedResource
28
- except ImportError:
29
- Server = None
30
- Tool = None
31
- TextContent = None
25
+ from mcp.server import Server
26
+ from mcp.types import Tool, TextContent, ImageContent, EmbeddedResource
32
27
 
33
28
  from ..custom_logging import log
34
29
  from ..streaming import start_streaming_chat_async
@@ -45,8 +40,7 @@ class VACMCPServer:
45
40
  stream_interpreter: The streaming interpreter function
46
41
  vac_interpreter: The static VAC interpreter function (optional)
47
42
  """
48
- if Server is None:
49
- raise ImportError("MCP server requires `pip install sunholo[anthropic]`")
43
+ # MCP server is always available with current SDK
50
44
 
51
45
  self.stream_interpreter = stream_interpreter
52
46
  self.vac_interpreter = vac_interpreter
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sunholo
3
- Version: 0.143.3
3
+ Version: 0.143.7
4
4
  Summary: AI DevOps - a package to help deploy GenAI to the Cloud.
5
5
  Author-email: Holosun ApS <multivac@sunholo.com>
6
6
  License: Apache License, Version 2.0
@@ -1,4 +1,4 @@
1
- sunholo/__init__.py,sha256=InRbX4V0-qdNHo9zYH3GEye7ASLR6LX8-SMvPV4Jsaw,1212
1
+ sunholo/__init__.py,sha256=_zHD01JyUVc-kGqm_bWtWxytec3b8-25fm5vK5j_2VU,1256
2
2
  sunholo/custom_logging.py,sha256=JXZTnXp_DixP3jwYfKw4LYRDS9IuTq7ctCgfZbI2rxA,22023
3
3
  sunholo/langchain_types.py,sha256=uZ4zvgej_f7pLqjtu4YP7qMC_eZD5ym_5x4pyvA1Ih4,1834
4
4
  sunholo/a2a/__init__.py,sha256=ohwR-3_toRUdyj3ACNCVPrd_V2lzR5tmL5Hwn1ChSSU,1049
@@ -18,7 +18,7 @@ sunholo/agents/fastapi/base.py,sha256=W-cyF8ZDUH40rc-c-Apw3-_8IIi2e4Y9qRtnoVnsc1
18
18
  sunholo/agents/fastapi/qna_routes.py,sha256=lKHkXPmwltu9EH3RMwmD153-J6pE7kWQ4BhBlV3to-s,3864
19
19
  sunholo/agents/flask/__init__.py,sha256=dEoByI3gDNUOjpX1uVKP7uPjhfFHJubbiaAv3xLopnk,63
20
20
  sunholo/agents/flask/base.py,sha256=vnpxFEOnCmt9humqj-jYPLfJcdwzsop9NorgkJ-tSaU,1756
21
- sunholo/agents/flask/vac_routes.py,sha256=4Wenjq1Mg9gnmVt_5nHH3Uzhvio269lo2N9v38VxT48,53850
21
+ sunholo/agents/flask/vac_routes.py,sha256=MvEsIWxrdeuRx-t_RfkodnJyJKP40aKaADWV4Yi3ijw,53375
22
22
  sunholo/archive/__init__.py,sha256=qNHWm5rGPVOlxZBZCpA1wTYPbalizRT7f8X4rs2t290,31
23
23
  sunholo/archive/archive.py,sha256=PxVfDtO2_2ZEEbnhXSCbXLdeoHoQVImo4y3Jr2XkCFY,1204
24
24
  sunholo/auth/__init__.py,sha256=TeP-OY0XGxYV_8AQcVGoh35bvyWhNUcMRfhuD5l44Sk,91
@@ -114,10 +114,10 @@ sunholo/llamaindex/llamaindex_class.py,sha256=PnpPoc7LpP7xvKIXYu-UvI4ehj67pGhE1E
114
114
  sunholo/llamaindex/user_history.py,sha256=ZtkecWuF9ORduyGB8kF8gP66bm9DdvCI-ZiK6Kt-cSE,2265
115
115
  sunholo/lookup/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
116
116
  sunholo/lookup/model_lookup.yaml,sha256=O7o-jP53MLA06C8pI-ILwERShO-xf6z_258wtpZBv6A,739
117
- sunholo/mcp/__init__.py,sha256=GmKB8Z0ecXUzpuzYEOXSI0aaZP7LZJc7yTCMEFdAmi4,791
117
+ sunholo/mcp/__init__.py,sha256=Bi0ZYMvWuf1AL_QSrMAREVVdTZFiIokGwrytBXKBJyc,1028
118
118
  sunholo/mcp/cli.py,sha256=d24nnVzhZYz4AWgTqmN-qjKG4rPbf8RhdmEOHZkBHy8,10570
119
- sunholo/mcp/mcp_manager.py,sha256=ooa_2JSNaKIuK9azEV0OaPVf5Mp_tL_DHaYEyFCmgKY,3752
120
- sunholo/mcp/vac_mcp_server.py,sha256=fRcerTqp_pTK8AVITpGPhrez_IaDuUDr4WnVUHPv8GM,10114
119
+ sunholo/mcp/mcp_manager.py,sha256=g75vv6XvM24U7uz366slE-p76Qs4AvVcsarHSF9qIvE,5061
120
+ sunholo/mcp/vac_mcp_server.py,sha256=DSSMsTeLU_1C2hHTvgLjZsg1chyMfb_S9ruCUw2f_dc,9969
121
121
  sunholo/ollama/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
122
122
  sunholo/ollama/ollama_images.py,sha256=H2cpcNu88R4TwyfL_nnqkQhdvBQ2FPCAy4Ok__0yQmo,2351
123
123
  sunholo/pubsub/__init__.py,sha256=DfTEk4zmCfqn6gFxRrqDO0pOrvXTDqH-medpgYO4PGw,117
@@ -175,9 +175,9 @@ sunholo/vertex/init.py,sha256=1OQwcPBKZYBTDPdyU7IM4X4OmiXLdsNV30C-fee2scQ,2875
175
175
  sunholo/vertex/memory_tools.py,sha256=tBZxqVZ4InTmdBvLlOYwoSEWu4-kGquc-gxDwZCC4FA,7667
176
176
  sunholo/vertex/safety.py,sha256=S9PgQT1O_BQAkcqauWncRJaydiP8Q_Jzmu9gxYfy1VA,2482
177
177
  sunholo/vertex/type_dict_to_json.py,sha256=uTzL4o9tJRao4u-gJOFcACgWGkBOtqACmb6ihvCErL8,4694
178
- sunholo-0.143.3.dist-info/licenses/LICENSE.txt,sha256=SdE3QjnD3GEmqqg9EX3TM9f7WmtOzqS1KJve8rhbYmU,11345
179
- sunholo-0.143.3.dist-info/METADATA,sha256=d36VCf5W1j1lyZ7HIe_vBHxOPyQ_f_UNhTD1X6_FjiQ,18413
180
- sunholo-0.143.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
181
- sunholo-0.143.3.dist-info/entry_points.txt,sha256=bZuN5AIHingMPt4Ro1b_T-FnQvZ3teBes-3OyO0asl4,49
182
- sunholo-0.143.3.dist-info/top_level.txt,sha256=wt5tadn5--5JrZsjJz2LceoUvcrIvxjHJe-RxuudxAk,8
183
- sunholo-0.143.3.dist-info/RECORD,,
178
+ sunholo-0.143.7.dist-info/licenses/LICENSE.txt,sha256=SdE3QjnD3GEmqqg9EX3TM9f7WmtOzqS1KJve8rhbYmU,11345
179
+ sunholo-0.143.7.dist-info/METADATA,sha256=c1IhnVsC3r20UUvBImOmvOIirVrkuNY6Tj-xFuF3jr0,18413
180
+ sunholo-0.143.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
181
+ sunholo-0.143.7.dist-info/entry_points.txt,sha256=bZuN5AIHingMPt4Ro1b_T-FnQvZ3teBes-3OyO0asl4,49
182
+ sunholo-0.143.7.dist-info/top_level.txt,sha256=wt5tadn5--5JrZsjJz2LceoUvcrIvxjHJe-RxuudxAk,8
183
+ sunholo-0.143.7.dist-info/RECORD,,