systemprompt-mcp 0.10.0

Native Model Context Protocol (MCP) implementation for systemprompt.io. Orchestration, per-server OAuth2, RBAC middleware, and tool-call governance — the core of the AI governance pipeline.
Documentation
//! Domain models for MCP — sessions, artifacts, validation results, etc.

use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use sqlx::FromRow;
use systemprompt_identifiers::{AiToolCallId, ContextId, McpExecutionId, UserId};
use uuid::Uuid;

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ExecutionStatus {
    Pending,
    Success,
    Failed,
}

impl ExecutionStatus {
    pub const fn as_str(&self) -> &'static str {
        match self {
            Self::Pending => "pending",
            Self::Success => "success",
            Self::Failed => "failed",
        }
    }

    pub const fn from_error(has_error: bool) -> Self {
        if has_error {
            Self::Failed
        } else {
            Self::Success
        }
    }
}

impl std::fmt::Display for ExecutionStatus {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", self.as_str())
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ValidationResultType {
    AuthRequired,
    PortUnavailable,
    ConnectionFailed,
    Timeout,
    Success,
    Error,
}

impl ValidationResultType {
    pub const fn as_str(&self) -> &'static str {
        match self {
            Self::AuthRequired => "auth_required",
            Self::PortUnavailable => "port_unavailable",
            Self::ConnectionFailed => "connection_failed",
            Self::Timeout => "timeout",
            Self::Success => "success",
            Self::Error => "error",
        }
    }

    pub fn parse(s: &str) -> Self {
        match s {
            "auth_required" => Self::AuthRequired,
            "port_unavailable" => Self::PortUnavailable,
            "connection_failed" => Self::ConnectionFailed,
            "timeout" => Self::Timeout,
            "success" => Self::Success,
            _ => Self::Error,
        }
    }
}

impl std::fmt::Display for ValidationResultType {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", self.as_str())
    }
}

#[derive(Debug, Clone)]
pub struct ToolExecutionRequest {
    pub tool_name: String,
    pub server_name: String,
    pub input: serde_json::Value,
    pub started_at: DateTime<Utc>,
    pub context: systemprompt_models::RequestContext,
    pub request_method: Option<String>,
    pub request_source: Option<String>,
    pub ai_tool_call_id: Option<AiToolCallId>,
}

#[derive(Debug, Clone)]
pub struct ToolExecutionResult {
    pub output: Option<serde_json::Value>,
    pub output_schema: Option<serde_json::Value>,
    pub status: String,
    pub error_message: Option<String>,
    pub started_at: DateTime<Utc>,
    pub completed_at: DateTime<Utc>,
}

#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
pub struct MCPService {
    pub id: Uuid,
    pub name: String,
    pub module: String,
    pub port: i32,
    pub pid: Option<i32>,
    pub status: String,
    pub health: String,
    pub restart_count: i32,
    pub last_health_check: Option<DateTime<Utc>>,
    pub created_at: DateTime<Utc>,
    pub updated_at: DateTime<Utc>,
}

const HEALTHY: &str = "healthy";

impl MCPService {
    pub fn is_running(&self) -> bool {
        self.status == crate::RUNNING
    }

    pub fn is_healthy(&self) -> bool {
        self.health == HEALTHY
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ToolExecution {
    pub mcp_execution_id: McpExecutionId,
    pub tool_name: String,
    pub server_name: String,
    pub context_id: Option<ContextId>,
    pub ai_tool_call_id: Option<AiToolCallId>,
    pub user_id: UserId,
    pub status: String,
    pub input: String,
    pub output: Option<String>,
    pub error_message: Option<String>,
    pub execution_time_ms: Option<i32>,
    pub started_at: DateTime<Utc>,
    pub completed_at: Option<DateTime<Utc>>,
}

#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
pub struct ToolStats {
    pub tool_name: String,
    pub server_name: String,
    pub total_executions: i64,
    pub success_count: i64,
    pub error_count: i64,
    pub avg_duration_ms: Option<i64>,
    pub min_duration_ms: Option<i64>,
    pub max_duration_ms: Option<i64>,
}