1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
// SPDX-FileCopyrightText: 2026 Andrei G <bug-ops>
// SPDX-License-Identifier: MIT OR Apache-2.0
//! MCP client lifecycle, multi-server management, and Qdrant tool registry.
//!
//! `zeph-mcp` implements the [Model Context Protocol](https://spec.modelcontextprotocol.io/)
//! client for Zeph. It manages connections to multiple MCP servers simultaneously,
//! discovers and registers their tools, and executes tool calls with a layered security
//! pipeline.
//!
//! # Architecture
//!
//! ```text
//! McpManager ──► McpClient (one per server, via rmcp)
//! │ └── ToolListChangedHandler (refresh notifications)
//! │
//! ├── PolicyEnforcer (allowlists, denylists, rate limiting)
//! ├── DefaultMcpProber (pre-connect resource/prompt injection scan)
//! ├── TrustScoreStore (per-server persistent score with decay)
//! ├── EmbeddingAnomalyGuard (post-call drift detection)
//! └── sanitize_tools() (always-on prompt injection scrubbing)
//!
//! McpToolExecutor ──► McpManager::call_tool()
//! implements ToolExecutor for zeph-tools dispatch
//!
//! McpToolRegistry ──► Qdrant (vector search for tool discovery)
//! SemanticToolIndex ──► in-memory cosine similarity (fast, no Qdrant)
//! ```
//!
//! # Transport types
//!
//! Servers are connected via three transport types (see [`McpTransport`]):
//!
//! - **Stdio** — spawns a child process; suitable for local MCP servers (e.g. `npx`, `uvx`).
//! - **Http** — streamable HTTP with optional static headers.
//! - **OAuth** — OAuth 2.1 authenticated HTTP; performs a browser-based authorization flow.
//!
//! # Security pipeline
//!
//! Every tool definition goes through the following checks before reaching the agent:
//!
//! 1. **Command allowlist** (`security.rs`) — Stdio server commands must be on the allowlist.
//! 2. **SSRF validation** — HTTP URLs are resolved and blocked if they point to private/reserved IPs.
//! 3. **Pre-connect probing** (`prober.rs`) — scans `resources/list` and `prompts/list` for
//! injection patterns; updates the persistent trust score.
//! 4. **Attestation** (`attestation.rs`) — compares the actual tool set against the operator's
//! `expected_tools` list and detects schema drift between connections.
//! 5. **Sanitization** (`sanitize.rs`) — scrubs tool `name`, `description`, and `input_schema`
//! for prompt injection patterns; always on, cannot be disabled.
//! 6. **Data-flow policy** (`policy.rs`) — blocks high-sensitivity tools on untrusted servers.
//! 7. **Embedding anomaly guard** (`embedding_guard.rs`) — post-call drift detection.
//!
//! # Trust levels
//!
//! Each server is assigned a [`McpTrustLevel`]:
//!
//! - `Trusted` — SSRF skip, all tools exposed (operator-controlled servers).
//! - `Untrusted` (default) — SSRF enforced; tools shown with a warning when allowlist is absent.
//! - `Sandboxed` — strict mode; only allowlisted tools exposed; elicitation disabled.
//!
//! # Examples
//!
//! Connect to an stdio MCP server and call a tool:
//!
//! ```no_run
//! use std::collections::HashMap;
//! use std::sync::Arc;
//! use std::time::Duration;
//!
//! use zeph_mcp::{McpManager, McpTransport, ServerEntry, McpTrustLevel};
//! use zeph_mcp::policy::PolicyEnforcer;
//!
//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
//! let server = ServerEntry {
//! id: "filesystem".to_owned(),
//! transport: McpTransport::Stdio {
//! command: "npx".to_owned(),
//! args: vec!["-y".to_owned(), "@modelcontextprotocol/server-filesystem".to_owned()],
//! env: HashMap::new(),
//! },
//! timeout: Duration::from_secs(30),
//! trust_level: McpTrustLevel::Untrusted,
//! tool_allowlist: None,
//! expected_tools: vec![],
//! roots: vec![],
//! tool_metadata: HashMap::new(),
//! elicitation_enabled: false,
//! elicitation_timeout_secs: 120,
//! env_isolation: false,
//! };
//!
//! let manager = McpManager::new(
//! vec![server],
//! vec!["npx".to_owned()],
//! PolicyEnforcer::new(vec![]),
//! );
//!
//! let (tools, _outcomes) = manager.connect_all().await;
//! println!("Connected {} tools", tools.len());
//! # Ok(())
//! # }
//! ```
pub use sql;
pub use ;
pub use McpCaller;
pub use ;
pub use ElicitationEvent;
pub use ;
pub use ;
pub use McpToolExecutor;
pub use ;
pub use ;
pub use ;
pub use ;
pub use format_mcp_tools_prompt;
pub use ;
pub use McpToolRegistry;
pub use SanitizeResult;
pub use ;
pub use ;
pub use ;