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