types.rs

  1use collections::HashMap;
  2use serde::{Deserialize, Serialize};
  3use url::Url;
  4
  5pub const LATEST_PROTOCOL_VERSION: &str = "2024-11-05";
  6
  7pub enum RequestType {
  8    Initialize,
  9    CallTool,
 10    ResourcesUnsubscribe,
 11    ResourcesSubscribe,
 12    ResourcesRead,
 13    ResourcesList,
 14    LoggingSetLevel,
 15    PromptsGet,
 16    PromptsList,
 17    CompletionComplete,
 18    Ping,
 19    ListTools,
 20    ListResourceTemplates,
 21    ListRoots,
 22}
 23
 24impl RequestType {
 25    pub fn as_str(&self) -> &'static str {
 26        match self {
 27            RequestType::Initialize => "initialize",
 28            RequestType::CallTool => "tools/call",
 29            RequestType::ResourcesUnsubscribe => "resources/unsubscribe",
 30            RequestType::ResourcesSubscribe => "resources/subscribe",
 31            RequestType::ResourcesRead => "resources/read",
 32            RequestType::ResourcesList => "resources/list",
 33            RequestType::LoggingSetLevel => "logging/setLevel",
 34            RequestType::PromptsGet => "prompts/get",
 35            RequestType::PromptsList => "prompts/list",
 36            RequestType::CompletionComplete => "completion/complete",
 37            RequestType::Ping => "ping",
 38            RequestType::ListTools => "tools/list",
 39            RequestType::ListResourceTemplates => "resources/templates/list",
 40            RequestType::ListRoots => "roots/list",
 41        }
 42    }
 43}
 44
 45#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
 46#[serde(transparent)]
 47pub struct ProtocolVersion(pub String);
 48
 49#[derive(Debug, Serialize)]
 50#[serde(rename_all = "camelCase")]
 51pub struct InitializeParams {
 52    pub protocol_version: ProtocolVersion,
 53    pub capabilities: ClientCapabilities,
 54    pub client_info: Implementation,
 55    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
 56    pub meta: Option<HashMap<String, serde_json::Value>>,
 57}
 58
 59#[derive(Debug, Serialize)]
 60#[serde(rename_all = "camelCase")]
 61pub struct CallToolParams {
 62    pub name: String,
 63    #[serde(skip_serializing_if = "Option::is_none")]
 64    pub arguments: Option<HashMap<String, serde_json::Value>>,
 65    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
 66    pub meta: Option<HashMap<String, serde_json::Value>>,
 67}
 68
 69#[derive(Debug, Serialize)]
 70#[serde(rename_all = "camelCase")]
 71pub struct ResourcesUnsubscribeParams {
 72    pub uri: Url,
 73    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
 74    pub meta: Option<HashMap<String, serde_json::Value>>,
 75}
 76
 77#[derive(Debug, Serialize)]
 78#[serde(rename_all = "camelCase")]
 79pub struct ResourcesSubscribeParams {
 80    pub uri: Url,
 81    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
 82    pub meta: Option<HashMap<String, serde_json::Value>>,
 83}
 84
 85#[derive(Debug, Serialize)]
 86#[serde(rename_all = "camelCase")]
 87pub struct ResourcesReadParams {
 88    pub uri: Url,
 89    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
 90    pub meta: Option<HashMap<String, serde_json::Value>>,
 91}
 92
 93#[derive(Debug, Serialize)]
 94#[serde(rename_all = "camelCase")]
 95pub struct LoggingSetLevelParams {
 96    pub level: LoggingLevel,
 97    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
 98    pub meta: Option<HashMap<String, serde_json::Value>>,
 99}
100
101#[derive(Debug, Serialize)]
102#[serde(rename_all = "camelCase")]
103pub struct PromptsGetParams {
104    pub name: String,
105    #[serde(skip_serializing_if = "Option::is_none")]
106    pub arguments: Option<HashMap<String, String>>,
107    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
108    pub meta: Option<HashMap<String, serde_json::Value>>,
109}
110
111#[derive(Debug, Serialize)]
112#[serde(rename_all = "camelCase")]
113pub struct CompletionCompleteParams {
114    pub r#ref: CompletionReference,
115    pub argument: CompletionArgument,
116    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
117    pub meta: Option<HashMap<String, serde_json::Value>>,
118}
119
120#[derive(Debug, Serialize)]
121#[serde(untagged)]
122pub enum CompletionReference {
123    Prompt(PromptReference),
124    Resource(ResourceReference),
125}
126
127#[derive(Debug, Serialize)]
128#[serde(rename_all = "camelCase")]
129pub struct PromptReference {
130    pub r#type: PromptReferenceType,
131    pub name: String,
132}
133
134#[derive(Debug, Serialize)]
135#[serde(rename_all = "camelCase")]
136pub struct ResourceReference {
137    pub r#type: PromptReferenceType,
138    pub uri: Url,
139}
140
141#[derive(Debug, Serialize)]
142#[serde(rename_all = "snake_case")]
143pub enum PromptReferenceType {
144    #[serde(rename = "ref/prompt")]
145    Prompt,
146    #[serde(rename = "ref/resource")]
147    Resource,
148}
149
150#[derive(Debug, Serialize)]
151#[serde(rename_all = "camelCase")]
152pub struct CompletionArgument {
153    pub name: String,
154    pub value: String,
155}
156
157#[derive(Debug, Deserialize)]
158#[serde(rename_all = "camelCase")]
159pub struct InitializeResponse {
160    pub protocol_version: ProtocolVersion,
161    pub capabilities: ServerCapabilities,
162    pub server_info: Implementation,
163    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
164    pub meta: Option<HashMap<String, serde_json::Value>>,
165}
166
167#[derive(Debug, Deserialize)]
168#[serde(rename_all = "camelCase")]
169pub struct ResourcesReadResponse {
170    pub contents: Vec<ResourceContentsType>,
171    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
172    pub meta: Option<HashMap<String, serde_json::Value>>,
173}
174
175#[derive(Debug, Deserialize)]
176#[serde(untagged)]
177pub enum ResourceContentsType {
178    Text(TextResourceContents),
179    Blob(BlobResourceContents),
180}
181
182#[derive(Debug, Deserialize)]
183#[serde(rename_all = "camelCase")]
184pub struct ResourcesListResponse {
185    pub resources: Vec<Resource>,
186    #[serde(skip_serializing_if = "Option::is_none")]
187    pub next_cursor: Option<String>,
188    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
189    pub meta: Option<HashMap<String, serde_json::Value>>,
190}
191
192#[derive(Debug, Serialize, Deserialize)]
193#[serde(rename_all = "camelCase")]
194pub struct SamplingMessage {
195    pub role: Role,
196    pub content: MessageContent,
197}
198
199#[derive(Debug, Serialize)]
200#[serde(rename_all = "camelCase")]
201pub struct CreateMessageRequest {
202    pub messages: Vec<SamplingMessage>,
203    #[serde(skip_serializing_if = "Option::is_none")]
204    pub model_preferences: Option<ModelPreferences>,
205    #[serde(skip_serializing_if = "Option::is_none")]
206    pub system_prompt: Option<String>,
207    #[serde(skip_serializing_if = "Option::is_none")]
208    pub include_context: Option<String>,
209    #[serde(skip_serializing_if = "Option::is_none")]
210    pub temperature: Option<f64>,
211    pub max_tokens: u32,
212    #[serde(skip_serializing_if = "Option::is_none")]
213    pub stop_sequences: Option<Vec<String>>,
214    #[serde(skip_serializing_if = "Option::is_none")]
215    pub metadata: Option<serde_json::Value>,
216}
217
218#[derive(Debug, Deserialize)]
219#[serde(rename_all = "camelCase")]
220pub struct CreateMessageResult {
221    pub role: Role,
222    pub content: MessageContent,
223    pub model: String,
224    #[serde(skip_serializing_if = "Option::is_none")]
225    pub stop_reason: Option<String>,
226}
227
228#[derive(Debug, Serialize, Deserialize)]
229#[serde(rename_all = "camelCase")]
230pub struct PromptMessage {
231    pub role: Role,
232    pub content: MessageContent,
233}
234
235#[derive(Debug, Serialize, Deserialize)]
236#[serde(rename_all = "lowercase")]
237pub enum Role {
238    User,
239    Assistant,
240}
241
242#[derive(Debug, Serialize, Deserialize)]
243#[serde(tag = "type")]
244pub enum MessageContent {
245    #[serde(rename = "text")]
246    Text {
247        text: String,
248        #[serde(skip_serializing_if = "Option::is_none")]
249        annotations: Option<MessageAnnotations>,
250    },
251    #[serde(rename = "image")]
252    Image {
253        data: String,
254        mime_type: String,
255        #[serde(skip_serializing_if = "Option::is_none")]
256        annotations: Option<MessageAnnotations>,
257    },
258    #[serde(rename = "resource")]
259    Resource {
260        resource: ResourceContents,
261        #[serde(skip_serializing_if = "Option::is_none")]
262        annotations: Option<MessageAnnotations>,
263    },
264}
265
266#[derive(Debug, Serialize, Deserialize)]
267#[serde(rename_all = "camelCase")]
268pub struct MessageAnnotations {
269    #[serde(skip_serializing_if = "Option::is_none")]
270    pub audience: Option<Vec<Role>>,
271    #[serde(skip_serializing_if = "Option::is_none")]
272    pub priority: Option<f64>,
273}
274
275#[derive(Debug, Deserialize)]
276#[serde(rename_all = "camelCase")]
277pub struct PromptsGetResponse {
278    #[serde(skip_serializing_if = "Option::is_none")]
279    pub description: Option<String>,
280    pub messages: Vec<PromptMessage>,
281    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
282    pub meta: Option<HashMap<String, serde_json::Value>>,
283}
284
285#[derive(Debug, Deserialize)]
286#[serde(rename_all = "camelCase")]
287pub struct PromptsListResponse {
288    pub prompts: Vec<Prompt>,
289    #[serde(skip_serializing_if = "Option::is_none")]
290    pub next_cursor: Option<String>,
291    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
292    pub meta: Option<HashMap<String, serde_json::Value>>,
293}
294
295#[derive(Debug, Deserialize)]
296#[serde(rename_all = "camelCase")]
297pub struct CompletionCompleteResponse {
298    pub completion: CompletionResult,
299    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
300    pub meta: Option<HashMap<String, serde_json::Value>>,
301}
302
303#[derive(Debug, Deserialize)]
304#[serde(rename_all = "camelCase")]
305pub struct CompletionResult {
306    pub values: Vec<String>,
307    #[serde(skip_serializing_if = "Option::is_none")]
308    pub total: Option<u32>,
309    #[serde(skip_serializing_if = "Option::is_none")]
310    pub has_more: Option<bool>,
311    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
312    pub meta: Option<HashMap<String, serde_json::Value>>,
313}
314
315#[derive(Debug, Deserialize, Serialize)]
316#[serde(rename_all = "camelCase")]
317pub struct Prompt {
318    pub name: String,
319    #[serde(skip_serializing_if = "Option::is_none")]
320    pub description: Option<String>,
321    #[serde(skip_serializing_if = "Option::is_none")]
322    pub arguments: Option<Vec<PromptArgument>>,
323}
324
325#[derive(Debug, Deserialize, Serialize)]
326#[serde(rename_all = "camelCase")]
327pub struct PromptArgument {
328    pub name: String,
329    #[serde(skip_serializing_if = "Option::is_none")]
330    pub description: Option<String>,
331    #[serde(skip_serializing_if = "Option::is_none")]
332    pub required: Option<bool>,
333}
334
335#[derive(Debug, Serialize, Deserialize)]
336#[serde(rename_all = "camelCase")]
337pub struct ClientCapabilities {
338    #[serde(skip_serializing_if = "Option::is_none")]
339    pub experimental: Option<HashMap<String, serde_json::Value>>,
340    #[serde(skip_serializing_if = "Option::is_none")]
341    pub sampling: Option<serde_json::Value>,
342    #[serde(skip_serializing_if = "Option::is_none")]
343    pub roots: Option<RootsCapabilities>,
344}
345
346#[derive(Debug, Serialize, Deserialize)]
347#[serde(rename_all = "camelCase")]
348pub struct ServerCapabilities {
349    #[serde(skip_serializing_if = "Option::is_none")]
350    pub experimental: Option<HashMap<String, serde_json::Value>>,
351    #[serde(skip_serializing_if = "Option::is_none")]
352    pub logging: Option<serde_json::Value>,
353    #[serde(skip_serializing_if = "Option::is_none")]
354    pub prompts: Option<PromptsCapabilities>,
355    #[serde(skip_serializing_if = "Option::is_none")]
356    pub resources: Option<ResourcesCapabilities>,
357    #[serde(skip_serializing_if = "Option::is_none")]
358    pub tools: Option<ToolsCapabilities>,
359}
360
361#[derive(Debug, Serialize, Deserialize)]
362#[serde(rename_all = "camelCase")]
363pub struct PromptsCapabilities {
364    #[serde(skip_serializing_if = "Option::is_none")]
365    pub list_changed: Option<bool>,
366}
367
368#[derive(Debug, Serialize, Deserialize)]
369#[serde(rename_all = "camelCase")]
370pub struct ResourcesCapabilities {
371    #[serde(skip_serializing_if = "Option::is_none")]
372    pub subscribe: Option<bool>,
373    #[serde(skip_serializing_if = "Option::is_none")]
374    pub list_changed: Option<bool>,
375}
376
377#[derive(Debug, Serialize, Deserialize)]
378#[serde(rename_all = "camelCase")]
379pub struct ToolsCapabilities {
380    #[serde(skip_serializing_if = "Option::is_none")]
381    pub list_changed: Option<bool>,
382}
383
384#[derive(Debug, Serialize, Deserialize)]
385#[serde(rename_all = "camelCase")]
386pub struct RootsCapabilities {
387    #[serde(skip_serializing_if = "Option::is_none")]
388    pub list_changed: Option<bool>,
389}
390
391#[derive(Debug, Serialize, Deserialize)]
392#[serde(rename_all = "camelCase")]
393pub struct Tool {
394    pub name: String,
395    #[serde(skip_serializing_if = "Option::is_none")]
396    pub description: Option<String>,
397    pub input_schema: serde_json::Value,
398}
399
400#[derive(Debug, Serialize, Deserialize)]
401#[serde(rename_all = "camelCase")]
402pub struct Implementation {
403    pub name: String,
404    pub version: String,
405}
406
407#[derive(Debug, Serialize, Deserialize)]
408#[serde(rename_all = "camelCase")]
409pub struct Resource {
410    pub uri: Url,
411    pub name: String,
412    #[serde(skip_serializing_if = "Option::is_none")]
413    pub description: Option<String>,
414    #[serde(skip_serializing_if = "Option::is_none")]
415    pub mime_type: Option<String>,
416}
417
418#[derive(Debug, Serialize, Deserialize)]
419#[serde(rename_all = "camelCase")]
420pub struct ResourceContents {
421    pub uri: Url,
422    #[serde(skip_serializing_if = "Option::is_none")]
423    pub mime_type: Option<String>,
424}
425
426#[derive(Debug, Serialize, Deserialize)]
427#[serde(rename_all = "camelCase")]
428pub struct TextResourceContents {
429    pub uri: Url,
430    #[serde(skip_serializing_if = "Option::is_none")]
431    pub mime_type: Option<String>,
432    pub text: String,
433}
434
435#[derive(Debug, Serialize, Deserialize)]
436#[serde(rename_all = "camelCase")]
437pub struct BlobResourceContents {
438    pub uri: Url,
439    #[serde(skip_serializing_if = "Option::is_none")]
440    pub mime_type: Option<String>,
441    pub blob: String,
442}
443
444#[derive(Debug, Serialize, Deserialize)]
445#[serde(rename_all = "camelCase")]
446pub struct ResourceTemplate {
447    pub uri_template: String,
448    pub name: String,
449    #[serde(skip_serializing_if = "Option::is_none")]
450    pub description: Option<String>,
451    #[serde(skip_serializing_if = "Option::is_none")]
452    pub mime_type: Option<String>,
453}
454
455#[derive(Debug, Serialize, Deserialize)]
456#[serde(rename_all = "lowercase")]
457pub enum LoggingLevel {
458    Debug,
459    Info,
460    Notice,
461    Warning,
462    Error,
463    Critical,
464    Alert,
465    Emergency,
466}
467
468#[derive(Debug, Serialize, Deserialize)]
469#[serde(rename_all = "camelCase")]
470pub struct ModelPreferences {
471    #[serde(skip_serializing_if = "Option::is_none")]
472    pub hints: Option<Vec<ModelHint>>,
473    #[serde(skip_serializing_if = "Option::is_none")]
474    pub cost_priority: Option<f64>,
475    #[serde(skip_serializing_if = "Option::is_none")]
476    pub speed_priority: Option<f64>,
477    #[serde(skip_serializing_if = "Option::is_none")]
478    pub intelligence_priority: Option<f64>,
479}
480
481#[derive(Debug, Serialize, Deserialize)]
482#[serde(rename_all = "camelCase")]
483pub struct ModelHint {
484    #[serde(skip_serializing_if = "Option::is_none")]
485    pub name: Option<String>,
486}
487
488#[derive(Debug, Serialize)]
489#[serde(rename_all = "camelCase")]
490pub enum NotificationType {
491    Initialized,
492    Progress,
493    Message,
494    ResourcesUpdated,
495    ResourcesListChanged,
496    ToolsListChanged,
497    PromptsListChanged,
498    RootsListChanged,
499}
500
501impl NotificationType {
502    pub fn as_str(&self) -> &'static str {
503        match self {
504            NotificationType::Initialized => "notifications/initialized",
505            NotificationType::Progress => "notifications/progress",
506            NotificationType::Message => "notifications/message",
507            NotificationType::ResourcesUpdated => "notifications/resources/updated",
508            NotificationType::ResourcesListChanged => "notifications/resources/list_changed",
509            NotificationType::ToolsListChanged => "notifications/tools/list_changed",
510            NotificationType::PromptsListChanged => "notifications/prompts/list_changed",
511            NotificationType::RootsListChanged => "notifications/roots/list_changed",
512        }
513    }
514}
515
516#[derive(Debug, Serialize)]
517#[serde(untagged)]
518pub enum ClientNotification {
519    Initialized,
520    Progress(ProgressParams),
521    RootsListChanged,
522    Cancelled {
523        request_id: String,
524        #[serde(skip_serializing_if = "Option::is_none")]
525        reason: Option<String>,
526    },
527}
528
529#[derive(Debug, Serialize, Deserialize)]
530#[serde(untagged)]
531pub enum ProgressToken {
532    String(String),
533    Number(f64),
534}
535
536#[derive(Debug, Serialize)]
537#[serde(rename_all = "camelCase")]
538pub struct ProgressParams {
539    pub progress_token: ProgressToken,
540    pub progress: f64,
541    #[serde(skip_serializing_if = "Option::is_none")]
542    pub total: Option<f64>,
543    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
544    pub meta: Option<HashMap<String, serde_json::Value>>,
545}
546
547pub enum CompletionTotal {
548    Exact(u32),
549    HasMore,
550    Unknown,
551}
552
553impl CompletionTotal {
554    pub fn from_options(has_more: Option<bool>, total: Option<u32>) -> Self {
555        match (has_more, total) {
556            (_, Some(count)) => CompletionTotal::Exact(count),
557            (Some(true), _) => CompletionTotal::HasMore,
558            _ => CompletionTotal::Unknown,
559        }
560    }
561}
562
563pub struct Completion {
564    pub values: Vec<String>,
565    pub total: CompletionTotal,
566}
567
568#[derive(Debug, Deserialize)]
569#[serde(rename_all = "camelCase")]
570pub struct CallToolResponse {
571    pub content: Vec<ToolResponseContent>,
572    #[serde(skip_serializing_if = "Option::is_none")]
573    pub is_error: Option<bool>,
574    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
575    pub meta: Option<HashMap<String, serde_json::Value>>,
576}
577
578#[derive(Debug, Serialize, Deserialize)]
579#[serde(tag = "type")]
580pub enum ToolResponseContent {
581    #[serde(rename = "text")]
582    Text { text: String },
583    #[serde(rename = "image")]
584    Image { data: String, mime_type: String },
585    #[serde(rename = "resource")]
586    Resource { resource: ResourceContents },
587}
588
589#[derive(Debug, Deserialize)]
590#[serde(rename_all = "camelCase")]
591pub struct ListToolsResponse {
592    pub tools: Vec<Tool>,
593    #[serde(skip_serializing_if = "Option::is_none")]
594    pub next_cursor: Option<String>,
595    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
596    pub meta: Option<HashMap<String, serde_json::Value>>,
597}
598
599#[derive(Debug, Deserialize)]
600#[serde(rename_all = "camelCase")]
601pub struct ListResourceTemplatesResponse {
602    pub resource_templates: Vec<ResourceTemplate>,
603    #[serde(skip_serializing_if = "Option::is_none")]
604    pub next_cursor: Option<String>,
605    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
606    pub meta: Option<HashMap<String, serde_json::Value>>,
607}
608
609#[derive(Debug, Deserialize)]
610#[serde(rename_all = "camelCase")]
611pub struct ListRootsResponse {
612    pub roots: Vec<Root>,
613    #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
614    pub meta: Option<HashMap<String, serde_json::Value>>,
615}
616
617#[derive(Debug, Serialize, Deserialize)]
618#[serde(rename_all = "camelCase")]
619pub struct Root {
620    pub uri: Url,
621    #[serde(skip_serializing_if = "Option::is_none")]
622    pub name: Option<String>,
623}