atlas-chat 0.1.0__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.
Files changed (250) hide show
  1. atlas/__init__.py +40 -0
  2. atlas/application/__init__.py +7 -0
  3. atlas/application/chat/__init__.py +7 -0
  4. atlas/application/chat/agent/__init__.py +10 -0
  5. atlas/application/chat/agent/act_loop.py +179 -0
  6. atlas/application/chat/agent/factory.py +142 -0
  7. atlas/application/chat/agent/protocols.py +46 -0
  8. atlas/application/chat/agent/react_loop.py +338 -0
  9. atlas/application/chat/agent/think_act_loop.py +171 -0
  10. atlas/application/chat/approval_manager.py +151 -0
  11. atlas/application/chat/elicitation_manager.py +191 -0
  12. atlas/application/chat/events/__init__.py +1 -0
  13. atlas/application/chat/events/agent_event_relay.py +112 -0
  14. atlas/application/chat/modes/__init__.py +1 -0
  15. atlas/application/chat/modes/agent.py +125 -0
  16. atlas/application/chat/modes/plain.py +74 -0
  17. atlas/application/chat/modes/rag.py +81 -0
  18. atlas/application/chat/modes/tools.py +179 -0
  19. atlas/application/chat/orchestrator.py +213 -0
  20. atlas/application/chat/policies/__init__.py +1 -0
  21. atlas/application/chat/policies/tool_authorization.py +99 -0
  22. atlas/application/chat/preprocessors/__init__.py +1 -0
  23. atlas/application/chat/preprocessors/message_builder.py +92 -0
  24. atlas/application/chat/preprocessors/prompt_override_service.py +104 -0
  25. atlas/application/chat/service.py +454 -0
  26. atlas/application/chat/utilities/__init__.py +6 -0
  27. atlas/application/chat/utilities/error_handler.py +367 -0
  28. atlas/application/chat/utilities/event_notifier.py +546 -0
  29. atlas/application/chat/utilities/file_processor.py +613 -0
  30. atlas/application/chat/utilities/tool_executor.py +789 -0
  31. atlas/atlas_chat_cli.py +347 -0
  32. atlas/atlas_client.py +238 -0
  33. atlas/core/__init__.py +0 -0
  34. atlas/core/auth.py +205 -0
  35. atlas/core/authorization_manager.py +27 -0
  36. atlas/core/capabilities.py +123 -0
  37. atlas/core/compliance.py +215 -0
  38. atlas/core/domain_whitelist.py +147 -0
  39. atlas/core/domain_whitelist_middleware.py +82 -0
  40. atlas/core/http_client.py +28 -0
  41. atlas/core/log_sanitizer.py +102 -0
  42. atlas/core/metrics_logger.py +59 -0
  43. atlas/core/middleware.py +131 -0
  44. atlas/core/otel_config.py +242 -0
  45. atlas/core/prompt_risk.py +200 -0
  46. atlas/core/rate_limit.py +0 -0
  47. atlas/core/rate_limit_middleware.py +64 -0
  48. atlas/core/security_headers_middleware.py +51 -0
  49. atlas/domain/__init__.py +37 -0
  50. atlas/domain/chat/__init__.py +1 -0
  51. atlas/domain/chat/dtos.py +85 -0
  52. atlas/domain/errors.py +96 -0
  53. atlas/domain/messages/__init__.py +12 -0
  54. atlas/domain/messages/models.py +160 -0
  55. atlas/domain/rag_mcp_service.py +664 -0
  56. atlas/domain/sessions/__init__.py +7 -0
  57. atlas/domain/sessions/models.py +36 -0
  58. atlas/domain/unified_rag_service.py +371 -0
  59. atlas/infrastructure/__init__.py +10 -0
  60. atlas/infrastructure/app_factory.py +135 -0
  61. atlas/infrastructure/events/__init__.py +1 -0
  62. atlas/infrastructure/events/cli_event_publisher.py +140 -0
  63. atlas/infrastructure/events/websocket_publisher.py +140 -0
  64. atlas/infrastructure/sessions/in_memory_repository.py +56 -0
  65. atlas/infrastructure/transport/__init__.py +7 -0
  66. atlas/infrastructure/transport/websocket_connection_adapter.py +33 -0
  67. atlas/init_cli.py +226 -0
  68. atlas/interfaces/__init__.py +15 -0
  69. atlas/interfaces/events.py +134 -0
  70. atlas/interfaces/llm.py +54 -0
  71. atlas/interfaces/rag.py +40 -0
  72. atlas/interfaces/sessions.py +75 -0
  73. atlas/interfaces/tools.py +57 -0
  74. atlas/interfaces/transport.py +24 -0
  75. atlas/main.py +564 -0
  76. atlas/mcp/api_key_demo/README.md +76 -0
  77. atlas/mcp/api_key_demo/main.py +172 -0
  78. atlas/mcp/api_key_demo/run.sh +56 -0
  79. atlas/mcp/basictable/main.py +147 -0
  80. atlas/mcp/calculator/main.py +149 -0
  81. atlas/mcp/code-executor/execution_engine.py +98 -0
  82. atlas/mcp/code-executor/execution_environment.py +95 -0
  83. atlas/mcp/code-executor/main.py +528 -0
  84. atlas/mcp/code-executor/result_processing.py +276 -0
  85. atlas/mcp/code-executor/script_generation.py +195 -0
  86. atlas/mcp/code-executor/security_checker.py +140 -0
  87. atlas/mcp/corporate_cars/main.py +437 -0
  88. atlas/mcp/csv_reporter/main.py +545 -0
  89. atlas/mcp/duckduckgo/main.py +182 -0
  90. atlas/mcp/elicitation_demo/README.md +171 -0
  91. atlas/mcp/elicitation_demo/main.py +262 -0
  92. atlas/mcp/env-demo/README.md +158 -0
  93. atlas/mcp/env-demo/main.py +199 -0
  94. atlas/mcp/file_size_test/main.py +284 -0
  95. atlas/mcp/filesystem/main.py +348 -0
  96. atlas/mcp/image_demo/main.py +113 -0
  97. atlas/mcp/image_demo/requirements.txt +4 -0
  98. atlas/mcp/logging_demo/README.md +72 -0
  99. atlas/mcp/logging_demo/main.py +103 -0
  100. atlas/mcp/many_tools_demo/main.py +50 -0
  101. atlas/mcp/order_database/__init__.py +0 -0
  102. atlas/mcp/order_database/main.py +369 -0
  103. atlas/mcp/order_database/signal_data.csv +1001 -0
  104. atlas/mcp/pdfbasic/main.py +394 -0
  105. atlas/mcp/pptx_generator/main.py +760 -0
  106. atlas/mcp/pptx_generator/requirements.txt +13 -0
  107. atlas/mcp/pptx_generator/run_test.sh +1 -0
  108. atlas/mcp/pptx_generator/test_pptx_generator_security.py +169 -0
  109. atlas/mcp/progress_demo/main.py +167 -0
  110. atlas/mcp/progress_updates_demo/QUICKSTART.md +273 -0
  111. atlas/mcp/progress_updates_demo/README.md +120 -0
  112. atlas/mcp/progress_updates_demo/main.py +497 -0
  113. atlas/mcp/prompts/main.py +222 -0
  114. atlas/mcp/public_demo/main.py +189 -0
  115. atlas/mcp/sampling_demo/README.md +169 -0
  116. atlas/mcp/sampling_demo/main.py +234 -0
  117. atlas/mcp/thinking/main.py +77 -0
  118. atlas/mcp/tool_planner/main.py +240 -0
  119. atlas/mcp/ui-demo/badmesh.png +0 -0
  120. atlas/mcp/ui-demo/main.py +383 -0
  121. atlas/mcp/ui-demo/templates/button_demo.html +32 -0
  122. atlas/mcp/ui-demo/templates/data_visualization.html +32 -0
  123. atlas/mcp/ui-demo/templates/form_demo.html +28 -0
  124. atlas/mcp/username-override-demo/README.md +320 -0
  125. atlas/mcp/username-override-demo/main.py +308 -0
  126. atlas/modules/__init__.py +0 -0
  127. atlas/modules/config/__init__.py +34 -0
  128. atlas/modules/config/cli.py +231 -0
  129. atlas/modules/config/config_manager.py +1096 -0
  130. atlas/modules/file_storage/__init__.py +22 -0
  131. atlas/modules/file_storage/cli.py +330 -0
  132. atlas/modules/file_storage/content_extractor.py +290 -0
  133. atlas/modules/file_storage/manager.py +295 -0
  134. atlas/modules/file_storage/mock_s3_client.py +402 -0
  135. atlas/modules/file_storage/s3_client.py +417 -0
  136. atlas/modules/llm/__init__.py +19 -0
  137. atlas/modules/llm/caller.py +287 -0
  138. atlas/modules/llm/litellm_caller.py +675 -0
  139. atlas/modules/llm/models.py +19 -0
  140. atlas/modules/mcp_tools/__init__.py +17 -0
  141. atlas/modules/mcp_tools/client.py +2123 -0
  142. atlas/modules/mcp_tools/token_storage.py +556 -0
  143. atlas/modules/prompts/prompt_provider.py +130 -0
  144. atlas/modules/rag/__init__.py +24 -0
  145. atlas/modules/rag/atlas_rag_client.py +336 -0
  146. atlas/modules/rag/client.py +129 -0
  147. atlas/routes/admin_routes.py +865 -0
  148. atlas/routes/config_routes.py +484 -0
  149. atlas/routes/feedback_routes.py +361 -0
  150. atlas/routes/files_routes.py +274 -0
  151. atlas/routes/health_routes.py +40 -0
  152. atlas/routes/mcp_auth_routes.py +223 -0
  153. atlas/server_cli.py +164 -0
  154. atlas/tests/conftest.py +20 -0
  155. atlas/tests/integration/test_mcp_auth_integration.py +152 -0
  156. atlas/tests/manual_test_sampling.py +87 -0
  157. atlas/tests/modules/mcp_tools/test_client_auth.py +226 -0
  158. atlas/tests/modules/mcp_tools/test_client_env.py +191 -0
  159. atlas/tests/test_admin_mcp_server_management_routes.py +141 -0
  160. atlas/tests/test_agent_roa.py +135 -0
  161. atlas/tests/test_app_factory_smoke.py +47 -0
  162. atlas/tests/test_approval_manager.py +439 -0
  163. atlas/tests/test_atlas_client.py +188 -0
  164. atlas/tests/test_atlas_rag_client.py +447 -0
  165. atlas/tests/test_atlas_rag_integration.py +224 -0
  166. atlas/tests/test_attach_file_flow.py +287 -0
  167. atlas/tests/test_auth_utils.py +165 -0
  168. atlas/tests/test_backend_public_url.py +185 -0
  169. atlas/tests/test_banner_logging.py +287 -0
  170. atlas/tests/test_capability_tokens_and_injection.py +203 -0
  171. atlas/tests/test_compliance_level.py +54 -0
  172. atlas/tests/test_compliance_manager.py +253 -0
  173. atlas/tests/test_config_manager.py +617 -0
  174. atlas/tests/test_config_manager_paths.py +12 -0
  175. atlas/tests/test_core_auth.py +18 -0
  176. atlas/tests/test_core_utils.py +190 -0
  177. atlas/tests/test_docker_env_sync.py +202 -0
  178. atlas/tests/test_domain_errors.py +329 -0
  179. atlas/tests/test_domain_whitelist.py +359 -0
  180. atlas/tests/test_elicitation_manager.py +408 -0
  181. atlas/tests/test_elicitation_routing.py +296 -0
  182. atlas/tests/test_env_demo_server.py +88 -0
  183. atlas/tests/test_error_classification.py +113 -0
  184. atlas/tests/test_error_flow_integration.py +116 -0
  185. atlas/tests/test_feedback_routes.py +333 -0
  186. atlas/tests/test_file_content_extraction.py +1134 -0
  187. atlas/tests/test_file_extraction_routes.py +158 -0
  188. atlas/tests/test_file_library.py +107 -0
  189. atlas/tests/test_file_manager_unit.py +18 -0
  190. atlas/tests/test_health_route.py +49 -0
  191. atlas/tests/test_http_client_stub.py +8 -0
  192. atlas/tests/test_imports_smoke.py +30 -0
  193. atlas/tests/test_interfaces_llm_response.py +9 -0
  194. atlas/tests/test_issue_access_denied_fix.py +136 -0
  195. atlas/tests/test_llm_env_expansion.py +836 -0
  196. atlas/tests/test_log_level_sensitive_data.py +285 -0
  197. atlas/tests/test_mcp_auth_routes.py +341 -0
  198. atlas/tests/test_mcp_client_auth.py +331 -0
  199. atlas/tests/test_mcp_data_injection.py +270 -0
  200. atlas/tests/test_mcp_get_authorized_servers.py +95 -0
  201. atlas/tests/test_mcp_hot_reload.py +512 -0
  202. atlas/tests/test_mcp_image_content.py +424 -0
  203. atlas/tests/test_mcp_logging.py +172 -0
  204. atlas/tests/test_mcp_progress_updates.py +313 -0
  205. atlas/tests/test_mcp_prompt_override_system_prompt.py +102 -0
  206. atlas/tests/test_mcp_prompts_server.py +39 -0
  207. atlas/tests/test_mcp_tool_result_parsing.py +296 -0
  208. atlas/tests/test_metrics_logger.py +56 -0
  209. atlas/tests/test_middleware_auth.py +379 -0
  210. atlas/tests/test_prompt_risk_and_acl.py +141 -0
  211. atlas/tests/test_rag_mcp_aggregator.py +204 -0
  212. atlas/tests/test_rag_mcp_service.py +224 -0
  213. atlas/tests/test_rate_limit_middleware.py +45 -0
  214. atlas/tests/test_routes_config_smoke.py +60 -0
  215. atlas/tests/test_routes_files_download_token.py +41 -0
  216. atlas/tests/test_routes_files_health.py +18 -0
  217. atlas/tests/test_runtime_imports.py +53 -0
  218. atlas/tests/test_sampling_integration.py +482 -0
  219. atlas/tests/test_security_admin_routes.py +61 -0
  220. atlas/tests/test_security_capability_tokens.py +65 -0
  221. atlas/tests/test_security_file_stats_scope.py +21 -0
  222. atlas/tests/test_security_header_injection.py +191 -0
  223. atlas/tests/test_security_headers_and_filename.py +63 -0
  224. atlas/tests/test_shared_session_repository.py +101 -0
  225. atlas/tests/test_system_prompt_loading.py +181 -0
  226. atlas/tests/test_token_storage.py +505 -0
  227. atlas/tests/test_tool_approval_config.py +93 -0
  228. atlas/tests/test_tool_approval_utils.py +356 -0
  229. atlas/tests/test_tool_authorization_group_filtering.py +223 -0
  230. atlas/tests/test_tool_details_in_config.py +108 -0
  231. atlas/tests/test_tool_planner.py +300 -0
  232. atlas/tests/test_unified_rag_service.py +398 -0
  233. atlas/tests/test_username_override_in_approval.py +258 -0
  234. atlas/tests/test_websocket_auth_header.py +168 -0
  235. atlas/version.py +6 -0
  236. atlas_chat-0.1.0.data/data/.env.example +253 -0
  237. atlas_chat-0.1.0.data/data/config/defaults/compliance-levels.json +44 -0
  238. atlas_chat-0.1.0.data/data/config/defaults/domain-whitelist.json +123 -0
  239. atlas_chat-0.1.0.data/data/config/defaults/file-extractors.json +74 -0
  240. atlas_chat-0.1.0.data/data/config/defaults/help-config.json +198 -0
  241. atlas_chat-0.1.0.data/data/config/defaults/llmconfig-buggy.yml +11 -0
  242. atlas_chat-0.1.0.data/data/config/defaults/llmconfig.yml +19 -0
  243. atlas_chat-0.1.0.data/data/config/defaults/mcp.json +138 -0
  244. atlas_chat-0.1.0.data/data/config/defaults/rag-sources.json +17 -0
  245. atlas_chat-0.1.0.data/data/config/defaults/splash-config.json +16 -0
  246. atlas_chat-0.1.0.dist-info/METADATA +236 -0
  247. atlas_chat-0.1.0.dist-info/RECORD +250 -0
  248. atlas_chat-0.1.0.dist-info/WHEEL +5 -0
  249. atlas_chat-0.1.0.dist-info/entry_points.txt +4 -0
  250. atlas_chat-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,120 @@
1
+ # Progress Updates Demo MCP Server
2
+
3
+ This MCP server demonstrates the enhanced progress reporting capabilities that allow MCP servers to send viewable updates to the frontend during tool execution.
4
+
5
+ ## Features
6
+
7
+ This demo shows three types of enhanced progress updates:
8
+
9
+ 1. **Canvas Updates**: Display HTML visualizations in the canvas panel during execution
10
+ 2. **System Messages**: Send rich messages that appear in chat history
11
+ 3. **Progress Artifacts**: Share file artifacts progressively as they're generated
12
+
13
+ ## Tools
14
+
15
+ ### `task_with_canvas_updates`
16
+
17
+ Demonstrates sending HTML progress visualizations to the canvas during execution.
18
+
19
+ **Parameters:**
20
+ - `task_name` (str): Name of the task (default: "demo")
21
+ - `steps` (int): Number of steps to process (default: 5)
22
+ - `interval_seconds` (int): Delay between steps (default: 2)
23
+
24
+ ### `task_with_system_messages`
25
+
26
+ Demonstrates sending rich system messages to chat history during execution.
27
+
28
+ **Parameters:**
29
+ - `task_name` (str): Name of the analysis task (default: "analysis")
30
+ - `stages` (int): Number of stages to process (default: 4)
31
+ - `interval_seconds` (int): Delay between stages (default: 2)
32
+
33
+ ### `task_with_artifacts`
34
+
35
+ Demonstrates sending file artifacts progressively during execution.
36
+
37
+ **Parameters:**
38
+ - `task_name` (str): Name of the processing task (default: "data_processing")
39
+ - `files_to_generate` (int): Number of intermediate files (default: 3)
40
+ - `interval_seconds` (int): Delay between file generation (default: 2)
41
+
42
+ ## How It Works
43
+
44
+ MCP servers can send structured progress updates by encoding JSON data in the progress message field with the prefix `"MCP_UPDATE:"`.
45
+
46
+ ### Supported Update Types
47
+
48
+ #### 1. Canvas Update
49
+ ```python
50
+ update_payload = {
51
+ "type": "canvas_update",
52
+ "content": "<html>...</html>", # HTML content to display
53
+ "progress_message": "Processing..." # Optional progress text
54
+ }
55
+ await ctx.report_progress(
56
+ progress=step,
57
+ total=total_steps,
58
+ message=f"MCP_UPDATE:{json.dumps(update_payload)}"
59
+ )
60
+ ```
61
+
62
+ #### 2. System Message
63
+ ```python
64
+ update_payload = {
65
+ "type": "system_message",
66
+ "message": "Data validation complete!",
67
+ "subtype": "success", # or "info", "warning", "error"
68
+ "progress_message": "Validating data..."
69
+ }
70
+ await ctx.report_progress(
71
+ progress=step,
72
+ total=total_steps,
73
+ message=f"MCP_UPDATE:{json.dumps(update_payload)}"
74
+ )
75
+ ```
76
+
77
+ #### 3. Artifacts
78
+ ```python
79
+ update_payload = {
80
+ "type": "artifacts",
81
+ "artifacts": [
82
+ {
83
+ "name": "result.html",
84
+ "b64": base64_encoded_content,
85
+ "mime": "text/html",
86
+ "size": content_size,
87
+ "description": "Intermediate result",
88
+ "viewer": "html"
89
+ }
90
+ ],
91
+ "display": {
92
+ "open_canvas": True,
93
+ "primary_file": "result.html",
94
+ "mode": "replace"
95
+ },
96
+ "progress_message": "Generated result..."
97
+ }
98
+ await ctx.report_progress(
99
+ progress=step,
100
+ total=total_steps,
101
+ message=f"MCP_UPDATE:{json.dumps(update_payload)}"
102
+ )
103
+ ```
104
+
105
+ ## Usage
106
+
107
+ Try these example prompts:
108
+
109
+ ```
110
+ Show me a task with canvas updates
111
+ Run task_with_system_messages
112
+ Generate artifacts progressively
113
+ ```
114
+
115
+ ## Benefits
116
+
117
+ - **Better UX**: Users see real-time progress with visual feedback
118
+ - **Reduced perceived latency**: Long-running tasks feel more responsive
119
+ - **More informative**: Rich context about what's happening at each stage
120
+ - **Flexible**: Can display any HTML content, images, or file artifacts
@@ -0,0 +1,497 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Progress Updates Demo MCP Server using FastMCP.
4
+
5
+ This server demonstrates the enhanced progress reporting capabilities
6
+ that allow MCP servers to send viewable updates to the frontend during
7
+ tool execution, including:
8
+ - Canvas updates (plots, HTML, images)
9
+ - Rich system messages
10
+ - Progress artifacts
11
+
12
+ To use these features from an MCP server, send special formatted messages
13
+ via ctx.report_progress() with the message field containing:
14
+ "MCP_UPDATE:{json_payload}"
15
+
16
+ Supported update types:
17
+ - canvas_update: Display HTML/images in canvas during execution
18
+ - system_message: Add rich messages to chat history
19
+ - artifacts: Send file artifacts during execution
20
+ """
21
+
22
+ from __future__ import annotations
23
+
24
+ import asyncio
25
+ import base64
26
+ import json
27
+ from typing import Any, Dict
28
+
29
+ from fastmcp import Context, FastMCP
30
+
31
+ # Initialize the MCP server
32
+ mcp = FastMCP("Progress Updates Demo")
33
+
34
+
35
+ def create_progress_html(step: int, total: int, message: str) -> str:
36
+ """Create an HTML progress visualization."""
37
+ percentage = int((step / total) * 100)
38
+ return f"""
39
+ <!DOCTYPE html>
40
+ <html>
41
+ <head>
42
+ <style>
43
+ body {{
44
+ font-family: Arial, sans-serif;
45
+ padding: 20px;
46
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
47
+ color: white;
48
+ }}
49
+ .progress-container {{
50
+ background: rgba(255, 255, 255, 0.2);
51
+ border-radius: 10px;
52
+ padding: 20px;
53
+ backdrop-filter: blur(10px);
54
+ }}
55
+ .progress-bar {{
56
+ width: 100%;
57
+ height: 30px;
58
+ background: rgba(255, 255, 255, 0.3);
59
+ border-radius: 15px;
60
+ overflow: hidden;
61
+ margin: 10px 0;
62
+ }}
63
+ .progress-fill {{
64
+ height: 100%;
65
+ background: linear-gradient(90deg, #4CAF50, #8BC34A);
66
+ width: {percentage}%;
67
+ transition: width 0.3s ease;
68
+ display: flex;
69
+ align-items: center;
70
+ justify-content: center;
71
+ color: white;
72
+ font-weight: bold;
73
+ }}
74
+ h1 {{
75
+ margin: 0 0 10px 0;
76
+ }}
77
+ .step-info {{
78
+ font-size: 18px;
79
+ margin: 10px 0;
80
+ }}
81
+ </style>
82
+ </head>
83
+ <body>
84
+ <div class="progress-container">
85
+ <h1>Task Progress</h1>
86
+ <div class="step-info">Step {step} of {total}</div>
87
+ <div class="progress-bar">
88
+ <div class="progress-fill">{percentage}%</div>
89
+ </div>
90
+ <p>{message}</p>
91
+ </div>
92
+ </body>
93
+ </html>
94
+ """
95
+
96
+
97
+ def create_chart_html(data: Dict[str, int]) -> str:
98
+ """Create a simple bar chart HTML."""
99
+ max_value = max(data.values()) if data else 1
100
+ bars = ""
101
+ for label, value in data.items():
102
+ percentage = int((value / max_value) * 100)
103
+ bars += f"""
104
+ <div class="bar-container">
105
+ <div class="bar-label">{label}</div>
106
+ <div class="bar-wrapper">
107
+ <div class="bar-fill" style="width: {percentage}%">
108
+ <span class="bar-value">{value}</span>
109
+ </div>
110
+ </div>
111
+ </div>
112
+ """
113
+
114
+ return f"""
115
+ <!DOCTYPE html>
116
+ <html>
117
+ <head>
118
+ <style>
119
+ body {{
120
+ font-family: Arial, sans-serif;
121
+ padding: 20px;
122
+ background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
123
+ }}
124
+ .chart-container {{
125
+ background: white;
126
+ border-radius: 10px;
127
+ padding: 20px;
128
+ box-shadow: 0 4px 6px rgba(0,0,0,0.1);
129
+ }}
130
+ h2 {{
131
+ color: #333;
132
+ margin-top: 0;
133
+ }}
134
+ .bar-container {{
135
+ margin: 15px 0;
136
+ }}
137
+ .bar-label {{
138
+ font-weight: bold;
139
+ margin-bottom: 5px;
140
+ color: #555;
141
+ }}
142
+ .bar-wrapper {{
143
+ background: #e0e0e0;
144
+ border-radius: 5px;
145
+ overflow: hidden;
146
+ height: 30px;
147
+ }}
148
+ .bar-fill {{
149
+ background: linear-gradient(90deg, #667eea, #764ba2);
150
+ height: 100%;
151
+ display: flex;
152
+ align-items: center;
153
+ justify-content: flex-end;
154
+ padding-right: 10px;
155
+ transition: width 0.5s ease;
156
+ }}
157
+ .bar-value {{
158
+ color: white;
159
+ font-weight: bold;
160
+ }}
161
+ </style>
162
+ </head>
163
+ <body>
164
+ <div class="chart-container">
165
+ <h2>Processing Results</h2>
166
+ {bars}
167
+ </div>
168
+ </body>
169
+ </html>
170
+ """
171
+
172
+
173
+ @mcp.tool
174
+ async def task_with_canvas_updates(
175
+ task_name: str = "demo",
176
+ steps: int = 5,
177
+ interval_seconds: int = 2,
178
+ ctx: Context | None = None,
179
+ ) -> Dict[str, Any]:
180
+ """
181
+ Execute a long-running task with visual progress updates in the canvas.
182
+
183
+ This tool demonstrates how MCP servers can send canvas updates during
184
+ execution, allowing users to see real-time visual progress indicators.
185
+
186
+ Args:
187
+ task_name: Name of the task to execute
188
+ steps: Number of steps to process (default: 5)
189
+ interval_seconds: Delay between steps (default: 2)
190
+ ctx: MCP context for progress reporting
191
+
192
+ Returns:
193
+ Task completion summary with final results
194
+ """
195
+ total = max(1, int(steps))
196
+ interval = max(1, int(interval_seconds))
197
+
198
+ # Initial progress
199
+ if ctx:
200
+ await ctx.report_progress(
201
+ progress=0,
202
+ total=total,
203
+ message=f"Starting {task_name}..."
204
+ )
205
+
206
+ # Process each step and send visual updates as artifacts
207
+ for step in range(1, total + 1):
208
+ await asyncio.sleep(interval)
209
+
210
+ # Create progress visualization HTML
211
+ html_content = create_progress_html(step, total, f"Processing {task_name}: Step {step}")
212
+
213
+ # Send progress HTML as an artifact so it uses the HTML viewer
214
+ if ctx:
215
+ artifact_html = base64.b64encode(html_content.encode("utf-8")).decode("utf-8")
216
+ update_payload = {
217
+ "type": "artifacts",
218
+ "artifacts": [
219
+ {
220
+ "name": f"progress_step_{step}.html",
221
+ "b64": artifact_html,
222
+ "mime": "text/html",
223
+ "size": len(html_content),
224
+ "description": f"Progress for {task_name} step {step}/{total}",
225
+ "viewer": "html",
226
+ }
227
+ ],
228
+ "display": {
229
+ "open_canvas": True,
230
+ "primary_file": f"progress_step_{step}.html",
231
+ "mode": "replace",
232
+ },
233
+ "progress_message": f"{task_name}: Step {step}/{total}",
234
+ }
235
+ await ctx.report_progress(
236
+ progress=step,
237
+ total=total,
238
+ message=f"MCP_UPDATE:{json.dumps(update_payload)}",
239
+ )
240
+
241
+ # Final result with chart
242
+ result_data = {
243
+ "Items Processed": total * 10,
244
+ "Errors Found": 2,
245
+ "Warnings": 5,
246
+ "Success Rate": 95
247
+ }
248
+
249
+ chart_html = create_chart_html(result_data)
250
+
251
+ return {
252
+ "results": {
253
+ "task": task_name,
254
+ "status": "completed",
255
+ "steps_completed": total,
256
+ "summary": result_data
257
+ },
258
+ "artifacts": [
259
+ {
260
+ "name": "final_results.html",
261
+ "b64": base64.b64encode(chart_html.encode('utf-8')).decode('utf-8'),
262
+ "mime": "text/html",
263
+ "size": len(chart_html),
264
+ "description": "Final processing results chart",
265
+ "viewer": "html"
266
+ }
267
+ ],
268
+ "display": {
269
+ "open_canvas": True,
270
+ "primary_file": "final_results.html",
271
+ "mode": "replace",
272
+ "viewer_hint": "html"
273
+ }
274
+ }
275
+
276
+
277
+ @mcp.tool
278
+ async def task_with_system_messages(
279
+ task_name: str = "analysis",
280
+ stages: int = 4,
281
+ interval_seconds: int = 2,
282
+ ctx: Context | None = None,
283
+ ) -> Dict[str, Any]:
284
+ """
285
+ Execute a task with rich system messages displayed in chat history.
286
+
287
+ This tool demonstrates how MCP servers can send rich system messages
288
+ that appear as new items in the chat history during tool execution.
289
+
290
+ Args:
291
+ task_name: Name of the analysis task
292
+ stages: Number of stages to process (default: 4)
293
+ interval_seconds: Delay between stages (default: 2)
294
+ ctx: MCP context for progress reporting
295
+
296
+ Returns:
297
+ Analysis completion summary
298
+ """
299
+ stage_names = [
300
+ "Data Collection",
301
+ "Data Validation",
302
+ "Analysis",
303
+ "Report Generation"
304
+ ][:stages]
305
+
306
+ total = len(stage_names)
307
+
308
+ # Initial progress
309
+ if ctx:
310
+ await ctx.report_progress(
311
+ progress=0,
312
+ total=total,
313
+ message=f"Starting {task_name}..."
314
+ )
315
+
316
+ # Process each stage and send system messages
317
+ for i, stage in enumerate(stage_names, 1):
318
+ await asyncio.sleep(interval_seconds)
319
+
320
+ # Send system message
321
+ if ctx:
322
+ update_payload = {
323
+ "type": "system_message",
324
+ "message": f"**{stage}** - Stage {i}/{total} completed successfully",
325
+ "subtype": "success",
326
+ "progress_message": f"{task_name}: {stage}"
327
+ }
328
+ await ctx.report_progress(
329
+ progress=i,
330
+ total=total,
331
+ message=f"MCP_UPDATE:{json.dumps(update_payload)}"
332
+ )
333
+
334
+ return {
335
+ "results": {
336
+ "task": task_name,
337
+ "status": "completed",
338
+ "stages_completed": total,
339
+ "completion_message": f"All {total} stages completed successfully"
340
+ }
341
+ }
342
+
343
+
344
+ @mcp.tool
345
+ async def task_with_artifacts(
346
+ task_name: str = "data_processing",
347
+ files_to_generate: int = 3,
348
+ interval_seconds: int = 2,
349
+ ctx: Context | None = None,
350
+ ) -> Dict[str, Any]:
351
+ """
352
+ Execute a task that generates and displays artifacts progressively.
353
+
354
+ This tool demonstrates how MCP servers can send file artifacts during
355
+ execution, allowing users to see intermediate results as they're generated.
356
+
357
+ Args:
358
+ task_name: Name of the processing task
359
+ files_to_generate: Number of intermediate files to create (default: 3)
360
+ interval_seconds: Delay between file generation (default: 2)
361
+ ctx: MCP context for progress reporting
362
+
363
+ Returns:
364
+ Processing completion summary
365
+ """
366
+ total = max(1, int(files_to_generate))
367
+ interval = max(1, int(interval_seconds))
368
+
369
+ # Initial progress
370
+ if ctx:
371
+ await ctx.report_progress(
372
+ progress=0,
373
+ total=total,
374
+ message=f"Starting {task_name}..."
375
+ )
376
+
377
+ # Generate intermediate files
378
+ for file_num in range(1, total + 1):
379
+ await asyncio.sleep(interval)
380
+
381
+ # Create intermediate result HTML
382
+ intermediate_html = f"""
383
+ <!DOCTYPE html>
384
+ <html>
385
+ <head>
386
+ <style>
387
+ body {{
388
+ font-family: Arial, sans-serif;
389
+ padding: 20px;
390
+ background: linear-gradient(135deg, #89f7fe 0%, #66a6ff 100%);
391
+ }}
392
+ .result {{
393
+ background: white;
394
+ border-radius: 10px;
395
+ padding: 20px;
396
+ box-shadow: 0 4px 6px rgba(0,0,0,0.1);
397
+ }}
398
+ h2 {{ color: #333; margin-top: 0; }}
399
+ .data {{ color: #666; font-size: 18px; }}
400
+ </style>
401
+ </head>
402
+ <body>
403
+ <div class="result">
404
+ <h2>Intermediate Result {file_num}</h2>
405
+ <p class="data">Generated at step {file_num} of {total}</p>
406
+ <p class="data">Processing status: In Progress</p>
407
+ </div>
408
+ </body>
409
+ </html>
410
+ """
411
+
412
+ # Send artifact via structured progress message
413
+ if ctx:
414
+ artifact_data = {
415
+ "type": "artifacts",
416
+ "artifacts": [
417
+ {
418
+ "name": f"intermediate_result_{file_num}.html",
419
+ "b64": base64.b64encode(intermediate_html.encode('utf-8')).decode('utf-8'),
420
+ "mime": "text/html",
421
+ "size": len(intermediate_html),
422
+ "description": f"Intermediate result {file_num}",
423
+ "viewer": "html"
424
+ }
425
+ ],
426
+ "display": {
427
+ "open_canvas": True,
428
+ "primary_file": f"intermediate_result_{file_num}.html",
429
+ "mode": "replace"
430
+ },
431
+ "progress_message": f"Generated file {file_num}/{total}"
432
+ }
433
+ await ctx.report_progress(
434
+ progress=file_num,
435
+ total=total,
436
+ message=f"MCP_UPDATE:{json.dumps(artifact_data)}"
437
+ )
438
+
439
+ # Final result
440
+ final_html = """
441
+ <!DOCTYPE html>
442
+ <html>
443
+ <head>
444
+ <style>
445
+ body {
446
+ font-family: Arial, sans-serif;
447
+ padding: 20px;
448
+ background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%);
449
+ }
450
+ .final-result {
451
+ background: white;
452
+ border-radius: 10px;
453
+ padding: 30px;
454
+ box-shadow: 0 4px 6px rgba(0,0,0,0.1);
455
+ text-align: center;
456
+ }
457
+ h1 { color: #4CAF50; }
458
+ .success-icon { font-size: 64px; }
459
+ </style>
460
+ </head>
461
+ <body>
462
+ <div class="final-result">
463
+ <div class="success-icon">✓</div>
464
+ <h1>Processing Complete!</h1>
465
+ <p>All files have been generated successfully.</p>
466
+ </div>
467
+ </body>
468
+ </html>
469
+ """
470
+
471
+ return {
472
+ "results": {
473
+ "task": task_name,
474
+ "status": "completed",
475
+ "files_generated": total
476
+ },
477
+ "artifacts": [
478
+ {
479
+ "name": "final_result.html",
480
+ "b64": base64.b64encode(final_html.encode('utf-8')).decode('utf-8'),
481
+ "mime": "text/html",
482
+ "size": len(final_html),
483
+ "description": "Final processing result",
484
+ "viewer": "html"
485
+ }
486
+ ],
487
+ "display": {
488
+ "open_canvas": True,
489
+ "primary_file": "final_result.html",
490
+ "mode": "replace",
491
+ "viewer_hint": "html"
492
+ }
493
+ }
494
+
495
+
496
+ if __name__ == "__main__":
497
+ mcp.run()