Files
ITWorx_MCP_Hub-Public/services/runtime/connector_mobilityops.py
T

97 lines
3.4 KiB
Python

from __future__ import annotations
from typing import Any
from mcp.server.mcpserver import MCPServer
from mcp.server.mcpserver.context import Context
from connectors.mobilityops import MobilityOpsConnector
from packages.connector_kit import (
DEFAULT_KNOWLEDGE_LOCALE,
ConnectorContext,
MobilityOpsClient,
MobilityOpsFileTokenProvider,
MobilityOpsSettings,
)
from .common import (
connector_context,
load_connector_identity_key,
load_json_environment,
request_headers,
)
from .mcp_server import add_operational_routes, add_workflow_prompts, run_mcp
def build_connector() -> tuple[MobilityOpsConnector, set[str]]:
import os
raw = load_json_environment("MOBILITYOPS_PROJECTS_JSON", list)
projects = {str(item).strip().lower() for item in raw if str(item).strip()}
if not projects:
raise ValueError("at least one project must be registered for the MobilityOps connector")
settings = MobilityOpsSettings(
base_url=os.environ["MOBILITYOPS_ENDPOINT"],
token_reference=os.environ.get(
"MOBILITYOPS_SERVICE_TOKEN_FILE", "/run/secrets/mobilityops_service_token"
),
)
client = MobilityOpsClient(settings, MobilityOpsFileTokenProvider())
return MobilityOpsConnector(client), projects
def build_server() -> MCPServer[Any]:
connector, projects = build_connector()
signing_key = load_connector_identity_key()
server: MCPServer[Any] = MCPServer(
"itworx-mobilityops",
title="Fleet Ops read-only connector",
version="1.0.0",
instructions=(
"Only read-only Fleet Ops operational and knowledge tools are available. Start "
"with the operations summary, narrow attention and vehicle reads, and require "
"grounded knowledge citations before recommending an operational action."
),
)
add_operational_routes(server, "mobilityops-connector", readiness=connector.readiness)
add_workflow_prompts(server, "mobilityops")
def current(context: Context[Any, Any]) -> ConnectorContext:
return connector_context(request_headers(context), projects, signing_key=signing_key)
@server.tool(name="mobilityops.operations.summary", structured_output=True)
async def operations_summary(context: Context[Any, Any]) -> dict[str, Any]:
return connector.operations_summary(current(context))
@server.tool(name="mobilityops.attention.list", structured_output=True)
async def attention_list(
context: Context[Any, Any],
minimum_severity: str = "medium",
date: str | None = None,
limit: int = 20,
) -> dict[str, Any]:
return connector.attention_list(
current(context), minimum_severity=minimum_severity, date=date, limit=limit
)
@server.tool(name="mobilityops.vehicle.get", structured_output=True)
async def vehicle_get(vehicleRef: str, context: Context[Any, Any]) -> dict[str, Any]:
return connector.vehicle_get(current(context), vehicleRef)
@server.tool(name="mobilityops.knowledge.search", structured_output=True)
async def knowledge_search(
question: str,
context: Context[Any, Any],
max_sources: int = 4,
locale: str = DEFAULT_KNOWLEDGE_LOCALE,
) -> dict[str, Any]:
return connector.knowledge_search(
current(context), question, max_sources=max_sources, locale=locale
)
return server
def run() -> None:
run_mcp(build_server())