napistu 0.2.5.dev7__py3-none-any.whl → 0.3.1.dev1__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.
- napistu/__init__.py +1 -3
- napistu/__main__.py +126 -96
- napistu/constants.py +35 -41
- napistu/context/__init__.py +10 -0
- napistu/context/discretize.py +462 -0
- napistu/context/filtering.py +387 -0
- napistu/gcs/__init__.py +1 -1
- napistu/identifiers.py +74 -15
- napistu/indices.py +68 -0
- napistu/ingestion/__init__.py +1 -1
- napistu/ingestion/bigg.py +47 -62
- napistu/ingestion/constants.py +18 -133
- napistu/ingestion/gtex.py +113 -0
- napistu/ingestion/hpa.py +147 -0
- napistu/ingestion/sbml.py +0 -97
- napistu/ingestion/string.py +2 -2
- napistu/matching/__init__.py +10 -0
- napistu/matching/constants.py +18 -0
- napistu/matching/interactions.py +518 -0
- napistu/matching/mount.py +529 -0
- napistu/matching/species.py +510 -0
- napistu/mcp/__init__.py +7 -4
- napistu/mcp/__main__.py +128 -72
- napistu/mcp/client.py +16 -25
- napistu/mcp/codebase.py +201 -145
- napistu/mcp/component_base.py +170 -0
- napistu/mcp/config.py +223 -0
- napistu/mcp/constants.py +45 -2
- napistu/mcp/documentation.py +253 -136
- napistu/mcp/documentation_utils.py +13 -48
- napistu/mcp/execution.py +372 -305
- napistu/mcp/health.py +47 -65
- napistu/mcp/profiles.py +10 -6
- napistu/mcp/server.py +161 -80
- napistu/mcp/tutorials.py +139 -87
- napistu/modify/__init__.py +1 -1
- napistu/modify/gaps.py +1 -1
- napistu/network/__init__.py +1 -1
- napistu/network/constants.py +101 -34
- napistu/network/data_handling.py +388 -0
- napistu/network/ig_utils.py +351 -0
- napistu/network/napistu_graph_core.py +354 -0
- napistu/network/neighborhoods.py +40 -40
- napistu/network/net_create.py +373 -309
- napistu/network/net_propagation.py +47 -19
- napistu/network/{net_utils.py → ng_utils.py} +124 -272
- napistu/network/paths.py +67 -51
- napistu/network/precompute.py +11 -11
- napistu/ontologies/__init__.py +10 -0
- napistu/ontologies/constants.py +129 -0
- napistu/ontologies/dogma.py +243 -0
- napistu/ontologies/genodexito.py +649 -0
- napistu/ontologies/mygene.py +369 -0
- napistu/ontologies/renaming.py +198 -0
- napistu/rpy2/__init__.py +229 -86
- napistu/rpy2/callr.py +47 -77
- napistu/rpy2/constants.py +24 -23
- napistu/rpy2/rids.py +61 -648
- napistu/sbml_dfs_core.py +587 -222
- napistu/scverse/__init__.py +15 -0
- napistu/scverse/constants.py +28 -0
- napistu/scverse/loading.py +727 -0
- napistu/utils.py +118 -10
- {napistu-0.2.5.dev7.dist-info → napistu-0.3.1.dev1.dist-info}/METADATA +8 -3
- napistu-0.3.1.dev1.dist-info/RECORD +133 -0
- tests/conftest.py +22 -0
- tests/test_context_discretize.py +56 -0
- tests/test_context_filtering.py +267 -0
- tests/test_identifiers.py +100 -0
- tests/test_indices.py +65 -0
- tests/{test_edgelist.py → test_ingestion_napistu_edgelist.py} +2 -2
- tests/test_matching_interactions.py +108 -0
- tests/test_matching_mount.py +305 -0
- tests/test_matching_species.py +394 -0
- tests/test_mcp_config.py +193 -0
- tests/test_mcp_documentation_utils.py +12 -3
- tests/test_mcp_server.py +156 -19
- tests/test_network_data_handling.py +397 -0
- tests/test_network_ig_utils.py +23 -0
- tests/test_network_neighborhoods.py +19 -0
- tests/test_network_net_create.py +459 -0
- tests/test_network_ng_utils.py +30 -0
- tests/test_network_paths.py +56 -0
- tests/{test_precomputed_distances.py → test_network_precompute.py} +8 -6
- tests/test_ontologies_genodexito.py +58 -0
- tests/test_ontologies_mygene.py +39 -0
- tests/test_ontologies_renaming.py +110 -0
- tests/test_rpy2_callr.py +79 -0
- tests/test_rpy2_init.py +151 -0
- tests/test_sbml.py +0 -31
- tests/test_sbml_dfs_core.py +134 -10
- tests/test_scverse_loading.py +778 -0
- tests/test_set_coverage.py +2 -2
- tests/test_utils.py +121 -1
- napistu/mechanism_matching.py +0 -1353
- napistu/rpy2/netcontextr.py +0 -467
- napistu-0.2.5.dev7.dist-info/RECORD +0 -98
- tests/test_igraph.py +0 -367
- tests/test_mechanism_matching.py +0 -784
- tests/test_net_utils.py +0 -149
- tests/test_netcontextr.py +0 -105
- tests/test_rpy2.py +0 -61
- /napistu/ingestion/{cpr_edgelist.py → napistu_edgelist.py} +0 -0
- {napistu-0.2.5.dev7.dist-info → napistu-0.3.1.dev1.dist-info}/WHEEL +0 -0
- {napistu-0.2.5.dev7.dist-info → napistu-0.3.1.dev1.dist-info}/entry_points.txt +0 -0
- {napistu-0.2.5.dev7.dist-info → napistu-0.3.1.dev1.dist-info}/licenses/LICENSE +0 -0
- {napistu-0.2.5.dev7.dist-info → napistu-0.3.1.dev1.dist-info}/top_level.txt +0 -0
- /tests/{test_obo.py → test_ingestion_obo.py} +0 -0
napistu/mcp/health.py
CHANGED
@@ -131,99 +131,81 @@ async def initialize_components() -> bool:
|
|
131
131
|
return False
|
132
132
|
|
133
133
|
|
134
|
-
def _check_component_health(
|
135
|
-
component_name: str, module_name: str, cache_attr: str
|
136
|
-
) -> Dict[str, str]:
|
134
|
+
def _check_component_health(component_name: str, module_path: str) -> Dict[str, Any]:
|
137
135
|
"""
|
138
|
-
Check the health of a single MCP component
|
136
|
+
Check the health of a single MCP component using the component class pattern.
|
139
137
|
|
140
138
|
Parameters
|
141
139
|
----------
|
142
140
|
component_name : str
|
143
|
-
Name of the component (for
|
144
|
-
|
145
|
-
Full module path for importing
|
146
|
-
cache_attr : str
|
147
|
-
Name of the cache/context attribute to check
|
141
|
+
Name of the component (for logging)
|
142
|
+
module_path : str
|
143
|
+
Full module path for importing the component
|
148
144
|
|
149
145
|
Returns
|
150
146
|
-------
|
151
|
-
Dict[str,
|
152
|
-
Dictionary containing component health status
|
153
|
-
- status : str
|
154
|
-
One of: 'healthy', 'inactive', or 'unavailable'
|
155
|
-
- error : str, optional
|
156
|
-
Error message if status is 'unavailable'
|
147
|
+
Dict[str, Any]
|
148
|
+
Dictionary containing component health status from the component's state
|
157
149
|
"""
|
158
150
|
try:
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
)
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
return {"status": "healthy"}
|
189
|
-
|
190
|
-
logger.info(f"{component_name} is inactive")
|
191
|
-
return {"status": "inactive"}
|
151
|
+
# Import the component module
|
152
|
+
module = __import__(module_path, fromlist=[component_name])
|
153
|
+
|
154
|
+
# Use the new component class pattern
|
155
|
+
if hasattr(module, "get_component"):
|
156
|
+
try:
|
157
|
+
component = module.get_component()
|
158
|
+
state = component.get_state()
|
159
|
+
health_status = state.get_health_status()
|
160
|
+
logger.info(f"{component_name} health: {health_status}")
|
161
|
+
return health_status
|
162
|
+
except RuntimeError as e:
|
163
|
+
# Handle execution component that might not be created yet
|
164
|
+
if "not created" in str(e):
|
165
|
+
logger.warning(f"{component_name} not initialized yet")
|
166
|
+
return {
|
167
|
+
"status": "initializing",
|
168
|
+
"message": "Component not created",
|
169
|
+
}
|
170
|
+
else:
|
171
|
+
raise
|
172
|
+
else:
|
173
|
+
# Component doesn't follow the new pattern
|
174
|
+
logger.warning(f"{component_name} doesn't use component class pattern")
|
175
|
+
return {"status": "unknown", "message": "Component using legacy pattern"}
|
176
|
+
|
177
|
+
except ImportError as e:
|
178
|
+
logger.error(f"Could not import {component_name}: {str(e)}")
|
179
|
+
return {"status": "unavailable", "error": f"Import failed: {str(e)}"}
|
192
180
|
except Exception as e:
|
193
|
-
logger.error(f"{component_name} check failed: {str(e)}")
|
181
|
+
logger.error(f"{component_name} health check failed: {str(e)}")
|
194
182
|
return {"status": "unavailable", "error": str(e)}
|
195
183
|
|
196
184
|
|
197
185
|
async def _check_components() -> Dict[str, Dict[str, Any]]:
|
198
186
|
"""
|
199
|
-
Check the health of individual MCP components
|
187
|
+
Check the health of individual MCP components using their component classes.
|
200
188
|
|
201
189
|
Returns
|
202
190
|
-------
|
203
191
|
Dict[str, Dict[str, Any]]
|
204
|
-
Dictionary mapping component names to their health status
|
205
|
-
- {component_name} : Dict[str, str]
|
206
|
-
Health status for each component, containing:
|
207
|
-
- status : str
|
208
|
-
One of: 'healthy', 'inactive', or 'unavailable'
|
209
|
-
- error : str, optional
|
210
|
-
Error message if status is 'unavailable'
|
192
|
+
Dictionary mapping component names to their health status
|
211
193
|
"""
|
212
|
-
# Define component configurations
|
194
|
+
# Define component configurations
|
213
195
|
component_configs = {
|
214
|
-
"documentation":
|
215
|
-
"codebase":
|
216
|
-
"tutorials":
|
217
|
-
"execution":
|
196
|
+
"documentation": "napistu.mcp.documentation",
|
197
|
+
"codebase": "napistu.mcp.codebase",
|
198
|
+
"tutorials": "napistu.mcp.tutorials",
|
199
|
+
"execution": "napistu.mcp.execution",
|
218
200
|
}
|
219
201
|
|
220
202
|
logger.info("Starting component health checks...")
|
221
203
|
logger.info(f"Checking components: {list(component_configs.keys())}")
|
222
204
|
|
223
|
-
# Check each component
|
205
|
+
# Check each component using their state objects
|
224
206
|
results = {
|
225
|
-
name: _check_component_health(name, module_path
|
226
|
-
for name,
|
207
|
+
name: _check_component_health(name, module_path)
|
208
|
+
for name, module_path in component_configs.items()
|
227
209
|
}
|
228
210
|
|
229
211
|
logger.info(f"Health check results: {results}")
|
napistu/mcp/profiles.py
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
from typing import Dict, Any
|
2
2
|
|
3
|
+
from napistu.mcp.constants import MCP_PROFILES
|
4
|
+
|
3
5
|
|
4
6
|
class ServerProfile:
|
5
7
|
"""Base profile for MCP server configuration."""
|
@@ -31,9 +33,11 @@ class ServerProfile:
|
|
31
33
|
|
32
34
|
|
33
35
|
# Pre-defined profiles
|
34
|
-
|
36
|
+
EXECUTION_PROFILE = ServerProfile(
|
37
|
+
server_name="napistu-execution", enable_execution=True
|
38
|
+
)
|
35
39
|
|
36
|
-
|
40
|
+
DOCS_PROFILE = ServerProfile(
|
37
41
|
server_name="napistu-docs",
|
38
42
|
enable_documentation=True,
|
39
43
|
enable_codebase=True,
|
@@ -54,16 +58,16 @@ def get_profile(profile_name: str, **overrides) -> ServerProfile:
|
|
54
58
|
Get a predefined profile with optional overrides.
|
55
59
|
|
56
60
|
Args:
|
57
|
-
profile_name: Name of the profile ('
|
61
|
+
profile_name: Name of the profile ('execution', 'docs', or 'full')
|
58
62
|
**overrides: Configuration overrides
|
59
63
|
|
60
64
|
Returns:
|
61
65
|
ServerProfile instance
|
62
66
|
"""
|
63
67
|
profiles = {
|
64
|
-
|
65
|
-
|
66
|
-
|
68
|
+
MCP_PROFILES.EXECUTION: EXECUTION_PROFILE,
|
69
|
+
MCP_PROFILES.DOCS: DOCS_PROFILE,
|
70
|
+
MCP_PROFILES.FULL: FULL_PROFILE,
|
67
71
|
}
|
68
72
|
|
69
73
|
if profile_name not in profiles:
|
napistu/mcp/server.py
CHANGED
@@ -1,11 +1,9 @@
|
|
1
|
-
# src/napistu/mcp/server.py
|
2
1
|
"""
|
3
2
|
Core MCP server implementation for Napistu.
|
4
3
|
"""
|
5
4
|
|
6
5
|
import asyncio
|
7
6
|
import logging
|
8
|
-
import os
|
9
7
|
|
10
8
|
from mcp.server import FastMCP
|
11
9
|
|
@@ -16,20 +14,60 @@ from napistu.mcp import tutorials
|
|
16
14
|
from napistu.mcp import health
|
17
15
|
|
18
16
|
from napistu.mcp.profiles import ServerProfile, get_profile
|
17
|
+
from napistu.mcp.constants import MCP_DEFAULTS
|
18
|
+
from napistu.mcp.config import MCPServerConfig
|
19
19
|
|
20
20
|
logger = logging.getLogger(__name__)
|
21
21
|
|
22
22
|
|
23
|
-
def
|
23
|
+
def _register_component(
|
24
|
+
name: str, module, config_key: str, config: dict, mcp: FastMCP, **kwargs
|
25
|
+
) -> None:
|
26
|
+
"""
|
27
|
+
Register a single component with the MCP server.
|
28
|
+
|
29
|
+
Parameters
|
30
|
+
----------
|
31
|
+
name : str
|
32
|
+
Component name for logging
|
33
|
+
module : module
|
34
|
+
Component module with get_component() function or create_component() for execution
|
35
|
+
config_key : str
|
36
|
+
Configuration key to check if component is enabled
|
37
|
+
config : dict
|
38
|
+
Server configuration
|
39
|
+
mcp : FastMCP
|
40
|
+
FastMCP server instance
|
41
|
+
**kwargs : dict
|
42
|
+
Additional arguments for component creation (used by execution component)
|
43
|
+
"""
|
44
|
+
if not config.get(config_key, False):
|
45
|
+
return # Skip disabled components
|
46
|
+
|
47
|
+
logger.info(f"Registering {name} components")
|
48
|
+
|
49
|
+
if name == "execution":
|
50
|
+
# Special handling for execution component which needs session context
|
51
|
+
component = module.create_component(
|
52
|
+
session_context=kwargs.get("session_context"),
|
53
|
+
object_registry=kwargs.get("object_registry"),
|
54
|
+
)
|
55
|
+
else:
|
56
|
+
component = module.get_component()
|
57
|
+
|
58
|
+
component.register(mcp)
|
59
|
+
|
60
|
+
|
61
|
+
def create_server(profile: ServerProfile, server_config: MCPServerConfig) -> FastMCP:
|
24
62
|
"""
|
25
|
-
Create an MCP server based on a profile configuration.
|
63
|
+
Create an MCP server based on a profile configuration and server config.
|
26
64
|
|
27
65
|
Parameters
|
28
66
|
----------
|
29
67
|
profile : ServerProfile
|
30
|
-
Server profile to use. All configuration must be set in the profile.
|
31
|
-
|
32
|
-
|
68
|
+
Server profile to use. All configuration must be set in the profile. (Valid profiles: 'execution', 'docs', 'full')
|
69
|
+
server_config : MCPServerConfig
|
70
|
+
Server configuration with validated host, port, and server name.
|
33
71
|
|
34
72
|
Returns
|
35
73
|
-------
|
@@ -39,26 +77,30 @@ def create_server(profile: ServerProfile, **kwargs) -> FastMCP:
|
|
39
77
|
|
40
78
|
config = profile.get_config()
|
41
79
|
|
42
|
-
# Create the server with
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
80
|
+
# Create the server with validated configuration
|
81
|
+
mcp = FastMCP(
|
82
|
+
server_config.server_name, host=server_config.host, port=server_config.port
|
83
|
+
)
|
84
|
+
|
85
|
+
# Define component configurations
|
86
|
+
component_configs = [
|
87
|
+
("documentation", documentation, "enable_documentation"),
|
88
|
+
("codebase", codebase, "enable_codebase"),
|
89
|
+
("tutorials", tutorials, "enable_tutorials"),
|
90
|
+
("execution", execution, "enable_execution"),
|
91
|
+
]
|
92
|
+
|
93
|
+
# Register all components
|
94
|
+
for name, module, config_key in component_configs:
|
95
|
+
_register_component(
|
96
|
+
name,
|
97
|
+
module,
|
98
|
+
config_key,
|
99
|
+
config,
|
55
100
|
mcp,
|
56
|
-
session_context=config
|
57
|
-
object_registry=config
|
101
|
+
session_context=config.get("session_context"),
|
102
|
+
object_registry=config.get("object_registry"),
|
58
103
|
)
|
59
|
-
if config["enable_tutorials"]:
|
60
|
-
logger.info("Registering tutorials components")
|
61
|
-
tutorials.register_components(mcp)
|
62
104
|
|
63
105
|
# Always register health components
|
64
106
|
health.register_components(mcp)
|
@@ -67,9 +109,44 @@ def create_server(profile: ServerProfile, **kwargs) -> FastMCP:
|
|
67
109
|
return mcp
|
68
110
|
|
69
111
|
|
112
|
+
async def _initialize_component(
|
113
|
+
name: str, module, config_key: str, config: dict
|
114
|
+
) -> bool:
|
115
|
+
"""
|
116
|
+
Initialize a single component with error handling.
|
117
|
+
|
118
|
+
Parameters
|
119
|
+
----------
|
120
|
+
name : str
|
121
|
+
Component name for logging
|
122
|
+
module : module
|
123
|
+
Component module with get_component() function
|
124
|
+
config_key : str
|
125
|
+
Configuration key to check if component is enabled
|
126
|
+
config : dict
|
127
|
+
Server configuration
|
128
|
+
|
129
|
+
Returns
|
130
|
+
-------
|
131
|
+
bool
|
132
|
+
True if initialization successful
|
133
|
+
"""
|
134
|
+
if not config.get(config_key, False):
|
135
|
+
return True # Skip disabled components
|
136
|
+
|
137
|
+
logger.info(f"Initializing {name} components")
|
138
|
+
try:
|
139
|
+
component = module.get_component()
|
140
|
+
result = await component.safe_initialize()
|
141
|
+
return result
|
142
|
+
except Exception as e:
|
143
|
+
logger.error(f"❌ {name.title()} components failed to initialize: {e}")
|
144
|
+
return False
|
145
|
+
|
146
|
+
|
70
147
|
async def initialize_components(profile: ServerProfile) -> None:
|
71
148
|
"""
|
72
|
-
Asynchronously initialize all enabled components for the MCP server
|
149
|
+
Asynchronously initialize all enabled components for the MCP server.
|
73
150
|
|
74
151
|
Parameters
|
75
152
|
----------
|
@@ -82,51 +159,61 @@ async def initialize_components(profile: ServerProfile) -> None:
|
|
82
159
|
"""
|
83
160
|
config = profile.get_config()
|
84
161
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
162
|
+
# Define component configurations
|
163
|
+
component_configs = [
|
164
|
+
("documentation", documentation, "enable_documentation"),
|
165
|
+
("codebase", codebase, "enable_codebase"),
|
166
|
+
("tutorials", tutorials, "enable_tutorials"),
|
167
|
+
("execution", execution, "enable_execution"),
|
168
|
+
]
|
169
|
+
|
170
|
+
# Initialize all components
|
171
|
+
initialization_results = {}
|
172
|
+
|
173
|
+
for name, module, config_key in component_configs:
|
174
|
+
result = await _initialize_component(name, module, config_key, config)
|
175
|
+
initialization_results[name] = result
|
97
176
|
|
98
177
|
# Initialize health components last since they monitor the other components
|
99
178
|
logger.info("Initializing health components")
|
100
|
-
|
179
|
+
try:
|
180
|
+
result = await health.initialize_components()
|
181
|
+
initialization_results["health"] = result
|
182
|
+
if result:
|
183
|
+
logger.info("✅ Health components initialized successfully")
|
184
|
+
else:
|
185
|
+
logger.warning("⚠️ Health components initialized with issues")
|
186
|
+
except Exception as e:
|
187
|
+
logger.error(f"❌ Health components failed to initialize: {e}")
|
188
|
+
initialization_results["health"] = False
|
189
|
+
|
190
|
+
# Summary of initialization
|
191
|
+
successful = sum(1 for success in initialization_results.values() if success)
|
192
|
+
total = len(initialization_results)
|
193
|
+
logger.info(
|
194
|
+
f"Component initialization complete: {successful}/{total} components successful"
|
195
|
+
)
|
101
196
|
|
197
|
+
if successful == 0:
|
198
|
+
logger.error(
|
199
|
+
"❌ All components failed to initialize - server may not function correctly"
|
200
|
+
)
|
201
|
+
elif successful < total:
|
202
|
+
logger.warning(
|
203
|
+
"⚠️ Some components failed to initialize - server running in degraded mode"
|
204
|
+
)
|
102
205
|
|
103
|
-
|
104
|
-
|
105
|
-
host: str = "0.0.0.0",
|
106
|
-
port: int = 8080,
|
107
|
-
server_name: str | None = None,
|
108
|
-
) -> None:
|
206
|
+
|
207
|
+
def start_mcp_server(profile_name: str, server_config: MCPServerConfig) -> None:
|
109
208
|
"""
|
110
209
|
Start MCP server - main entry point for server startup.
|
111
210
|
|
112
|
-
The server will be started with HTTP transport on the specified host and port.
|
113
|
-
Environment variables can override the default configuration:
|
114
|
-
- MCP_PROFILE: Server profile to use
|
115
|
-
- HOST: Host to bind to
|
116
|
-
- PORT: Port to bind to
|
117
|
-
- MCP_SERVER_NAME: Name of the MCP server
|
118
|
-
|
119
211
|
Parameters
|
120
212
|
----------
|
121
|
-
profile_name : str
|
122
|
-
Server profile to use ('local', 'remote', 'full').
|
123
|
-
|
124
|
-
|
125
|
-
port : int, optional
|
126
|
-
Port number to listen on. Defaults to 8080.
|
127
|
-
server_name : str | None, optional
|
128
|
-
Custom name for the MCP server. If None, will be generated from profile name.
|
129
|
-
Defaults to None.
|
213
|
+
profile_name : str
|
214
|
+
Server profile to use ('local', 'remote', 'full').
|
215
|
+
server_config : MCPServerConfig
|
216
|
+
Validated server configuration.
|
130
217
|
|
131
218
|
Returns
|
132
219
|
-------
|
@@ -143,20 +230,12 @@ def start_mcp_server(
|
|
143
230
|
logging.basicConfig(level=logging.INFO)
|
144
231
|
logger = logging.getLogger("napistu")
|
145
232
|
|
146
|
-
# Get configuration from environment variables (for Cloud Run)
|
147
|
-
env_profile = os.getenv("MCP_PROFILE", profile_name)
|
148
|
-
env_host = os.getenv("HOST", host)
|
149
|
-
env_port = int(os.getenv("PORT", port))
|
150
|
-
env_server_name = os.getenv(
|
151
|
-
"MCP_SERVER_NAME", server_name or f"napistu-{env_profile}"
|
152
|
-
)
|
153
|
-
|
154
233
|
logger.info("Starting Napistu MCP Server")
|
155
|
-
logger.info(f" Profile: {
|
156
|
-
logger.info(f" Host: {
|
157
|
-
logger.info(f" Port: {
|
158
|
-
logger.info(f" Server Name: {
|
159
|
-
logger.info(" Transport:
|
234
|
+
logger.info(f" Profile: {profile_name}")
|
235
|
+
logger.info(f" Host: {server_config.host}")
|
236
|
+
logger.info(f" Port: {server_config.port}")
|
237
|
+
logger.info(f" Server Name: {server_config.server_name}")
|
238
|
+
logger.info(f" Transport: {MCP_DEFAULTS.TRANSPORT}")
|
160
239
|
|
161
240
|
# Create session context for execution components
|
162
241
|
session_context = {}
|
@@ -164,14 +243,14 @@ def start_mcp_server(
|
|
164
243
|
|
165
244
|
# Get profile with configuration
|
166
245
|
profile: ServerProfile = get_profile(
|
167
|
-
|
246
|
+
profile_name,
|
168
247
|
session_context=session_context,
|
169
248
|
object_registry=object_registry,
|
170
|
-
server_name=
|
249
|
+
server_name=server_config.server_name,
|
171
250
|
)
|
172
251
|
|
173
|
-
# Create server with
|
174
|
-
mcp = create_server(profile,
|
252
|
+
# Create server with validated configuration
|
253
|
+
mcp = create_server(profile, server_config)
|
175
254
|
|
176
255
|
# Initialize components first (separate async call)
|
177
256
|
async def init_components():
|
@@ -186,6 +265,8 @@ def start_mcp_server(
|
|
186
265
|
logger.info(f"Server settings: {mcp.settings}")
|
187
266
|
|
188
267
|
logger.info("🚀 Starting MCP server...")
|
189
|
-
logger.info(
|
268
|
+
logger.info(
|
269
|
+
f"Using {MCP_DEFAULTS.TRANSPORT} transport on http://{server_config.host}:{server_config.port}"
|
270
|
+
)
|
190
271
|
|
191
|
-
mcp.run(transport=
|
272
|
+
mcp.run(transport=MCP_DEFAULTS.TRANSPORT)
|