Coverage for gco_mcp/run_mcp.py: 92.11%
192 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-07-30 21:22 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-07-30 21:22 +0000
1#!/usr/bin/env python3
2"""
3GCO MCP Server — Exposes the GCO CLI as MCP tools for LLM interaction.
5Run with:
6 python gco_mcp/run_mcp.py
8Add to Kiro MCP config (.kiro/settings/mcp.json):
9 {
10 "mcpServers": {
11 "gco": {
12 "command": "python3",
13 "args": ["gco_mcp/run_mcp.py"],
14 "cwd": "/path/to/GCO"
15 }
16 }
17 }
19This file is a thin entrypoint. The implementation lives under
20``gco_mcp/``; the two package registries are the authoritative module lists:
22 gco_mcp/
23 ├── server.py — FastMCP singleton, transforms, and middleware
24 ├── feature_flags.py — Environment-driven tool gates
25 ├── audit.py — Structured tool/resource/startup audit logging
26 ├── audit_middleware.py — Per-request message and elicitation capture
27 ├── iam.py — Optional startup role assumption
28 ├── cli_runner.py — Bounded gco CLI subprocess wrapper
29 ├── local_data.py — Confined local-path and snapshot helpers
30 ├── mission/ — Goal-directed Mission engine
31 ├── metric_readers/ — Canonical metric-source adapters
32 ├── mission_judge/ — Semantic-progress scorer
33 ├── tools/
34 │ ├── __init__.py — Registers all tool-domain modules
35 │ └── README.md — Complete per-module and per-tool catalog
36 └── resources/
37 ├── __init__.py — Registers every static/live resource module
38 └── README.md — Complete URI-family and module catalog
39"""
41import sys
42from pathlib import Path
44# The file is supported both as ``python gco_mcp/run_mcp.py`` and as
45# ``import gco_mcp.run_mcp``. Alias the two names before importing the shared
46# server so either route observes one module and one FastMCP singleton.
47_THIS_MODULE = sys.modules[__name__]
48if __name__ in {"run_mcp", "__main__"}: 48 ↛ 50line 48 didn't jump to line 50 because the condition on line 48 was always true
49 sys.modules.setdefault("gco_mcp.run_mcp", _THIS_MODULE)
50if __name__ in {"gco_mcp.run_mcp", "__main__"}: 50 ↛ 51line 50 didn't jump to line 51 because the condition on line 50 was never true
51 sys.modules.setdefault("run_mcp", _THIS_MODULE)
53# ``importlib.reload`` retains a module's globals. Record whether this is an
54# explicit same-process reload so compatibility rebinds do not re-register
55# every flagged tool during a normal, clean server startup.
56_IS_RELOAD = bool(getattr(_THIS_MODULE, "_RUN_MCP_IMPORT_COMPLETE", False))
58# Direct script execution starts with only gco_mcp/ on sys.path. Add each
59# required root at most once; package imports need no mutation.
60PROJECT_ROOT = Path(__file__).resolve().parent.parent
61MCP_DIR = Path(__file__).resolve().parent
62for _path in (str(PROJECT_ROOT), str(MCP_DIR)):
63 if _path not in sys.path: 63 ↛ 64line 63 didn't jump to line 64 because the condition on line 63 was never true
64 sys.path.insert(0, _path)
66# --- Re-export everything the existing tests expect on ``run_mcp.*`` ---
68from audit import ( # noqa: E402, F401
69 _MCP_SERVER_VERSION,
70 _sanitize_arguments,
71 audit_logged,
72 audit_logger,
73 emit_startup_log,
74)
75from iam import assume_mcp_role # noqa: E402, F401
76from server import mcp # noqa: E402, F401
77from version import get_project_version # noqa: E402, F401
79# Re-export the project version for tests that check run_mcp._PROJECT_VERSION
80_PROJECT_VERSION = get_project_version()
82# --- Register all tools and resources ---
84from resources import register_all_resources # noqa: E402
85from tools import register_all_tools # noqa: E402
87register_all_tools()
88if _IS_RELOAD:
89 # Static resources already live on the shared FastMCP singleton. Mission
90 # resources are the sole flag-gated family and may need to appear after a
91 # test or embedding process deliberately changes flags and reloads us.
92 from resources import mission as _mission_resources
94 _mission_resources.register(mcp)
95else:
96 register_all_resources()
98# --- Re-export tool functions for backward compat with existing tests ---
99# Tests call e.g. run_mcp.list_jobs(), so we import them into this namespace.
101# Conditionally re-export reserve_capacity if it was registered.
102# contextlib.suppress is the idiomatic "swallow this exception" form.
103import contextlib as _contextlib # noqa: E402
104import importlib as _importlib # noqa: E402
106import feature_flags as _feature_flags # noqa: E402
107from tools.analytics import ( # noqa: E402, F401
108 analytics_doctor,
109 analytics_login_url,
110 analytics_status,
111 analytics_user_add,
112 analytics_users_list,
113 disable_analytics,
114 enable_analytics,
115)
116from tools.capacity import ( # noqa: E402, F401
117 ai_recommend,
118 capacity_history_patterns,
119 capacity_history_show,
120 capacity_history_stats,
121 capacity_predict,
122 capacity_status,
123 check_capacity,
124 find_capacity_blocks,
125 find_capacity_reservations,
126 instance_info,
127 list_reservations,
128 recommend_capacity,
129 recommend_region,
130 reservation_check,
131 spot_prices,
132)
133from tools.cluster import cluster_tunnel_command # noqa: E402, F401
134from tools.config import config_get # noqa: E402, F401
135from tools.costs import ( # noqa: E402, F401
136 cost_allocation_activate,
137 cost_allocation_status,
138 cost_by_region,
139 cost_forecast,
140 cost_k8s_namespaces,
141 cost_k8s_regions,
142 cost_k8s_top,
143 cost_k8s_trend,
144 cost_report_generate,
145 cost_report_list,
146 cost_report_status,
147 cost_summary,
148 cost_trend,
149 cost_workloads,
150)
151from tools.dag import dag_run, dag_validate # noqa: E402, F401
152from tools.docs import find_docs # noqa: E402, F401
153from tools.examples import find_examples # noqa: E402, F401
154from tools.images import ( # noqa: E402, F401
155 images_describe,
156 images_init,
157 images_lifecycle_get,
158 images_lifecycle_set,
159 images_list,
160 images_mirror_plan,
161 images_mirror_status,
162 images_orphans,
163 images_replication_get,
164 images_replication_status,
165 images_replication_sync,
166 images_tags,
167 images_uri,
168)
169from tools.inference import ( # noqa: E402, F401
170 canary_deploy,
171 chat_inference,
172 configure_mooncake_store,
173 deploy_disaggregated_inference,
174 deploy_inference,
175 inference_health,
176 inference_status,
177 invoke_inference,
178 list_endpoint_models,
179 list_inference_endpoints,
180 mooncake_topology_status,
181 populate_kv_cache,
182 promote_canary,
183 rollback_canary,
184 scale_inference,
185 set_mooncake_topology,
186 start_inference,
187 stop_inference,
188 update_inference_image,
189)
190from tools.jobs import ( # noqa: E402, F401
191 cluster_health,
192 get_job,
193 get_job_events,
194 get_job_logs,
195 get_job_metrics,
196 get_job_pods,
197 get_pod_logs,
198 list_jobs,
199 queue_status,
200 retry_job,
201 submit_job_api,
202 submit_job_sqs,
203)
204from tools.metrics import ( # noqa: E402, F401
205 metrics_cloudwatch_get,
206 metrics_from_job_logs,
207 metrics_from_shared_storage_file,
208)
209from tools.models import get_model_uri, list_models # noqa: E402, F401
210from tools.monitoring import ( # noqa: E402, F401
211 disable_monitoring,
212 enable_monitoring,
213 monitoring_status,
214 monitoring_user_add,
215 monitoring_users_list,
216)
217from tools.nodepools import ( # noqa: E402, F401
218 nodepools_create_capacity_block,
219 nodepools_create_odcr,
220 nodepools_describe,
221 nodepools_list,
222)
223from tools.queue import queue_get, queue_list, queue_stats, queue_submit # noqa: E402, F401
224from tools.stacks import ( # noqa: E402, F401
225 addons_status,
226 aurora_status,
227 disable_aurora,
228 disable_fsx,
229 disable_valkey,
230 enable_aurora,
231 enable_fsx,
232 enable_valkey,
233 fsx_status,
234 list_stacks,
235 setup_cluster_access,
236 stack_diff,
237 stack_outputs,
238 stack_status,
239 stack_synth,
240 valkey_status,
241)
242from tools.storage import ( # noqa: E402, F401
243 files_access_points,
244 files_get,
245 list_file_systems,
246 list_storage_buckets,
247 list_storage_contents,
248)
249from tools.tasks import task_status, task_tail # noqa: E402, F401
250from tools.templates import ( # noqa: E402, F401
251 templates_create,
252 templates_get,
253 templates_list,
254 templates_run,
255)
256from tools.webhooks import webhooks_create, webhooks_get, webhooks_list # noqa: E402, F401
258with _contextlib.suppress(ImportError):
259 from tools.capacity import create_reservation, reserve_capacity # noqa: F401
261with _contextlib.suppress(ImportError):
262 from tools.images import images_build, images_mirror, images_push # noqa: F401
264with _contextlib.suppress(ImportError):
265 from tools.images import ( # noqa: F401
266 images_cleanup,
267 images_delete_repo,
268 images_delete_tag,
269 images_prune,
270 )
272with _contextlib.suppress(ImportError):
273 from tools.stacks import addons_install, bootstrap_cdk, deploy_all, deploy_stack # noqa: F401
275with _contextlib.suppress(ImportError):
276 from tools.stacks import destroy_all, destroy_stack # noqa: F401
278# Destructive-operations gated tools — present only when
279# GCO_ENABLE_DESTRUCTIVE_OPERATIONS (or GCO_ENABLE_ALL_TOOLS) is set.
280with _contextlib.suppress(ImportError):
281 from tools.capacity import cancel_reservation # noqa: F401
283with _contextlib.suppress(ImportError):
284 from tools.jobs import delete_job # noqa: F401
286with _contextlib.suppress(ImportError):
287 from tools.inference import delete_inference # noqa: F401
289with _contextlib.suppress(ImportError):
290 from tools.templates import delete_template # noqa: F401
292with _contextlib.suppress(ImportError):
293 from tools.webhooks import delete_webhook # noqa: F401
295with _contextlib.suppress(ImportError):
296 from tools.models import delete_model # noqa: F401
298with _contextlib.suppress(ImportError):
299 from tools.nodepools import delete_nodepool # noqa: F401
301with _contextlib.suppress(ImportError):
302 from tools.analytics import analytics_user_remove # noqa: F401
304with _contextlib.suppress(ImportError):
305 from tools.monitoring import monitoring_user_remove # noqa: F401
307with _contextlib.suppress(ImportError):
308 from tools.queue import cancel_queue_job # noqa: F401
310with _contextlib.suppress(ImportError):
311 from tools.tasks import task_prune # noqa: F401
313# Model-upload gated tool — present only when GCO_ENABLE_MODEL_UPLOAD
314# (or GCO_ENABLE_ALL_TOOLS) is set.
315with _contextlib.suppress(ImportError):
316 from tools.models import models_upload # noqa: F401
318with _contextlib.suppress(ImportError):
319 from tools.storage import upload_to_regional_bucket # noqa: F401
321# Local-metrics, local-storage, semantic-progress, and Mission tools also use
322# import-time gates. The imports are no-ops when disabled; the explicit reload
323# compatibility blocks below rebind them only during ``importlib.reload``.
324with _contextlib.suppress(ImportError):
325 from tools.metrics import metrics_from_local_file # noqa: F401
327with _contextlib.suppress(ImportError):
328 from tools.storage import sync_storage_bucket # noqa: F401
330with _contextlib.suppress(ImportError):
331 from tools.semantic_progress import metrics_semantic_progress # noqa: F401
333with _contextlib.suppress(ImportError):
334 from tools.mission import ( # noqa: F401
335 mission_abort,
336 mission_checkpoint,
337 mission_complete,
338 mission_history,
339 mission_iterate,
340 mission_list,
341 mission_resume,
342 mission_start,
343 mission_status,
344 )
346# Explicit reload compatibility for the two gated families in capacity.py.
347# A clean startup has just imported the module under the final environment and
348# must not reload it: doing so used to emit duplicate-component warnings for
349# every unconditional capacity tool.
350if _IS_RELOAD and (
351 _feature_flags.is_enabled(_feature_flags.FLAG_CAPACITY_PURCHASE)
352 or _feature_flags.is_enabled(_feature_flags.FLAG_DESTRUCTIVE_OPERATIONS)
353):
354 from tools import capacity as _cap_mod # noqa: E402
356 _importlib.reload(_cap_mod)
357 for _name in ("reserve_capacity", "create_reservation", "cancel_reservation"):
358 if hasattr(_cap_mod, _name):
359 globals()[_name] = getattr(_cap_mod, _name)
361# Reload tools.images when image-publish or destructive flags are set so
362# the gated build/push/delete tools are present after a test
363# ``importlib.reload(run_mcp)`` cycle. Mirrors the reserve_capacity pattern.
364if _IS_RELOAD and (
365 _feature_flags.is_enabled(_feature_flags.FLAG_IMAGE_PUBLISH)
366 or _feature_flags.is_enabled(_feature_flags.FLAG_DESTRUCTIVE_OPERATIONS)
367):
368 from tools import images as _img_mod # noqa: E402
370 _importlib.reload(_img_mod)
371 for _name in (
372 "images_build",
373 "images_push",
374 "images_mirror",
375 "images_cleanup",
376 "images_prune",
377 "images_delete_tag",
378 "images_delete_repo",
379 ):
380 if hasattr(_img_mod, _name):
381 globals()[_name] = getattr(_img_mod, _name)
383# Reload tools.stacks when either infrastructure flag is set so the
384# gated deploy/destroy/bootstrap tools are present after a test
385# ``importlib.reload(run_mcp)`` cycle. Mirrors the reserve_capacity pattern.
386if _IS_RELOAD and (
387 _feature_flags.is_enabled(_feature_flags.FLAG_INFRASTRUCTURE_DEPLOY)
388 or _feature_flags.is_enabled(_feature_flags.FLAG_INFRASTRUCTURE_DESTROY)
389):
390 from tools import stacks as _stacks_mod # noqa: E402
392 _importlib.reload(_stacks_mod)
393 for _name in (
394 "deploy_stack",
395 "deploy_all",
396 "bootstrap_cdk",
397 "addons_install",
398 "destroy_stack",
399 "destroy_all",
400 ):
401 if hasattr(_stacks_mod, _name):
402 globals()[_name] = getattr(_stacks_mod, _name)
404# Destructive-operations and model-upload gated reload blocks — mirror the
405# reserve_capacity pattern so flag-driven tests can do ``importlib.reload(
406# run_mcp)`` and have the gated names appear as module-level attributes.
407_DESTRUCTIVE_FLAG_ON = _feature_flags.is_enabled(_feature_flags.FLAG_DESTRUCTIVE_OPERATIONS)
408_MODEL_UPLOAD_FLAG_ON = _feature_flags.is_enabled(_feature_flags.FLAG_MODEL_UPLOAD)
410if _IS_RELOAD and _DESTRUCTIVE_FLAG_ON:
411 from tools import jobs as _jobs_mod # noqa: E402
413 _importlib.reload(_jobs_mod)
414 if hasattr(_jobs_mod, "delete_job"): 414 ↛ 417line 414 didn't jump to line 417 because the condition on line 414 was always true
415 delete_job = _jobs_mod.delete_job # noqa: F811
417 from tools import inference as _inf_mod # noqa: E402
419 _importlib.reload(_inf_mod)
420 if hasattr(_inf_mod, "delete_inference"): 420 ↛ 423line 420 didn't jump to line 423 because the condition on line 420 was always true
421 delete_inference = _inf_mod.delete_inference # noqa: F811
423 from tools import templates as _tpl_mod # noqa: E402
425 _importlib.reload(_tpl_mod)
426 if hasattr(_tpl_mod, "delete_template"): 426 ↛ 429line 426 didn't jump to line 429 because the condition on line 426 was always true
427 globals()["delete_template"] = _tpl_mod.delete_template
429 from tools import webhooks as _wh_mod # noqa: E402
431 _importlib.reload(_wh_mod)
432 if hasattr(_wh_mod, "delete_webhook"): 432 ↛ 435line 432 didn't jump to line 435 because the condition on line 432 was always true
433 globals()["delete_webhook"] = _wh_mod.delete_webhook
435 from tools import nodepools as _np_mod # noqa: E402
437 _importlib.reload(_np_mod)
438 if hasattr(_np_mod, "delete_nodepool"): 438 ↛ 441line 438 didn't jump to line 441 because the condition on line 438 was always true
439 globals()["delete_nodepool"] = _np_mod.delete_nodepool
441 from tools import analytics as _an_mod # noqa: E402
443 _importlib.reload(_an_mod)
444 if hasattr(_an_mod, "analytics_user_remove"): 444 ↛ 447line 444 didn't jump to line 447 because the condition on line 444 was always true
445 globals()["analytics_user_remove"] = _an_mod.analytics_user_remove
447 from tools import queue as _q_mod # noqa: E402
449 _importlib.reload(_q_mod)
450 if hasattr(_q_mod, "cancel_queue_job"): 450 ↛ 453line 450 didn't jump to line 453 because the condition on line 450 was always true
451 globals()["cancel_queue_job"] = _q_mod.cancel_queue_job
453 from tools import monitoring as _mon_mod # noqa: E402
455 _importlib.reload(_mon_mod)
456 if hasattr(_mon_mod, "monitoring_user_remove"): 456 ↛ 459line 456 didn't jump to line 459 because the condition on line 456 was always true
457 globals()["monitoring_user_remove"] = _mon_mod.monitoring_user_remove
459 from tools import tasks as _tasks_mod # noqa: E402
461 _importlib.reload(_tasks_mod)
462 if hasattr(_tasks_mod, "task_prune"): 462 ↛ 468line 462 didn't jump to line 468 because the condition on line 462 was always true
463 globals()["task_prune"] = _tasks_mod.task_prune
465# tools.models is reloaded if either the destructive flag (delete_model)
466# or the model-upload flag (models_upload) is set, so do it once here
467# regardless of which (or both) flipped.
468if _IS_RELOAD and (_DESTRUCTIVE_FLAG_ON or _MODEL_UPLOAD_FLAG_ON):
469 from tools import models as _models_mod # noqa: E402
471 _importlib.reload(_models_mod)
472 for _name in ("delete_model", "models_upload"):
473 if hasattr(_models_mod, _name):
474 globals()[_name] = getattr(_models_mod, _name)
476if _IS_RELOAD and (
477 _MODEL_UPLOAD_FLAG_ON or _feature_flags.is_enabled(_feature_flags.FLAG_LOCAL_STORAGE_SYNC)
478):
479 from tools import storage as _storage_mod # noqa: E402
481 _importlib.reload(_storage_mod)
482 for _name in ("upload_to_regional_bucket", "sync_storage_bucket"):
483 if hasattr(_storage_mod, _name):
484 globals()[_name] = getattr(_storage_mod, _name)
486if _IS_RELOAD and _feature_flags.is_enabled(_feature_flags.FLAG_LOCAL_METRICS):
487 from tools import metrics as _metrics_mod # noqa: E402
489 _importlib.reload(_metrics_mod)
490 if hasattr(_metrics_mod, "metrics_from_local_file"): 490 ↛ 493line 490 didn't jump to line 493 because the condition on line 490 was always true
491 metrics_from_local_file = _metrics_mod.metrics_from_local_file
493if _IS_RELOAD and _feature_flags.is_enabled(_feature_flags.FLAG_SEMANTIC_PROGRESS):
494 from tools import semantic_progress as _semantic_progress_mod # noqa: E402
496 _importlib.reload(_semantic_progress_mod)
497 if hasattr(_semantic_progress_mod, "metrics_semantic_progress"): 497 ↛ 500line 497 didn't jump to line 500 because the condition on line 497 was always true
498 metrics_semantic_progress = _semantic_progress_mod.metrics_semantic_progress
500if _IS_RELOAD and _feature_flags.is_enabled(_feature_flags.FLAG_MISSION):
501 from tools import mission as _mission_tools_mod # noqa: E402
503 _importlib.reload(_mission_tools_mod)
504 for _name in (
505 "mission_start",
506 "mission_status",
507 "mission_iterate",
508 "mission_checkpoint",
509 "mission_complete",
510 "mission_abort",
511 "mission_resume",
512 "mission_history",
513 "mission_list",
514 ):
515 if hasattr(_mission_tools_mod, _name): 515 ↛ 504line 515 didn't jump to line 504 because the condition on line 515 was always true
516 globals()[_name] = getattr(_mission_tools_mod, _name)
518# --- Re-export resource directory constants for tests ---
519from resources.ci import ( # noqa: E402, F401
520 GITHUB_ACTIONS_DIR,
521 GITHUB_CODEQL_DIR,
522 GITHUB_DIR,
523 GITHUB_ISSUE_TEMPLATE_DIR,
524 GITHUB_KIND_DIR,
525 GITHUB_SCRIPTS_DIR,
526 GITHUB_WORKFLOWS_DIR,
527)
528from resources.docs import DOCS_DIR, EXAMPLES_DIR # noqa: E402, F401
529from resources.infra import DOCKERFILES_DIR, HELM_CHARTS_FILE # noqa: E402, F401
530from resources.k8s import MANIFESTS_DIR # noqa: E402, F401
531from resources.self import _TOOL_GATING_TABLE # noqa: E402
533# Declare every candidate name that is intentionally re-exported for tests and
534# downstream consumers. The final ``__all__`` below filters gated names against
535# both the current environment and actual module globals, so ``from run_mcp
536# import *`` never advertises an unavailable attribute.
537_PUBLIC_EXPORTS = [
538 "DOCKERFILES_DIR",
539 "DOCS_DIR",
540 "EXAMPLES_DIR",
541 "GITHUB_ACTIONS_DIR",
542 "GITHUB_CODEQL_DIR",
543 "GITHUB_DIR",
544 "GITHUB_ISSUE_TEMPLATE_DIR",
545 "GITHUB_KIND_DIR",
546 "GITHUB_SCRIPTS_DIR",
547 "GITHUB_WORKFLOWS_DIR",
548 "HELM_CHARTS_FILE",
549 "MANIFESTS_DIR",
550 "_MCP_SERVER_VERSION",
551 "_PROJECT_VERSION",
552 "_sanitize_arguments",
553 "addons_install",
554 "addons_status",
555 "ai_recommend",
556 "analytics_doctor",
557 "analytics_login_url",
558 "analytics_status",
559 "analytics_user_add",
560 "analytics_user_remove",
561 "analytics_users_list",
562 "assume_mcp_role",
563 "audit_logged",
564 "audit_logger",
565 "aurora_status",
566 "bootstrap_cdk",
567 "canary_deploy",
568 "cancel_queue_job",
569 "cancel_reservation",
570 "capacity_history_patterns",
571 "capacity_history_show",
572 "capacity_history_stats",
573 "capacity_predict",
574 "capacity_status",
575 "chat_inference",
576 "check_capacity",
577 "cluster_health",
578 "cluster_tunnel_command",
579 "config_get",
580 "configure_mooncake_store",
581 "cost_allocation_activate",
582 "cost_allocation_status",
583 "cost_by_region",
584 "cost_forecast",
585 "cost_k8s_namespaces",
586 "cost_k8s_regions",
587 "cost_k8s_top",
588 "cost_k8s_trend",
589 "cost_report_generate",
590 "cost_report_list",
591 "cost_report_status",
592 "cost_summary",
593 "cost_trend",
594 "cost_workloads",
595 "create_reservation",
596 "dag_run",
597 "dag_validate",
598 "delete_inference",
599 "delete_job",
600 "delete_model",
601 "delete_nodepool",
602 "delete_template",
603 "delete_webhook",
604 "deploy_all",
605 "deploy_disaggregated_inference",
606 "deploy_inference",
607 "deploy_stack",
608 "destroy_all",
609 "destroy_stack",
610 "disable_analytics",
611 "disable_aurora",
612 "disable_fsx",
613 "disable_monitoring",
614 "disable_valkey",
615 "emit_startup_log",
616 "enable_analytics",
617 "enable_aurora",
618 "enable_fsx",
619 "enable_monitoring",
620 "enable_valkey",
621 "files_access_points",
622 "files_get",
623 "find_capacity_blocks",
624 "find_capacity_reservations",
625 "find_docs",
626 "find_examples",
627 "fsx_status",
628 "get_job",
629 "get_job_events",
630 "get_job_logs",
631 "get_job_metrics",
632 "get_job_pods",
633 "get_model_uri",
634 "get_pod_logs",
635 "get_project_version",
636 "images_build",
637 "images_cleanup",
638 "images_delete_repo",
639 "images_delete_tag",
640 "images_describe",
641 "images_init",
642 "images_lifecycle_get",
643 "images_lifecycle_set",
644 "images_list",
645 "images_mirror",
646 "images_mirror_plan",
647 "images_mirror_status",
648 "images_orphans",
649 "images_prune",
650 "images_push",
651 "images_replication_get",
652 "images_replication_status",
653 "images_replication_sync",
654 "images_tags",
655 "images_uri",
656 "inference_health",
657 "inference_status",
658 "instance_info",
659 "invoke_inference",
660 "list_endpoint_models",
661 "list_file_systems",
662 "list_inference_endpoints",
663 "list_jobs",
664 "list_models",
665 "list_reservations",
666 "list_stacks",
667 "list_storage_buckets",
668 "list_storage_contents",
669 "mcp",
670 "metrics_cloudwatch_get",
671 "metrics_from_job_logs",
672 "metrics_from_local_file",
673 "metrics_from_shared_storage_file",
674 "metrics_semantic_progress",
675 "mission_abort",
676 "mission_checkpoint",
677 "mission_complete",
678 "mission_history",
679 "mission_iterate",
680 "mission_list",
681 "mission_resume",
682 "mission_start",
683 "mission_status",
684 "models_upload",
685 "monitoring_status",
686 "monitoring_user_add",
687 "monitoring_user_remove",
688 "monitoring_users_list",
689 "mooncake_topology_status",
690 "nodepools_create_capacity_block",
691 "nodepools_create_odcr",
692 "nodepools_describe",
693 "nodepools_list",
694 "populate_kv_cache",
695 "promote_canary",
696 "queue_get",
697 "queue_list",
698 "queue_stats",
699 "queue_status",
700 "queue_submit",
701 "recommend_capacity",
702 "recommend_region",
703 "reservation_check",
704 "reserve_capacity",
705 "retry_job",
706 "rollback_canary",
707 "scale_inference",
708 "set_mooncake_topology",
709 "setup_cluster_access",
710 "spot_prices",
711 "stack_diff",
712 "stack_outputs",
713 "stack_status",
714 "stack_synth",
715 "start_inference",
716 "stop_inference",
717 "submit_job_api",
718 "submit_job_sqs",
719 "sync_storage_bucket",
720 "task_prune",
721 "task_status",
722 "task_tail",
723 "templates_create",
724 "templates_get",
725 "templates_list",
726 "templates_run",
727 "update_inference_image",
728 "upload_to_regional_bucket",
729 "valkey_status",
730 "webhooks_create",
731 "webhooks_get",
732 "webhooks_list",
733]
735__all__ = [
736 name
737 for name in _PUBLIC_EXPORTS
738 if name in globals()
739 and (name not in _TOOL_GATING_TABLE or _feature_flags.is_enabled(_TOOL_GATING_TABLE[name]))
740]
742# =============================================================================
743# ENTRYPOINT
744# =============================================================================
747def _initialize_runtime() -> None:
748 """Perform external startup effects exactly once per process invocation.
750 Importing ``run_mcp`` is now safe for documentation tooling and tests: it
751 does not emit a startup audit record or mutate the ambient boto3 session by
752 assuming a role. Those effects happen only when the server is actually run.
753 """
754 emit_startup_log()
755 assume_mcp_role()
758def main() -> None:
759 """Start the MCP server after applying runtime identity and audit setup."""
760 _initialize_runtime()
761 mcp.run()
764# Set only after registration/re-export initialization has completed. Python's
765# reload machinery preserves this sentinel in the module dictionary.
766_RUN_MCP_IMPORT_COMPLETE = True
769if __name__ == "__main__":
770 main()