Skip to main content

soma_mcp_client/upstream/pool/
prompts.rs

1use crate::upstream::{CapScope, PromptDescriptor, UpstreamError};
2
3use super::tools::matches_filter;
4
5impl super::UpstreamPool {
6    pub async fn list_prompts(
7        &self,
8        upstream: &str,
9    ) -> Result<Vec<PromptDescriptor>, UpstreamError> {
10        self.ensure_connected(upstream).await?;
11        self.with_entry(upstream, |entry| {
12            if !entry.config.proxy_prompts {
13                return Ok(Vec::new());
14            }
15            let prompts: Vec<PromptDescriptor> = entry
16                .snapshot
17                .prompts
18                .iter()
19                .filter(|prompt| {
20                    matches_filter(entry.config.expose_prompts.as_deref(), &prompt.name)
21                })
22                .cloned()
23                .collect();
24            let bytes = serde_json::to_vec(&prompts).map_or(usize::MAX, |bytes| bytes.len());
25            self.response_caps().enforce(CapScope::PromptsList, bytes)?;
26            Ok(prompts)
27        })
28    }
29
30    pub async fn get_prompt(
31        &self,
32        upstream: &str,
33        name: &str,
34        arguments: Option<serde_json::Map<String, serde_json::Value>>,
35    ) -> Result<serde_json::Value, UpstreamError> {
36        self.ensure_connected(upstream).await?;
37        let peer =
38            self.with_entry(upstream, |entry| {
39                if !entry.config.proxy_prompts {
40                    return Err(UpstreamError::Unsupported {
41                        upstream: upstream.to_owned(),
42                        capability: "prompts/get",
43                    });
44                }
45                entry.live.as_ref().map(|live| live.peer()).ok_or_else(|| {
46                    UpstreamError::Unsupported {
47                        upstream: upstream.to_owned(),
48                        capability: "prompts/get",
49                    }
50                })
51            })?;
52        let value =
53            super::live::get_live_prompt(upstream, peer, name.to_owned(), arguments).await?;
54        let bytes = serde_json::to_vec(&value).map_or(usize::MAX, |bytes| bytes.len());
55        self.response_caps().enforce(CapScope::PromptsGet, bytes)?;
56        Ok(value)
57    }
58}
59
60#[cfg(test)]
61#[path = "prompts_tests.rs"]
62mod tests;