sunholo 0.115.3__tar.gz → 0.116.0__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 (167) hide show
  1. {sunholo-0.115.3 → sunholo-0.116.0}/PKG-INFO +4 -3
  2. {sunholo-0.115.3 → sunholo-0.116.0}/setup.py +5 -3
  3. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/cli/cli.py +4 -0
  4. sunholo-0.116.0/sunholo/mcp/__init__.py +0 -0
  5. sunholo-0.116.0/sunholo/mcp/cli.py +256 -0
  6. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo.egg-info/PKG-INFO +4 -3
  7. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo.egg-info/SOURCES.txt +2 -0
  8. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo.egg-info/requires.txt +2 -1
  9. {sunholo-0.115.3 → sunholo-0.116.0}/LICENSE.txt +0 -0
  10. {sunholo-0.115.3 → sunholo-0.116.0}/MANIFEST.in +0 -0
  11. {sunholo-0.115.3 → sunholo-0.116.0}/README.md +0 -0
  12. {sunholo-0.115.3 → sunholo-0.116.0}/setup.cfg +0 -0
  13. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/__init__.py +0 -0
  14. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/agents/__init__.py +0 -0
  15. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/agents/chat_history.py +0 -0
  16. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/agents/dispatch_to_qa.py +0 -0
  17. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/agents/fastapi/__init__.py +0 -0
  18. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/agents/fastapi/base.py +0 -0
  19. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/agents/fastapi/qna_routes.py +0 -0
  20. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/agents/flask/__init__.py +0 -0
  21. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/agents/flask/base.py +0 -0
  22. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/agents/flask/qna_routes.py +0 -0
  23. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/agents/flask/vac_routes.py +0 -0
  24. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/agents/langserve.py +0 -0
  25. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/agents/pubsub.py +0 -0
  26. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/agents/route.py +0 -0
  27. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/agents/special_commands.py +0 -0
  28. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/agents/swagger.py +0 -0
  29. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/archive/__init__.py +0 -0
  30. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/archive/archive.py +0 -0
  31. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/auth/__init__.py +0 -0
  32. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/auth/gcloud.py +0 -0
  33. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/auth/refresh.py +0 -0
  34. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/auth/run.py +0 -0
  35. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/azure/__init__.py +0 -0
  36. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/azure/auth.py +0 -0
  37. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/azure/blobs.py +0 -0
  38. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/azure/event_grid.py +0 -0
  39. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/bots/__init__.py +0 -0
  40. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/bots/discord.py +0 -0
  41. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/bots/github_webhook.py +0 -0
  42. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/bots/webapp.py +0 -0
  43. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/chunker/__init__.py +0 -0
  44. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/chunker/azure.py +0 -0
  45. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/chunker/doc_handling.py +0 -0
  46. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/chunker/encode_metadata.py +0 -0
  47. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/chunker/images.py +0 -0
  48. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/chunker/loaders.py +0 -0
  49. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/chunker/message_data.py +0 -0
  50. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/chunker/pdfs.py +0 -0
  51. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/chunker/process_chunker_data.py +0 -0
  52. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/chunker/publish.py +0 -0
  53. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/chunker/pubsub.py +0 -0
  54. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/chunker/splitter.py +0 -0
  55. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/cli/__init__.py +0 -0
  56. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/cli/chat_vac.py +0 -0
  57. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/cli/cli_init.py +0 -0
  58. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/cli/configs.py +0 -0
  59. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/cli/deploy.py +0 -0
  60. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/cli/embedder.py +0 -0
  61. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/cli/merge_texts.py +0 -0
  62. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/cli/run_proxy.py +0 -0
  63. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/cli/sun_rich.py +0 -0
  64. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/cli/swagger.py +0 -0
  65. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/cli/vertex.py +0 -0
  66. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/components/__init__.py +0 -0
  67. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/components/llm.py +0 -0
  68. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/components/retriever.py +0 -0
  69. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/components/vectorstore.py +0 -0
  70. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/custom_logging.py +0 -0
  71. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/database/__init__.py +0 -0
  72. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/database/alloydb.py +0 -0
  73. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/database/alloydb_client.py +0 -0
  74. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/database/database.py +0 -0
  75. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/database/lancedb.py +0 -0
  76. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/database/sql/sb/create_function.sql +0 -0
  77. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/database/sql/sb/create_function_time.sql +0 -0
  78. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/database/sql/sb/create_table.sql +0 -0
  79. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/database/sql/sb/delete_source_row.sql +0 -0
  80. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/database/sql/sb/return_sources.sql +0 -0
  81. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/database/sql/sb/setup.sql +0 -0
  82. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/database/static_dbs.py +0 -0
  83. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/database/uuid.py +0 -0
  84. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/discovery_engine/__init__.py +0 -0
  85. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/discovery_engine/chunker_handler.py +0 -0
  86. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/discovery_engine/create_new.py +0 -0
  87. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/discovery_engine/discovery_engine_client.py +0 -0
  88. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/discovery_engine/get_ai_search_chunks.py +0 -0
  89. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/embedder/__init__.py +0 -0
  90. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/embedder/embed_chunk.py +0 -0
  91. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/excel/__init__.py +0 -0
  92. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/excel/plugin.py +0 -0
  93. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/gcs/__init__.py +0 -0
  94. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/gcs/add_file.py +0 -0
  95. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/gcs/download_folder.py +0 -0
  96. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/gcs/download_url.py +0 -0
  97. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/gcs/extract_and_sign.py +0 -0
  98. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/gcs/metadata.py +0 -0
  99. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/genai/__init__.py +0 -0
  100. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/genai/file_handling.py +0 -0
  101. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/genai/images.py +0 -0
  102. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/genai/init.py +0 -0
  103. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/genai/process_funcs_cls.py +0 -0
  104. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/genai/safety.py +0 -0
  105. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/invoke/__init__.py +0 -0
  106. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/invoke/async_class.py +0 -0
  107. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/invoke/direct_vac_func.py +0 -0
  108. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/invoke/invoke_vac_utils.py +0 -0
  109. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/langfuse/__init__.py +0 -0
  110. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/langfuse/callback.py +0 -0
  111. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/langfuse/evals.py +0 -0
  112. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/langfuse/prompts.py +0 -0
  113. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/llamaindex/__init__.py +0 -0
  114. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/llamaindex/get_files.py +0 -0
  115. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/llamaindex/import_files.py +0 -0
  116. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/llamaindex/llamaindex_class.py +0 -0
  117. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/llamaindex/user_history.py +0 -0
  118. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/lookup/__init__.py +0 -0
  119. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/lookup/model_lookup.yaml +0 -0
  120. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/pubsub/__init__.py +0 -0
  121. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/pubsub/process_pubsub.py +0 -0
  122. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/pubsub/pubsub_manager.py +0 -0
  123. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/qna/__init__.py +0 -0
  124. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/qna/parsers.py +0 -0
  125. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/qna/retry.py +0 -0
  126. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/senses/__init__.py +0 -0
  127. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/senses/stream_voice.py +0 -0
  128. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/streaming/__init__.py +0 -0
  129. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/streaming/content_buffer.py +0 -0
  130. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/streaming/langserve.py +0 -0
  131. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/streaming/stream_lookup.py +0 -0
  132. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/streaming/streaming.py +0 -0
  133. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/summarise/__init__.py +0 -0
  134. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/summarise/summarise.py +0 -0
  135. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/terraform/__init__.py +0 -0
  136. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/terraform/tfvars_editor.py +0 -0
  137. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/tools/__init__.py +0 -0
  138. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/tools/web_browser.py +0 -0
  139. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/types.py +0 -0
  140. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/utils/__init__.py +0 -0
  141. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/utils/api_key.py +0 -0
  142. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/utils/big_context.py +0 -0
  143. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/utils/config.py +0 -0
  144. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/utils/config_class.py +0 -0
  145. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/utils/config_schema.py +0 -0
  146. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/utils/gcp.py +0 -0
  147. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/utils/gcp_project.py +0 -0
  148. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/utils/mime.py +0 -0
  149. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/utils/parsers.py +0 -0
  150. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/utils/timedelta.py +0 -0
  151. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/utils/user_ids.py +0 -0
  152. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/utils/version.py +0 -0
  153. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/vertex/__init__.py +0 -0
  154. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/vertex/extensions_call.py +0 -0
  155. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/vertex/extensions_class.py +0 -0
  156. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/vertex/genai_functions.py +0 -0
  157. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/vertex/init.py +0 -0
  158. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/vertex/memory_tools.py +0 -0
  159. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/vertex/safety.py +0 -0
  160. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo/vertex/type_dict_to_json.py +0 -0
  161. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo.egg-info/dependency_links.txt +0 -0
  162. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo.egg-info/entry_points.txt +0 -0
  163. {sunholo-0.115.3 → sunholo-0.116.0}/sunholo.egg-info/top_level.txt +0 -0
  164. {sunholo-0.115.3 → sunholo-0.116.0}/tests/test_async.py +0 -0
  165. {sunholo-0.115.3 → sunholo-0.116.0}/tests/test_chat_history.py +0 -0
  166. {sunholo-0.115.3 → sunholo-0.116.0}/tests/test_config.py +0 -0
  167. {sunholo-0.115.3 → sunholo-0.116.0}/tests/test_unstructured.py +0 -0
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sunholo
3
- Version: 0.115.3
3
+ Version: 0.116.0
4
4
  Summary: Large Language Model DevOps - a package to help deploy LLMs to the Cloud.
5
5
  Home-page: https://github.com/sunholo-data/sunholo-py
6
- Download-URL: https://github.com/sunholo-data/sunholo-py/archive/refs/tags/v0.115.3.tar.gz
6
+ Download-URL: https://github.com/sunholo-data/sunholo-py/archive/refs/tags/v0.116.0.tar.gz
7
7
  Author: Holosun ApS
8
8
  Author-email: multivac@sunholo.com
9
9
  License: Apache License, Version 2.0
@@ -138,7 +138,8 @@ Provides-Extra: openai
138
138
  Requires-Dist: langchain-openai==0.1.25; extra == "openai"
139
139
  Requires-Dist: tiktoken; extra == "openai"
140
140
  Provides-Extra: anthropic
141
- Requires-Dist: langchain-anthropic==0.1.23; extra == "anthropic"
141
+ Requires-Dist: langchain-anthropic>=0.1.23; extra == "anthropic"
142
+ Requires-Dist: mcp; extra == "anthropic"
142
143
  Provides-Extra: tools
143
144
  Requires-Dist: openapi-spec-validator; extra == "tools"
144
145
  Requires-Dist: playwright; extra == "tools"
@@ -1,6 +1,6 @@
1
1
  from setuptools import setup, find_packages
2
2
 
3
- version = '0.115.3'
3
+ version = '0.116.0'
4
4
 
5
5
  setup(
6
6
  name='sunholo',
@@ -159,7 +159,8 @@ setup(
159
159
  "tiktoken"
160
160
  ],
161
161
  'anthropic': [
162
- "langchain-anthropic==0.1.23"
162
+ "langchain-anthropic>=0.1.23",
163
+ "mcp"
163
164
  ],
164
165
  'tools' : [
165
166
  'openapi-spec-validator',
@@ -188,7 +189,8 @@ setup(
188
189
  'google-cloud-texttospeech',
189
190
  'numpy',
190
191
  'sounddevice',
191
- ]
192
+ ],
193
+
192
194
 
193
195
  },
194
196
  classifiers=[
@@ -14,6 +14,8 @@ from ..llamaindex import setup_llamaindex_subparser
14
14
  from ..excel import setup_excel_subparser
15
15
  from ..terraform import setup_tfvarseditor_subparser
16
16
  from ..senses.stream_voice import setup_tts_subparser
17
+ from ..mcp.cli import setup_mcp_subparser
18
+
17
19
 
18
20
  from ..utils import ConfigManager
19
21
  from ..utils.version import sunholo_version
@@ -101,6 +103,8 @@ def main(args=None):
101
103
  setup_tfvarseditor_subparser(subparsers)
102
104
  # tts
103
105
  setup_tts_subparser(subparsers)
106
+ # anthropic MCP
107
+ setup_mcp_subparser(subparsers)
104
108
 
105
109
  #TODO: add database setup commands: alloydb and supabase
106
110
 
File without changes
@@ -0,0 +1,256 @@
1
+ import os
2
+ import asyncio
3
+ from typing import Any, Sequence
4
+ from functools import lru_cache
5
+ import subprocess
6
+ from mcp.server import Server
7
+ from mcp.server.stdio import stdio_server
8
+ from mcp.types import (
9
+ Resource,
10
+ Tool,
11
+ TextContent,
12
+ ImageContent,
13
+ EmbeddedResource,
14
+ )
15
+ """
16
+ try:
17
+ from mcp.server import Server
18
+ from mcp.server.stdio import stdio_server
19
+ from mcp.types import (
20
+ Resource,
21
+ Tool,
22
+ TextContent,
23
+ ImageContent,
24
+ EmbeddedResource,
25
+ )
26
+ except ImportError:
27
+ Server = None
28
+ """
29
+
30
+ from pydantic import AnyUrl
31
+
32
+ # Configure logging
33
+ from ..custom_logging import setup_logging
34
+ logger = setup_logging("sunholo-mcp-server")
35
+
36
+ class SunholoMCPServer:
37
+ def __init__(self):
38
+ if Server is None:
39
+ raise ImportError("SunholoMCPServer requires `sunholo[anthropic]` to be installed")
40
+
41
+ self.server = Server("sunholo-mcp-server")
42
+ self.setup_handlers()
43
+
44
+ def setup_handlers(self):
45
+ """Set up all the MCP protocol handlers"""
46
+ self.setup_resource_handlers()
47
+ self.setup_tool_handlers()
48
+
49
+ def setup_resource_handlers(self):
50
+ """Configure resource-related handlers"""
51
+
52
+ @self.server.list_resources()
53
+ async def list_resources() -> list[Resource]:
54
+ """List available Sunholo resources"""
55
+ return [
56
+ Resource(
57
+ uri="sunholo://vacs/list",
58
+ name="Available Sunholo VACs",
59
+ mimeType="application/json",
60
+ description="List of available Virtual Agent Computers"
61
+ )
62
+ ]
63
+
64
+ @self.server.read_resource()
65
+ async def read_resource(uri: AnyUrl) -> str:
66
+ """Read Sunholo resources based on URI"""
67
+ if str(uri) == "sunholo://vacs/list":
68
+ try:
69
+ # Execute sunholo vac list command
70
+ result = subprocess.run(
71
+ ["sunholo", "vac", "list", "--debug"],
72
+ capture_output=True,
73
+ text=True
74
+ )
75
+ return result.stdout
76
+ except subprocess.CalledProcessError as e:
77
+ raise RuntimeError(f"Failed to list VACs: {str(e)}")
78
+ except Exception as e:
79
+ raise RuntimeError(f"Error accessing Sunholo: {str(e)}")
80
+
81
+ raise ValueError(f"Unknown resource: {uri}")
82
+
83
+ def setup_tool_handlers(self):
84
+ """Configure tool-related handlers"""
85
+
86
+ @self.server.list_tools()
87
+ async def list_tools() -> list[Tool]:
88
+ """List available Sunholo tools"""
89
+ return [
90
+ Tool(
91
+ name="chat_with_vac",
92
+ description="Chat with a specific Sunholo VAC",
93
+ inputSchema={
94
+ "type": "object",
95
+ "properties": {
96
+ "vac_name": {
97
+ "type": "string",
98
+ "description": "Name of the VAC to chat with"
99
+ },
100
+ "message": {
101
+ "type": "string",
102
+ "description": "Message to send to the VAC"
103
+ },
104
+ "headless": {
105
+ "type": "boolean",
106
+ "description": "Whether to run in headless mode",
107
+ "default": True
108
+ }
109
+ },
110
+ "required": ["vac_name", "message"]
111
+ }
112
+ ),
113
+ Tool(
114
+ name="embed_content",
115
+ description="Embed content in a VAC's vector store",
116
+ inputSchema={
117
+ "type": "object",
118
+ "properties": {
119
+ "vac_name": {
120
+ "type": "string",
121
+ "description": "Name of the VAC to embed content for"
122
+ },
123
+ "content": {
124
+ "type": "string",
125
+ "description": "Content to embed"
126
+ },
127
+ "local_chunks": {
128
+ "type": "boolean",
129
+ "description": "Whether to process chunks locally",
130
+ "default": False
131
+ }
132
+ },
133
+ "required": ["vac_name", "content"]
134
+ }
135
+ )
136
+ ]
137
+
138
+ @self.server.call_tool()
139
+ async def call_tool(
140
+ name: str,
141
+ arguments: Any
142
+ ) -> Sequence[TextContent | ImageContent | EmbeddedResource]:
143
+ """Handle tool calls for Sunholo interactions"""
144
+
145
+ if name == "chat_with_vac":
146
+ if not isinstance(arguments, dict):
147
+ raise ValueError("Invalid arguments format")
148
+
149
+ vac_name = arguments.get("vac_name")
150
+ message = arguments.get("message")
151
+ headless = arguments.get("headless", True)
152
+
153
+ if not vac_name or not message:
154
+ raise ValueError("Missing required arguments")
155
+
156
+ try:
157
+ cmd = ["sunholo", "vac", "chat", vac_name, message]
158
+ if headless:
159
+ cmd.append("--headless")
160
+
161
+ result = subprocess.run(
162
+ cmd,
163
+ capture_output=True,
164
+ text=True
165
+ )
166
+
167
+ return [
168
+ TextContent(
169
+ type="text",
170
+ text=result.stdout
171
+ )
172
+ ]
173
+ except subprocess.CalledProcessError as e:
174
+ return [
175
+ TextContent(
176
+ type="text",
177
+ text=f"Error chatting with VAC: {e.stderr}"
178
+ )
179
+ ]
180
+
181
+ elif name == "embed_content":
182
+ if not isinstance(arguments, dict):
183
+ raise ValueError("Invalid arguments format")
184
+
185
+ vac_name = arguments.get("vac_name")
186
+ content = arguments.get("content")
187
+ local_chunks = arguments.get("local_chunks", False)
188
+
189
+ if not vac_name or not content:
190
+ raise ValueError("Missing required arguments")
191
+
192
+ try:
193
+ cmd = ["sunholo", "embed", vac_name, content]
194
+ if local_chunks:
195
+ cmd.append("--local-chunks")
196
+
197
+ result = subprocess.run(
198
+ cmd,
199
+ capture_output=True,
200
+ text=True
201
+ )
202
+
203
+ return [
204
+ TextContent(
205
+ type="text",
206
+ text=result.stdout
207
+ )
208
+ ]
209
+ except subprocess.CalledProcessError as e:
210
+ return [
211
+ TextContent(
212
+ type="text",
213
+ text=f"Error embedding content: {e.stderr}"
214
+ )
215
+ ]
216
+
217
+ raise ValueError(f"Unknown tool: {name}")
218
+
219
+ async def run(self):
220
+ """Run the MCP server"""
221
+ async with stdio_server() as (read_stream, write_stream):
222
+ await self.server.run(
223
+ read_stream,
224
+ write_stream,
225
+ self.server.create_initialization_options()
226
+ )
227
+
228
+ def cli_mcp(args):
229
+ """CLI handler for the MCP server command"""
230
+ try:
231
+
232
+ # Create and run the MCP server
233
+ server = SunholoMCPServer()
234
+
235
+ logger.info("Starting Sunholo MCP server...")
236
+ asyncio.run(server.run())
237
+
238
+ except Exception as e:
239
+ logger.error(f"Error running MCP server: {str(e)}")
240
+ raise
241
+
242
+ def setup_mcp_subparser(subparsers):
243
+ """
244
+ Sets up an argparse subparser for the 'mcp' command.
245
+
246
+ By default will use configurations within the folder specified by '_CONFIG_FOLDER'
247
+
248
+ Example command:
249
+ ```bash
250
+ sunholo mcp
251
+ ```
252
+ """
253
+ mcp_parser = subparsers.add_parser('mcp',
254
+ help='Start an Anthropic MCP server that wraps `sunholo` functionality')
255
+
256
+ mcp_parser.set_defaults(func=cli_mcp)
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sunholo
3
- Version: 0.115.3
3
+ Version: 0.116.0
4
4
  Summary: Large Language Model DevOps - a package to help deploy LLMs to the Cloud.
5
5
  Home-page: https://github.com/sunholo-data/sunholo-py
6
- Download-URL: https://github.com/sunholo-data/sunholo-py/archive/refs/tags/v0.115.3.tar.gz
6
+ Download-URL: https://github.com/sunholo-data/sunholo-py/archive/refs/tags/v0.116.0.tar.gz
7
7
  Author: Holosun ApS
8
8
  Author-email: multivac@sunholo.com
9
9
  License: Apache License, Version 2.0
@@ -138,7 +138,8 @@ Provides-Extra: openai
138
138
  Requires-Dist: langchain-openai==0.1.25; extra == "openai"
139
139
  Requires-Dist: tiktoken; extra == "openai"
140
140
  Provides-Extra: anthropic
141
- Requires-Dist: langchain-anthropic==0.1.23; extra == "anthropic"
141
+ Requires-Dist: langchain-anthropic>=0.1.23; extra == "anthropic"
142
+ Requires-Dist: mcp; extra == "anthropic"
142
143
  Provides-Extra: tools
143
144
  Requires-Dist: openapi-spec-validator; extra == "tools"
144
145
  Requires-Dist: playwright; extra == "tools"
@@ -118,6 +118,8 @@ sunholo/llamaindex/llamaindex_class.py
118
118
  sunholo/llamaindex/user_history.py
119
119
  sunholo/lookup/__init__.py
120
120
  sunholo/lookup/model_lookup.yaml
121
+ sunholo/mcp/__init__.py
122
+ sunholo/mcp/cli.py
121
123
  sunholo/pubsub/__init__.py
122
124
  sunholo/pubsub/process_pubsub.py
123
125
  sunholo/pubsub/pubsub_manager.py
@@ -67,7 +67,8 @@ unstructured[all-docs,local-inference]
67
67
  xlwings
68
68
 
69
69
  [anthropic]
70
- langchain-anthropic==0.1.23
70
+ langchain-anthropic>=0.1.23
71
+ mcp
71
72
 
72
73
  [azure]
73
74
  azure-identity
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes