Skip to main content

research_agent/mcp/
params.rs

1//! MCP tool parameter structs.
2//!
3//! Each derives `serde::Deserialize + schemars::JsonSchema` (required by rmcp so
4//! the tool's `inputSchema` is derived automatically). Only **primitive** types
5//! are used — research-agent domain types (which derive `Serialize` but **not**
6//! `JsonSchema`) are returned from tools as opaque `serde_json::Value` instead.
7//!
8//! Tools that take no parameters (`init`, `index_rebuild`, `state`,
9//! `topics_list`) declare no `Parameters` at all, mirroring BYOH's `genre_list`.
10
11use schemars::JsonSchema;
12use serde::Deserialize;
13
14#[derive(Debug, Deserialize, JsonSchema)]
15pub struct IngestParams {
16    /// Search query (required for arxiv/s2/openalex/europepmc/preprints/all;
17    /// ignored for pdf).
18    #[serde(default)]
19    pub query: Option<String>,
20    /// Source: "arxiv" | "s2" | "openalex" | "europepmc" | "preprints" | "all"
21    /// | "pdf" (default "all").
22    #[serde(default = "default_source")]
23    pub source: String,
24    /// Maximum papers to fetch for remote sources (default 10).
25    #[serde(default = "default_limit")]
26    pub limit: usize,
27    /// Path to a PDF file or directory (required for source=pdf).
28    #[serde(default)]
29    pub path: Option<String>,
30    /// Optional topic id to link the ingested papers to.
31    #[serde(default)]
32    pub topic: Option<String>,
33}
34
35#[derive(Debug, Deserialize, JsonSchema)]
36pub struct ImportPapersParams {
37    /// Path to a .bib/.bibtex/.json file, or a directory of them.
38    pub path: String,
39}
40
41#[derive(Debug, Deserialize, JsonSchema)]
42pub struct PaperBodyParams {
43    /// Paper id.
44    pub id: String,
45    /// When set, return matching snippets with their section and page instead
46    /// of the truncated whole body.
47    pub query: Option<String>,
48}
49
50#[derive(Debug, Deserialize, JsonSchema)]
51pub struct PaperReferencesParams {
52    /// Paper id.
53    pub id: String,
54    /// Direction: "references" (default, works the paper cites) or
55    /// "cited_by" (works citing the paper).
56    pub direction: Option<String>,
57    /// Also label edges with Semantic Scholar citation intents
58    /// (background/methodology/result, influential). Costs one extra
59    /// rate-limited request; defaults to false.
60    pub intents: Option<bool>,
61}
62
63#[derive(Debug, Deserialize, JsonSchema)]
64pub struct QueryPapersParams {
65    pub query: String,
66    /// Maximum results (default 20).
67    #[serde(default = "default_query_limit")]
68    pub limit: usize,
69}
70
71#[derive(Debug, Deserialize, JsonSchema)]
72pub struct MissingKeywordsParams {
73    /// Maximum papers to return (default 20).
74    #[serde(default = "default_query_limit")]
75    pub limit: usize,
76}
77
78#[derive(Debug, Deserialize, JsonSchema)]
79pub struct EnrichPaperParams {
80    pub id: String,
81    /// Keywords separated by "; ", e.g. "transformer; self-attention".
82    pub keywords: String,
83}
84
85#[derive(Debug, Deserialize, JsonSchema)]
86pub struct TopicBriefParams {
87    /// Topic id to collect.
88    pub topic: String,
89}
90
91#[derive(Debug, Deserialize, JsonSchema)]
92pub struct GapInput {
93    /// What the library is missing, in one sentence.
94    pub description: String,
95    /// missing_literature | unanswered_question | methodology_gap | connection_gap
96    #[serde(default)]
97    pub gap_type: Option<String>,
98    /// 0.0–1.0 (default 0.5).
99    #[serde(default)]
100    pub priority: Option<f32>,
101}
102
103#[derive(Debug, Deserialize, JsonSchema)]
104pub struct GapsRecordParams {
105    /// Topic id the gaps belong to.
106    pub topic: String,
107    /// The gaps to record.
108    pub gaps: Vec<GapInput>,
109}
110
111#[derive(Debug, Deserialize, JsonSchema)]
112pub struct ListGapsParams {
113    /// Optional topic id filter.
114    #[serde(default)]
115    pub topic: Option<String>,
116}
117
118#[derive(Debug, Deserialize, JsonSchema)]
119pub struct ReportTopicParams {
120    /// Comma-separated topic ids.
121    pub topics: String,
122}
123
124#[derive(Debug, Deserialize, JsonSchema)]
125pub struct ReportSaveParams {
126    /// Report title.
127    pub title: String,
128    /// Comma-separated topic ids the report covers.
129    pub topics: String,
130    /// Full markdown. Sections split on '## ' headings.
131    pub markdown: String,
132}
133
134#[derive(Debug, Deserialize, JsonSchema)]
135pub struct TopicAddParams {
136    pub name: String,
137    #[serde(default)]
138    pub description: String,
139    /// Parent topic id (creates a sub-topic).
140    #[serde(default)]
141    pub parent: Option<String>,
142}
143
144#[derive(Debug, Deserialize, JsonSchema)]
145pub struct UpdateReadParams {
146    /// Paper id.
147    pub id: String,
148    /// New status: unread | queued | in_progress | completed | abandoned.
149    #[serde(default)]
150    pub status: Option<String>,
151    /// Rating 1–5.
152    #[serde(default)]
153    pub rating: Option<u8>,
154}
155
156fn default_source() -> String {
157    "all".to_string()
158}
159fn default_limit() -> usize {
160    10
161}
162fn default_query_limit() -> usize {
163    20
164}