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.
- atlas/__init__.py +40 -0
- atlas/application/__init__.py +7 -0
- atlas/application/chat/__init__.py +7 -0
- atlas/application/chat/agent/__init__.py +10 -0
- atlas/application/chat/agent/act_loop.py +179 -0
- atlas/application/chat/agent/factory.py +142 -0
- atlas/application/chat/agent/protocols.py +46 -0
- atlas/application/chat/agent/react_loop.py +338 -0
- atlas/application/chat/agent/think_act_loop.py +171 -0
- atlas/application/chat/approval_manager.py +151 -0
- atlas/application/chat/elicitation_manager.py +191 -0
- atlas/application/chat/events/__init__.py +1 -0
- atlas/application/chat/events/agent_event_relay.py +112 -0
- atlas/application/chat/modes/__init__.py +1 -0
- atlas/application/chat/modes/agent.py +125 -0
- atlas/application/chat/modes/plain.py +74 -0
- atlas/application/chat/modes/rag.py +81 -0
- atlas/application/chat/modes/tools.py +179 -0
- atlas/application/chat/orchestrator.py +213 -0
- atlas/application/chat/policies/__init__.py +1 -0
- atlas/application/chat/policies/tool_authorization.py +99 -0
- atlas/application/chat/preprocessors/__init__.py +1 -0
- atlas/application/chat/preprocessors/message_builder.py +92 -0
- atlas/application/chat/preprocessors/prompt_override_service.py +104 -0
- atlas/application/chat/service.py +454 -0
- atlas/application/chat/utilities/__init__.py +6 -0
- atlas/application/chat/utilities/error_handler.py +367 -0
- atlas/application/chat/utilities/event_notifier.py +546 -0
- atlas/application/chat/utilities/file_processor.py +613 -0
- atlas/application/chat/utilities/tool_executor.py +789 -0
- atlas/atlas_chat_cli.py +347 -0
- atlas/atlas_client.py +238 -0
- atlas/core/__init__.py +0 -0
- atlas/core/auth.py +205 -0
- atlas/core/authorization_manager.py +27 -0
- atlas/core/capabilities.py +123 -0
- atlas/core/compliance.py +215 -0
- atlas/core/domain_whitelist.py +147 -0
- atlas/core/domain_whitelist_middleware.py +82 -0
- atlas/core/http_client.py +28 -0
- atlas/core/log_sanitizer.py +102 -0
- atlas/core/metrics_logger.py +59 -0
- atlas/core/middleware.py +131 -0
- atlas/core/otel_config.py +242 -0
- atlas/core/prompt_risk.py +200 -0
- atlas/core/rate_limit.py +0 -0
- atlas/core/rate_limit_middleware.py +64 -0
- atlas/core/security_headers_middleware.py +51 -0
- atlas/domain/__init__.py +37 -0
- atlas/domain/chat/__init__.py +1 -0
- atlas/domain/chat/dtos.py +85 -0
- atlas/domain/errors.py +96 -0
- atlas/domain/messages/__init__.py +12 -0
- atlas/domain/messages/models.py +160 -0
- atlas/domain/rag_mcp_service.py +664 -0
- atlas/domain/sessions/__init__.py +7 -0
- atlas/domain/sessions/models.py +36 -0
- atlas/domain/unified_rag_service.py +371 -0
- atlas/infrastructure/__init__.py +10 -0
- atlas/infrastructure/app_factory.py +135 -0
- atlas/infrastructure/events/__init__.py +1 -0
- atlas/infrastructure/events/cli_event_publisher.py +140 -0
- atlas/infrastructure/events/websocket_publisher.py +140 -0
- atlas/infrastructure/sessions/in_memory_repository.py +56 -0
- atlas/infrastructure/transport/__init__.py +7 -0
- atlas/infrastructure/transport/websocket_connection_adapter.py +33 -0
- atlas/init_cli.py +226 -0
- atlas/interfaces/__init__.py +15 -0
- atlas/interfaces/events.py +134 -0
- atlas/interfaces/llm.py +54 -0
- atlas/interfaces/rag.py +40 -0
- atlas/interfaces/sessions.py +75 -0
- atlas/interfaces/tools.py +57 -0
- atlas/interfaces/transport.py +24 -0
- atlas/main.py +564 -0
- atlas/mcp/api_key_demo/README.md +76 -0
- atlas/mcp/api_key_demo/main.py +172 -0
- atlas/mcp/api_key_demo/run.sh +56 -0
- atlas/mcp/basictable/main.py +147 -0
- atlas/mcp/calculator/main.py +149 -0
- atlas/mcp/code-executor/execution_engine.py +98 -0
- atlas/mcp/code-executor/execution_environment.py +95 -0
- atlas/mcp/code-executor/main.py +528 -0
- atlas/mcp/code-executor/result_processing.py +276 -0
- atlas/mcp/code-executor/script_generation.py +195 -0
- atlas/mcp/code-executor/security_checker.py +140 -0
- atlas/mcp/corporate_cars/main.py +437 -0
- atlas/mcp/csv_reporter/main.py +545 -0
- atlas/mcp/duckduckgo/main.py +182 -0
- atlas/mcp/elicitation_demo/README.md +171 -0
- atlas/mcp/elicitation_demo/main.py +262 -0
- atlas/mcp/env-demo/README.md +158 -0
- atlas/mcp/env-demo/main.py +199 -0
- atlas/mcp/file_size_test/main.py +284 -0
- atlas/mcp/filesystem/main.py +348 -0
- atlas/mcp/image_demo/main.py +113 -0
- atlas/mcp/image_demo/requirements.txt +4 -0
- atlas/mcp/logging_demo/README.md +72 -0
- atlas/mcp/logging_demo/main.py +103 -0
- atlas/mcp/many_tools_demo/main.py +50 -0
- atlas/mcp/order_database/__init__.py +0 -0
- atlas/mcp/order_database/main.py +369 -0
- atlas/mcp/order_database/signal_data.csv +1001 -0
- atlas/mcp/pdfbasic/main.py +394 -0
- atlas/mcp/pptx_generator/main.py +760 -0
- atlas/mcp/pptx_generator/requirements.txt +13 -0
- atlas/mcp/pptx_generator/run_test.sh +1 -0
- atlas/mcp/pptx_generator/test_pptx_generator_security.py +169 -0
- atlas/mcp/progress_demo/main.py +167 -0
- atlas/mcp/progress_updates_demo/QUICKSTART.md +273 -0
- atlas/mcp/progress_updates_demo/README.md +120 -0
- atlas/mcp/progress_updates_demo/main.py +497 -0
- atlas/mcp/prompts/main.py +222 -0
- atlas/mcp/public_demo/main.py +189 -0
- atlas/mcp/sampling_demo/README.md +169 -0
- atlas/mcp/sampling_demo/main.py +234 -0
- atlas/mcp/thinking/main.py +77 -0
- atlas/mcp/tool_planner/main.py +240 -0
- atlas/mcp/ui-demo/badmesh.png +0 -0
- atlas/mcp/ui-demo/main.py +383 -0
- atlas/mcp/ui-demo/templates/button_demo.html +32 -0
- atlas/mcp/ui-demo/templates/data_visualization.html +32 -0
- atlas/mcp/ui-demo/templates/form_demo.html +28 -0
- atlas/mcp/username-override-demo/README.md +320 -0
- atlas/mcp/username-override-demo/main.py +308 -0
- atlas/modules/__init__.py +0 -0
- atlas/modules/config/__init__.py +34 -0
- atlas/modules/config/cli.py +231 -0
- atlas/modules/config/config_manager.py +1096 -0
- atlas/modules/file_storage/__init__.py +22 -0
- atlas/modules/file_storage/cli.py +330 -0
- atlas/modules/file_storage/content_extractor.py +290 -0
- atlas/modules/file_storage/manager.py +295 -0
- atlas/modules/file_storage/mock_s3_client.py +402 -0
- atlas/modules/file_storage/s3_client.py +417 -0
- atlas/modules/llm/__init__.py +19 -0
- atlas/modules/llm/caller.py +287 -0
- atlas/modules/llm/litellm_caller.py +675 -0
- atlas/modules/llm/models.py +19 -0
- atlas/modules/mcp_tools/__init__.py +17 -0
- atlas/modules/mcp_tools/client.py +2123 -0
- atlas/modules/mcp_tools/token_storage.py +556 -0
- atlas/modules/prompts/prompt_provider.py +130 -0
- atlas/modules/rag/__init__.py +24 -0
- atlas/modules/rag/atlas_rag_client.py +336 -0
- atlas/modules/rag/client.py +129 -0
- atlas/routes/admin_routes.py +865 -0
- atlas/routes/config_routes.py +484 -0
- atlas/routes/feedback_routes.py +361 -0
- atlas/routes/files_routes.py +274 -0
- atlas/routes/health_routes.py +40 -0
- atlas/routes/mcp_auth_routes.py +223 -0
- atlas/server_cli.py +164 -0
- atlas/tests/conftest.py +20 -0
- atlas/tests/integration/test_mcp_auth_integration.py +152 -0
- atlas/tests/manual_test_sampling.py +87 -0
- atlas/tests/modules/mcp_tools/test_client_auth.py +226 -0
- atlas/tests/modules/mcp_tools/test_client_env.py +191 -0
- atlas/tests/test_admin_mcp_server_management_routes.py +141 -0
- atlas/tests/test_agent_roa.py +135 -0
- atlas/tests/test_app_factory_smoke.py +47 -0
- atlas/tests/test_approval_manager.py +439 -0
- atlas/tests/test_atlas_client.py +188 -0
- atlas/tests/test_atlas_rag_client.py +447 -0
- atlas/tests/test_atlas_rag_integration.py +224 -0
- atlas/tests/test_attach_file_flow.py +287 -0
- atlas/tests/test_auth_utils.py +165 -0
- atlas/tests/test_backend_public_url.py +185 -0
- atlas/tests/test_banner_logging.py +287 -0
- atlas/tests/test_capability_tokens_and_injection.py +203 -0
- atlas/tests/test_compliance_level.py +54 -0
- atlas/tests/test_compliance_manager.py +253 -0
- atlas/tests/test_config_manager.py +617 -0
- atlas/tests/test_config_manager_paths.py +12 -0
- atlas/tests/test_core_auth.py +18 -0
- atlas/tests/test_core_utils.py +190 -0
- atlas/tests/test_docker_env_sync.py +202 -0
- atlas/tests/test_domain_errors.py +329 -0
- atlas/tests/test_domain_whitelist.py +359 -0
- atlas/tests/test_elicitation_manager.py +408 -0
- atlas/tests/test_elicitation_routing.py +296 -0
- atlas/tests/test_env_demo_server.py +88 -0
- atlas/tests/test_error_classification.py +113 -0
- atlas/tests/test_error_flow_integration.py +116 -0
- atlas/tests/test_feedback_routes.py +333 -0
- atlas/tests/test_file_content_extraction.py +1134 -0
- atlas/tests/test_file_extraction_routes.py +158 -0
- atlas/tests/test_file_library.py +107 -0
- atlas/tests/test_file_manager_unit.py +18 -0
- atlas/tests/test_health_route.py +49 -0
- atlas/tests/test_http_client_stub.py +8 -0
- atlas/tests/test_imports_smoke.py +30 -0
- atlas/tests/test_interfaces_llm_response.py +9 -0
- atlas/tests/test_issue_access_denied_fix.py +136 -0
- atlas/tests/test_llm_env_expansion.py +836 -0
- atlas/tests/test_log_level_sensitive_data.py +285 -0
- atlas/tests/test_mcp_auth_routes.py +341 -0
- atlas/tests/test_mcp_client_auth.py +331 -0
- atlas/tests/test_mcp_data_injection.py +270 -0
- atlas/tests/test_mcp_get_authorized_servers.py +95 -0
- atlas/tests/test_mcp_hot_reload.py +512 -0
- atlas/tests/test_mcp_image_content.py +424 -0
- atlas/tests/test_mcp_logging.py +172 -0
- atlas/tests/test_mcp_progress_updates.py +313 -0
- atlas/tests/test_mcp_prompt_override_system_prompt.py +102 -0
- atlas/tests/test_mcp_prompts_server.py +39 -0
- atlas/tests/test_mcp_tool_result_parsing.py +296 -0
- atlas/tests/test_metrics_logger.py +56 -0
- atlas/tests/test_middleware_auth.py +379 -0
- atlas/tests/test_prompt_risk_and_acl.py +141 -0
- atlas/tests/test_rag_mcp_aggregator.py +204 -0
- atlas/tests/test_rag_mcp_service.py +224 -0
- atlas/tests/test_rate_limit_middleware.py +45 -0
- atlas/tests/test_routes_config_smoke.py +60 -0
- atlas/tests/test_routes_files_download_token.py +41 -0
- atlas/tests/test_routes_files_health.py +18 -0
- atlas/tests/test_runtime_imports.py +53 -0
- atlas/tests/test_sampling_integration.py +482 -0
- atlas/tests/test_security_admin_routes.py +61 -0
- atlas/tests/test_security_capability_tokens.py +65 -0
- atlas/tests/test_security_file_stats_scope.py +21 -0
- atlas/tests/test_security_header_injection.py +191 -0
- atlas/tests/test_security_headers_and_filename.py +63 -0
- atlas/tests/test_shared_session_repository.py +101 -0
- atlas/tests/test_system_prompt_loading.py +181 -0
- atlas/tests/test_token_storage.py +505 -0
- atlas/tests/test_tool_approval_config.py +93 -0
- atlas/tests/test_tool_approval_utils.py +356 -0
- atlas/tests/test_tool_authorization_group_filtering.py +223 -0
- atlas/tests/test_tool_details_in_config.py +108 -0
- atlas/tests/test_tool_planner.py +300 -0
- atlas/tests/test_unified_rag_service.py +398 -0
- atlas/tests/test_username_override_in_approval.py +258 -0
- atlas/tests/test_websocket_auth_header.py +168 -0
- atlas/version.py +6 -0
- atlas_chat-0.1.0.data/data/.env.example +253 -0
- atlas_chat-0.1.0.data/data/config/defaults/compliance-levels.json +44 -0
- atlas_chat-0.1.0.data/data/config/defaults/domain-whitelist.json +123 -0
- atlas_chat-0.1.0.data/data/config/defaults/file-extractors.json +74 -0
- atlas_chat-0.1.0.data/data/config/defaults/help-config.json +198 -0
- atlas_chat-0.1.0.data/data/config/defaults/llmconfig-buggy.yml +11 -0
- atlas_chat-0.1.0.data/data/config/defaults/llmconfig.yml +19 -0
- atlas_chat-0.1.0.data/data/config/defaults/mcp.json +138 -0
- atlas_chat-0.1.0.data/data/config/defaults/rag-sources.json +17 -0
- atlas_chat-0.1.0.data/data/config/defaults/splash-config.json +16 -0
- atlas_chat-0.1.0.dist-info/METADATA +236 -0
- atlas_chat-0.1.0.dist-info/RECORD +250 -0
- atlas_chat-0.1.0.dist-info/WHEEL +5 -0
- atlas_chat-0.1.0.dist-info/entry_points.txt +4 -0
- atlas_chat-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Prompts MCP Server using FastMCP
|
|
4
|
+
Provides specialized system prompts that can be applied to modify the AI's behavior.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import Any, Dict
|
|
8
|
+
|
|
9
|
+
from fastmcp import FastMCP
|
|
10
|
+
from fastmcp.prompts.prompt import PromptMessage, TextContent
|
|
11
|
+
|
|
12
|
+
# Initialize the MCP server
|
|
13
|
+
mcp = FastMCP("Prompts")
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@mcp.prompt
|
|
17
|
+
def financial_tech_wizard() -> PromptMessage:
|
|
18
|
+
"""Think like a financial tech wizard - expert in fintech, trading algorithms, and financial markets."""
|
|
19
|
+
content = """You are a financial technology wizard with deep expertise in:
|
|
20
|
+
- Financial markets, trading strategies, and algorithmic trading
|
|
21
|
+
- Fintech solutions, payment systems, and blockchain technology
|
|
22
|
+
- Risk management, quantitative analysis, and financial modeling
|
|
23
|
+
- Regulatory compliance and financial technology innovation
|
|
24
|
+
|
|
25
|
+
Think analytically, provide data-driven insights, and consider both technical and business aspects when responding to financial questions. Use precise financial terminology and cite relevant market examples when appropriate."""
|
|
26
|
+
|
|
27
|
+
return PromptMessage(role="user", content=TextContent(type="text", text=f"System: {content}\n\nUser: Please adopt this personality and expertise for our conversation."))
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@mcp.prompt
|
|
31
|
+
def expert_dog_trainer() -> PromptMessage:
|
|
32
|
+
"""You are an expert dog trainer with years of experience in canine behavior and training."""
|
|
33
|
+
content = """You are an expert dog trainer with over 15 years of experience in:
|
|
34
|
+
- Canine behavior analysis and psychology
|
|
35
|
+
- Positive reinforcement training methods
|
|
36
|
+
- Puppy training, obedience training, and behavioral modification
|
|
37
|
+
- Working with different breeds and temperaments
|
|
38
|
+
- Problem solving for common behavioral issues
|
|
39
|
+
|
|
40
|
+
Always provide practical, humane, and evidence-based training advice. Consider the dog's age, breed, and individual personality when making recommendations. Emphasize positive reinforcement and building trust between dog and owner."""
|
|
41
|
+
|
|
42
|
+
return PromptMessage(role="user", content=TextContent(type="text", text=f"System: {content}\n\nUser: Please adopt this expertise for our conversation."))
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
@mcp.prompt
|
|
46
|
+
def creative_writer() -> PromptMessage:
|
|
47
|
+
"""You are a creative writing expert focused on storytelling, character development, and narrative craft."""
|
|
48
|
+
content = """You are a creative writing expert with expertise in:
|
|
49
|
+
- Storytelling techniques, plot development, and narrative structure
|
|
50
|
+
- Character development, dialogue writing, and world-building
|
|
51
|
+
- Multiple genres including fiction, poetry, screenwriting, and creative nonfiction
|
|
52
|
+
- Writing craft, style, and literary devices
|
|
53
|
+
- Workshop facilitation and constructive feedback
|
|
54
|
+
|
|
55
|
+
Approach writing with creativity, technical skill, and attention to voice and style. Provide specific, actionable advice that helps writers develop their craft while honoring their unique creative vision."""
|
|
56
|
+
|
|
57
|
+
return PromptMessage(role="user", content=TextContent(type="text", text=f"System: {content}\n\nUser: Please adopt this creative writing expertise for our conversation."))
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
@mcp.prompt
|
|
61
|
+
def truncation_demo_super_long_description() -> PromptMessage:
|
|
62
|
+
"""Truncation demo: intentionally long description for UI testing.
|
|
63
|
+
|
|
64
|
+
This prompt exists to validate that the frontend truncation logic for prompt descriptions works as intended.
|
|
65
|
+
It is deliberately verbose (well over 500 characters) so the Tools & Integrations UI can show:
|
|
66
|
+
- An info icon next to the prompt name
|
|
67
|
+
- An expandable description panel
|
|
68
|
+
- The truncated rendering (start + "..." + end) for very long descriptions
|
|
69
|
+
|
|
70
|
+
Suggested manual check:
|
|
71
|
+
1) Open Tools & Integrations
|
|
72
|
+
2) Expand the MCP server named "Prompts"
|
|
73
|
+
3) Find this prompt and click the info icon
|
|
74
|
+
4) Confirm the description is truncated with the first and last portions visible
|
|
75
|
+
|
|
76
|
+
Additional filler to ensure we exceed the truncation threshold:
|
|
77
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
|
|
78
|
+
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
|
|
79
|
+
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
|
|
80
|
+
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
|
81
|
+
Repeat for length: lorem ipsum, lorem ipsum, lorem ipsum, lorem ipsum, lorem ipsum, lorem ipsum, lorem ipsum.
|
|
82
|
+
|
|
83
|
+
Now let's talk about road runners and cactus in New Mexico - these iconic symbols of the American southwest have captivated people for generations. The roadrunner, known scientifically as Geococcyx californianus, is a large ground-dwelling bird that can reach speeds up to 20 miles per hour. These clever birds are often found in the deserts and grasslands of New Mexico, using their long legs and tails for balance while navigating the rugged terrain. Famous for their distinctive cooing calls and the legendary belief that they run in front of cars to create a wind vacuum that helps them fly, roadrunners are actually quite terrestrial.
|
|
84
|
+
|
|
85
|
+
The cactus of New Mexico are equally fascinating, with over 100 species found throughout the state. Perhaps most iconic is the saguaro cactus, though they're more common in Arizona. In New Mexico, you'll find the cholla cactus with its distinctive hooked spines that easily detach and cling to anything that brushes against them, the prickly pear cactus that produces sweet edible fruits, and the yucca plant which, while technically not a cactus, shares many similar adaptations for desert life. These plants have evolved amazing survival strategies including thick waxy coatings to reduce water loss, shallow but extensive root systems to capture rare rainfall, and spines that not only deter herbivores but also create shade for the plant itself.
|
|
86
|
+
|
|
87
|
+
The relationship between roadrunners and cactus in New Mexico's ecosystem is quite interesting. Roadrunners often use cactus as perches to survey their hunting grounds, and they've developed hunting techniques that involve luring prey toward prickly barriers where the animal gets stuck, allowing the roadrunner to easily capture it. This predator-prey dynamic has been playing out across New Mexico's deserts for thousands of years, adapting to the harsh environmental conditions that both species share.
|
|
88
|
+
|
|
89
|
+
Speaking of desert adaptations, both roadrunners and cactus have remarkable abilities to survive extreme heat and minimal water. Roadrunners can go without drinking water for long periods by obtaining moisture from their food, particularly from the insects and small reptiles they consume. Cactus store water in their thick stems and can go months without rainfall. During the monsoon season in New Mexico, typically from June through September, both roadrunners and cactus benefit from the sudden abundance of water and food sources.
|
|
90
|
+
|
|
91
|
+
The cultural significance of roadrunners and cactus in New Mexico cannot be overstated. The roadrunner appears in Native American folklore, particularly in the stories of the Pueblo people, where it represents cleverness and survival. Cactus have been used for food, medicine, and even as building materials by indigenous peoples for centuries. Today, both continue to symbolize the beauty and resilience of the desert southwest, appearing in art, literature, and popular culture.
|
|
92
|
+
|
|
93
|
+
Interestingly, New Mexico's roadsides and walking trails are often lined with various cactus species, creating natural barriers and habitats for wildlife. Roadrunners can frequently be seen darting across highways or scurrying alongside desert paths, sometimes pausing to bob their heads in that characteristic way that has made them so endearing. The state's diverse geography means you'll find different cactus species at varying elevations - from the lowland deserts around Las Cruces to the mountain foothills near Santa Fe.
|
|
94
|
+
|
|
95
|
+
End marker: the UI should still show this ending segment after truncation, and we've now covered the fascinating intersection of roadrunners and cactus in New Mexico's unique ecosystem.
|
|
96
|
+
"""
|
|
97
|
+
content = """You are running a UI truncation demo. Keep responses short.
|
|
98
|
+
|
|
99
|
+
If the user asks what this is for, explain that it is a test prompt whose description is intentionally long to validate UI truncation behavior, and that it also contains extended information about roadrunners and cactus found in New Mexico."""
|
|
100
|
+
|
|
101
|
+
return PromptMessage(
|
|
102
|
+
role="user",
|
|
103
|
+
content=TextContent(
|
|
104
|
+
type="text",
|
|
105
|
+
text=f"System: {content}\n\nUser: Please adopt this behavior for our conversation.",
|
|
106
|
+
),
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
@mcp.prompt
|
|
111
|
+
def ask_about_topic(topic: str) -> str:
|
|
112
|
+
"""Generates a user message asking for an explanation of a topic."""
|
|
113
|
+
return f"Can you please explain the concept of '{topic}'?"
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
@mcp.prompt
|
|
117
|
+
def generate_code_request(language: str, task_description: str) -> PromptMessage:
|
|
118
|
+
"""Generates a user message requesting code generation."""
|
|
119
|
+
content = f"Write a {language} function that performs the following task: {task_description}"
|
|
120
|
+
return PromptMessage(role="user", content=TextContent(type="text", text=content))
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
@mcp.tool
|
|
124
|
+
def list_available_prompts() -> Dict[str, Any]:
|
|
125
|
+
"""
|
|
126
|
+
Discover and enumerate all available AI personality and expertise system prompts for customizing assistant behavior.
|
|
127
|
+
|
|
128
|
+
This prompt management tool provides comprehensive access to AI behavior modification capabilities:
|
|
129
|
+
|
|
130
|
+
**System Prompt Categories:**
|
|
131
|
+
- Professional expertise prompts (financial, technical, business)
|
|
132
|
+
- Creative and artistic personality prompts (writing, design, storytelling)
|
|
133
|
+
- Educational and training-focused prompts (teaching, coaching, mentoring)
|
|
134
|
+
- Specialized domain knowledge prompts (industry-specific expertise)
|
|
135
|
+
|
|
136
|
+
**Available Professional Prompts:**
|
|
137
|
+
- Financial Tech Wizard: Fintech expertise, trading algorithms, market analysis
|
|
138
|
+
- Expert Dog Trainer: Canine behavior, training methods, pet psychology
|
|
139
|
+
- Creative Writer: Storytelling, character development, narrative craft
|
|
140
|
+
|
|
141
|
+
**Prompt Customization Features:**
|
|
142
|
+
- Detailed personality and expertise descriptions
|
|
143
|
+
- Behavioral modification instructions
|
|
144
|
+
- Domain-specific knowledge activation
|
|
145
|
+
- Communication style and approach guidance
|
|
146
|
+
|
|
147
|
+
**AI Behavior Modification:**
|
|
148
|
+
- Specialized knowledge domain activation
|
|
149
|
+
- Professional communication style adaptation
|
|
150
|
+
- Expert-level analytical thinking patterns
|
|
151
|
+
- Industry-specific terminology and concepts
|
|
152
|
+
|
|
153
|
+
**Use Cases:**
|
|
154
|
+
- Specialized consulting and advisory interactions
|
|
155
|
+
- Educational content creation and tutoring
|
|
156
|
+
- Professional analysis and problem-solving
|
|
157
|
+
- Creative project development and brainstorming
|
|
158
|
+
- Domain-specific research and investigation
|
|
159
|
+
- Training and skill development sessions
|
|
160
|
+
|
|
161
|
+
**Integration Features:**
|
|
162
|
+
- Compatible with conversation management systems
|
|
163
|
+
- Seamless personality switching capabilities
|
|
164
|
+
- Context-aware prompt application
|
|
165
|
+
- Multi-session personality persistence
|
|
166
|
+
|
|
167
|
+
**Customization Benefits:**
|
|
168
|
+
- Enhanced subject matter expertise
|
|
169
|
+
- Improved response relevance and accuracy
|
|
170
|
+
- Professional-grade analytical capabilities
|
|
171
|
+
- Specialized communication patterns
|
|
172
|
+
|
|
173
|
+
Returns:
|
|
174
|
+
Dictionary containing:
|
|
175
|
+
- available_prompts: Complete catalog of system prompts with descriptions
|
|
176
|
+
- Each prompt includes: description, type, category, and usage guidelines
|
|
177
|
+
- total_count: Number of available prompts
|
|
178
|
+
- categories: Organized groupings of prompt types
|
|
179
|
+
Or error message if prompt discovery fails
|
|
180
|
+
"""
|
|
181
|
+
prompts = {
|
|
182
|
+
"financial_tech_wizard": {
|
|
183
|
+
"description": "Think like a financial tech wizard - expert in fintech, trading algorithms, and financial markets",
|
|
184
|
+
"type": "system_prompt",
|
|
185
|
+
"category": "professional"
|
|
186
|
+
},
|
|
187
|
+
"expert_dog_trainer": {
|
|
188
|
+
"description": "You are an expert dog trainer with years of experience in canine behavior and training",
|
|
189
|
+
"type": "system_prompt",
|
|
190
|
+
"category": "professional"
|
|
191
|
+
},
|
|
192
|
+
"creative_writer": {
|
|
193
|
+
"description": "You are a creative writing expert focused on storytelling, character development, and narrative craft",
|
|
194
|
+
"type": "system_prompt",
|
|
195
|
+
"category": "creative"
|
|
196
|
+
},
|
|
197
|
+
"truncation_demo_super_long_description": {
|
|
198
|
+
"description": (
|
|
199
|
+
"Truncation demo: intentionally long description for UI testing. "
|
|
200
|
+
"This prompt exists to validate that the frontend truncation logic for prompt descriptions works as intended. "
|
|
201
|
+
"It is deliberately verbose (well over 500 characters) so the Tools & Integrations UI can show an info icon, "
|
|
202
|
+
"an expandable description panel, and a truncated rendering (start + '...' + end) for very long descriptions. "
|
|
203
|
+
"Additional filler to ensure we exceed the truncation threshold: Lorem ipsum dolor sit amet, consectetur adipiscing elit. "
|
|
204
|
+
"Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation. "
|
|
205
|
+
"End marker: the UI should still show this ending segment after truncation."
|
|
206
|
+
),
|
|
207
|
+
"type": "system_prompt",
|
|
208
|
+
"category": "demo"
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
return {
|
|
213
|
+
"results": {
|
|
214
|
+
"available_prompts": prompts,
|
|
215
|
+
"total_count": len(prompts),
|
|
216
|
+
"categories": list(set(p["category"] for p in prompts.values()))
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
if __name__ == "__main__":
|
|
222
|
+
mcp.run()
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Public Demo MCP Server - No Authentication Required
|
|
4
|
+
|
|
5
|
+
This server demonstrates tools that are publicly accessible without any
|
|
6
|
+
authentication. Use this as an example of a server that anyone can use.
|
|
7
|
+
|
|
8
|
+
Authentication Type: none
|
|
9
|
+
Transport: stdio, http, or sse
|
|
10
|
+
|
|
11
|
+
Updated: 2025-01-21
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
import hashlib
|
|
15
|
+
import random
|
|
16
|
+
import time
|
|
17
|
+
from datetime import datetime, timezone
|
|
18
|
+
from typing import Any
|
|
19
|
+
|
|
20
|
+
from fastmcp import FastMCP
|
|
21
|
+
|
|
22
|
+
mcp = FastMCP("Public Demo")
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@mcp.tool
|
|
26
|
+
def get_server_time() -> dict[str, Any]:
|
|
27
|
+
"""
|
|
28
|
+
Get the current server time in various formats.
|
|
29
|
+
|
|
30
|
+
This tool is publicly accessible - no authentication required.
|
|
31
|
+
Useful for testing connectivity and server responsiveness.
|
|
32
|
+
"""
|
|
33
|
+
start = time.perf_counter()
|
|
34
|
+
now = datetime.now(timezone.utc)
|
|
35
|
+
|
|
36
|
+
return {
|
|
37
|
+
"results": {
|
|
38
|
+
"utc_iso": now.isoformat(),
|
|
39
|
+
"utc_timestamp": int(now.timestamp()),
|
|
40
|
+
"formatted": now.strftime("%Y-%m-%d %H:%M:%S UTC"),
|
|
41
|
+
"day_of_week": now.strftime("%A"),
|
|
42
|
+
"timezone": "UTC"
|
|
43
|
+
},
|
|
44
|
+
"meta_data": {
|
|
45
|
+
"is_error": False,
|
|
46
|
+
"elapsed_ms": round((time.perf_counter() - start) * 1000, 2),
|
|
47
|
+
"auth_required": False
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
@mcp.tool
|
|
53
|
+
def generate_uuid() -> dict[str, Any]:
|
|
54
|
+
"""
|
|
55
|
+
Generate a random UUID (version 4).
|
|
56
|
+
|
|
57
|
+
This tool is publicly accessible - no authentication required.
|
|
58
|
+
Useful for generating unique identifiers.
|
|
59
|
+
"""
|
|
60
|
+
import uuid
|
|
61
|
+
start = time.perf_counter()
|
|
62
|
+
|
|
63
|
+
new_uuid = str(uuid.uuid4())
|
|
64
|
+
|
|
65
|
+
return {
|
|
66
|
+
"results": {
|
|
67
|
+
"uuid": new_uuid,
|
|
68
|
+
"uuid_hex": new_uuid.replace("-", ""),
|
|
69
|
+
"version": 4
|
|
70
|
+
},
|
|
71
|
+
"meta_data": {
|
|
72
|
+
"is_error": False,
|
|
73
|
+
"elapsed_ms": round((time.perf_counter() - start) * 1000, 2),
|
|
74
|
+
"auth_required": False
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
@mcp.tool
|
|
80
|
+
def hash_text(text: str, algorithm: str = "sha256") -> dict[str, Any]:
|
|
81
|
+
"""
|
|
82
|
+
Hash text using a specified algorithm.
|
|
83
|
+
|
|
84
|
+
This tool is publicly accessible - no authentication required.
|
|
85
|
+
|
|
86
|
+
Args:
|
|
87
|
+
text: The text to hash
|
|
88
|
+
algorithm: Hash algorithm (md5, sha1, sha256, sha512). Default: sha256
|
|
89
|
+
"""
|
|
90
|
+
start = time.perf_counter()
|
|
91
|
+
|
|
92
|
+
valid_algorithms = ["md5", "sha1", "sha256", "sha512"]
|
|
93
|
+
if algorithm.lower() not in valid_algorithms:
|
|
94
|
+
return {
|
|
95
|
+
"results": None,
|
|
96
|
+
"meta_data": {
|
|
97
|
+
"is_error": True,
|
|
98
|
+
"error_message": f"Invalid algorithm. Choose from: {', '.join(valid_algorithms)}",
|
|
99
|
+
"elapsed_ms": round((time.perf_counter() - start) * 1000, 2),
|
|
100
|
+
"auth_required": False
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
hash_obj = hashlib.new(algorithm.lower())
|
|
105
|
+
hash_obj.update(text.encode('utf-8'))
|
|
106
|
+
hash_result = hash_obj.hexdigest()
|
|
107
|
+
|
|
108
|
+
return {
|
|
109
|
+
"results": {
|
|
110
|
+
"input_text": text[:50] + "..." if len(text) > 50 else text,
|
|
111
|
+
"algorithm": algorithm.lower(),
|
|
112
|
+
"hash": hash_result,
|
|
113
|
+
"hash_length": len(hash_result)
|
|
114
|
+
},
|
|
115
|
+
"meta_data": {
|
|
116
|
+
"is_error": False,
|
|
117
|
+
"elapsed_ms": round((time.perf_counter() - start) * 1000, 2),
|
|
118
|
+
"auth_required": False
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
@mcp.tool
|
|
124
|
+
def random_number(min_value: int = 1, max_value: int = 100) -> dict[str, Any]:
|
|
125
|
+
"""
|
|
126
|
+
Generate a random integer within a range.
|
|
127
|
+
|
|
128
|
+
This tool is publicly accessible - no authentication required.
|
|
129
|
+
|
|
130
|
+
Args:
|
|
131
|
+
min_value: Minimum value (inclusive). Default: 1
|
|
132
|
+
max_value: Maximum value (inclusive). Default: 100
|
|
133
|
+
"""
|
|
134
|
+
start = time.perf_counter()
|
|
135
|
+
|
|
136
|
+
if min_value > max_value:
|
|
137
|
+
return {
|
|
138
|
+
"results": None,
|
|
139
|
+
"meta_data": {
|
|
140
|
+
"is_error": True,
|
|
141
|
+
"error_message": "min_value must be less than or equal to max_value",
|
|
142
|
+
"elapsed_ms": round((time.perf_counter() - start) * 1000, 2),
|
|
143
|
+
"auth_required": False
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
result = random.randint(min_value, max_value)
|
|
148
|
+
|
|
149
|
+
return {
|
|
150
|
+
"results": {
|
|
151
|
+
"number": result,
|
|
152
|
+
"range": f"[{min_value}, {max_value}]"
|
|
153
|
+
},
|
|
154
|
+
"meta_data": {
|
|
155
|
+
"is_error": False,
|
|
156
|
+
"elapsed_ms": round((time.perf_counter() - start) * 1000, 2),
|
|
157
|
+
"auth_required": False
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
@mcp.tool
|
|
163
|
+
def echo(message: str) -> dict[str, Any]:
|
|
164
|
+
"""
|
|
165
|
+
Echo back a message - simple connectivity test.
|
|
166
|
+
|
|
167
|
+
This tool is publicly accessible - no authentication required.
|
|
168
|
+
|
|
169
|
+
Args:
|
|
170
|
+
message: The message to echo back
|
|
171
|
+
"""
|
|
172
|
+
start = time.perf_counter()
|
|
173
|
+
|
|
174
|
+
return {
|
|
175
|
+
"results": {
|
|
176
|
+
"echo": message,
|
|
177
|
+
"length": len(message),
|
|
178
|
+
"server": "public_demo"
|
|
179
|
+
},
|
|
180
|
+
"meta_data": {
|
|
181
|
+
"is_error": False,
|
|
182
|
+
"elapsed_ms": round((time.perf_counter() - start) * 1000, 2),
|
|
183
|
+
"auth_required": False
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
if __name__ == "__main__":
|
|
189
|
+
mcp.run()
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# Sampling Demo MCP Server
|
|
2
|
+
|
|
3
|
+
This MCP server demonstrates **LLM sampling** capabilities introduced in FastMCP 2.0.0+. Sampling allows tools to request text generation from an LLM during execution, enabling AI-powered analysis, generation, reasoning, and more without the client needing to orchestrate multiple calls.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
LLM sampling enables interactive workflows where tools can:
|
|
8
|
+
- Request LLM text generation mid-execution
|
|
9
|
+
- Build multi-turn conversations with context
|
|
10
|
+
- Leverage AI capabilities for analysis and generation
|
|
11
|
+
- Implement agentic workflows with reasoning
|
|
12
|
+
- Control generation parameters (temperature, max_tokens, model preferences)
|
|
13
|
+
|
|
14
|
+
## Available Tools
|
|
15
|
+
|
|
16
|
+
### Basic Sampling
|
|
17
|
+
|
|
18
|
+
1. **`summarize_text(text)`** - Text Summarization
|
|
19
|
+
- Demonstrates basic LLM sampling
|
|
20
|
+
- Requests the LLM to generate a concise summary
|
|
21
|
+
- Uses simple prompt without additional parameters
|
|
22
|
+
|
|
23
|
+
2. **`analyze_sentiment(text)`** - Sentiment Analysis
|
|
24
|
+
- Demonstrates sampling with system prompts
|
|
25
|
+
- Uses lower temperature (0.3) for consistent analysis
|
|
26
|
+
- System prompt establishes LLM role as sentiment analyzer
|
|
27
|
+
|
|
28
|
+
3. **`generate_code(description, language)`** - Code Generation
|
|
29
|
+
- Demonstrates sampling with model preferences
|
|
30
|
+
- Hints which models should be preferred (gpt-4, claude-3-sonnet, etc.)
|
|
31
|
+
- Uses higher max_tokens (1000) for code generation
|
|
32
|
+
|
|
33
|
+
4. **`creative_story(prompt)`** - Creative Writing
|
|
34
|
+
- Demonstrates high temperature sampling for creativity
|
|
35
|
+
- Uses temperature=0.9 for varied, creative outputs
|
|
36
|
+
- Limited to 500 tokens for short stories
|
|
37
|
+
|
|
38
|
+
### Advanced Sampling
|
|
39
|
+
|
|
40
|
+
5. **`multi_turn_conversation(topic)`** - Multi-turn Conversation
|
|
41
|
+
- Demonstrates maintaining conversation context
|
|
42
|
+
- Multiple sequential sampling calls with message history
|
|
43
|
+
- Builds up conversation across sampling requests
|
|
44
|
+
|
|
45
|
+
6. **`research_question(question)`** - Agentic Research
|
|
46
|
+
- Demonstrates agentic workflow with sampling
|
|
47
|
+
- Multiple sampling calls to break down and answer questions
|
|
48
|
+
- Shows complex reasoning and synthesis
|
|
49
|
+
|
|
50
|
+
7. **`translate_and_explain(text, target_language)`** - Sequential Tasks
|
|
51
|
+
- Demonstrates multi-step workflows
|
|
52
|
+
- First sampling for translation, second for explanation
|
|
53
|
+
- Shows how to chain sampling results
|
|
54
|
+
|
|
55
|
+
## Usage Examples
|
|
56
|
+
|
|
57
|
+
### In Atlas UI Chat
|
|
58
|
+
|
|
59
|
+
After the sampling_demo server is enabled, you can test it with prompts like:
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
"Summarize this text using the sampling demo: [your text]"
|
|
63
|
+
"Analyze the sentiment of this review: [review text]"
|
|
64
|
+
"Generate Python code that calculates fibonacci numbers"
|
|
65
|
+
"Write a creative story about a robot learning to paint"
|
|
66
|
+
"Have a conversation about artificial intelligence"
|
|
67
|
+
"Research this question: What are the benefits of renewable energy?"
|
|
68
|
+
"Translate 'Hello, how are you?' to Spanish and explain the choices"
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Technical Details
|
|
72
|
+
|
|
73
|
+
### Sampling Parameters
|
|
74
|
+
|
|
75
|
+
Tools can control LLM generation with parameters:
|
|
76
|
+
|
|
77
|
+
- **messages**: Simple string or list of SamplingMessage objects for multi-turn
|
|
78
|
+
- **system_prompt**: Establishes LLM role and behavior
|
|
79
|
+
- **temperature**: Controls randomness (0.0 = deterministic, 1.0 = creative)
|
|
80
|
+
- **max_tokens**: Maximum tokens to generate (default: 512)
|
|
81
|
+
- **model_preferences**: Hints for which models the client should prefer
|
|
82
|
+
|
|
83
|
+
### Sampling Flow
|
|
84
|
+
|
|
85
|
+
1. Tool calls `ctx.sample()` with parameters
|
|
86
|
+
2. FastMCP client sends sampling request to Atlas backend
|
|
87
|
+
3. Backend's sampling handler routes request to configured LLM (via LiteLLM)
|
|
88
|
+
4. LLM generates response based on parameters
|
|
89
|
+
5. Response is returned to the tool execution
|
|
90
|
+
6. Tool processes and returns result to user
|
|
91
|
+
|
|
92
|
+
### Model Selection
|
|
93
|
+
|
|
94
|
+
The sampling handler selects models based on:
|
|
95
|
+
1. **Model preferences** provided in the sampling request
|
|
96
|
+
2. **Configured models** in Atlas llmconfig.yml
|
|
97
|
+
3. **Default model** as fallback
|
|
98
|
+
|
|
99
|
+
Model preferences are hints, not requirements. The backend uses the first matching configured model or falls back to the default.
|
|
100
|
+
|
|
101
|
+
## Configuration
|
|
102
|
+
|
|
103
|
+
This server is configured in `config/overrides/mcp.json`:
|
|
104
|
+
|
|
105
|
+
```json
|
|
106
|
+
{
|
|
107
|
+
"sampling_demo": {
|
|
108
|
+
"command": ["python", "mcp/sampling_demo/main.py"],
|
|
109
|
+
"cwd": "atlas",
|
|
110
|
+
"groups": ["users"],
|
|
111
|
+
"description": "Demonstrates MCP LLM sampling capabilities...",
|
|
112
|
+
"compliance_level": "Public"
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Development
|
|
118
|
+
|
|
119
|
+
To run the server standalone for testing:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
cd atlas
|
|
123
|
+
python mcp/sampling_demo/main.py
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
The FastMCP framework will display available tools and their schemas.
|
|
127
|
+
|
|
128
|
+
## References
|
|
129
|
+
|
|
130
|
+
- [FastMCP Sampling Documentation](https://gofastmcp.com/clients/sampling)
|
|
131
|
+
- [MCP Specification - Sampling](https://spec.modelcontextprotocol.io/)
|
|
132
|
+
- FastMCP Version: 2.0.0+
|
|
133
|
+
|
|
134
|
+
## Example Tool Implementation
|
|
135
|
+
|
|
136
|
+
```python
|
|
137
|
+
from fastmcp import FastMCP, Context
|
|
138
|
+
|
|
139
|
+
mcp = FastMCP("My Server")
|
|
140
|
+
|
|
141
|
+
@mcp.tool
|
|
142
|
+
async def analyze_text(text: str, ctx: Context) -> str:
|
|
143
|
+
"""Analyze text using LLM sampling."""
|
|
144
|
+
result = await ctx.sample(
|
|
145
|
+
messages=f"Analyze this text: {text}",
|
|
146
|
+
system_prompt="You are an expert analyst.",
|
|
147
|
+
temperature=0.5,
|
|
148
|
+
max_tokens=500
|
|
149
|
+
)
|
|
150
|
+
return result.text or "Analysis failed"
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## Comparison with Elicitation
|
|
154
|
+
|
|
155
|
+
| Feature | Elicitation | Sampling |
|
|
156
|
+
|---------|------------|----------|
|
|
157
|
+
| Purpose | Get user input | Get LLM generation |
|
|
158
|
+
| Who responds | Human user | LLM model |
|
|
159
|
+
| Use cases | Forms, confirmations | Analysis, generation |
|
|
160
|
+
| Timeout | 5 minutes | 5 minutes |
|
|
161
|
+
| Multiple turns | Supported | Supported |
|
|
162
|
+
| Parameters | Response schema | Temperature, max_tokens, model preferences |
|
|
163
|
+
|
|
164
|
+
## Support
|
|
165
|
+
|
|
166
|
+
For issues or questions about sampling:
|
|
167
|
+
- Check Atlas UI documentation in `/docs` folder
|
|
168
|
+
- Review FastMCP sampling docs at https://gofastmcp.com
|
|
169
|
+
- Report bugs via GitHub issues
|