use rmcp::schemars;
use schemars::JsonSchema;
use serde::Deserialize;
#[derive(Debug, Default, Deserialize, JsonSchema)]
pub struct SearchInput {
#[schemars(description = "Text to search for across issues and pages")]
pub query: String,
#[schemars(description = "Filter to a specific project (e.g. LIF)")]
pub project: Option<String>,
#[schemars(description = "Restrict results to one type: issue or page")]
pub result_type: Option<String>,
#[schemars(
description = "Sort mode: relevance (default, best match first) or recent (most recently updated first)"
)]
pub sort: Option<String>,
#[schemars(description = "Max results (default 20)")]
pub limit: Option<i64>,
#[schemars(
description = "Zero-indexed offset for paging. Output appends a hint when more results exist."
)]
pub offset: Option<i64>,
}
#[derive(Debug, Default, Deserialize, JsonSchema)]
pub struct ListIssuesInput {
#[schemars(description = "Project identifier (e.g. LIF)")]
pub project: String,
#[schemars(description = "Filter by status: backlog, todo, active, done, cancelled")]
pub status: Option<String>,
#[schemars(description = "Filter by priority: urgent, high, medium, low, none")]
pub priority: Option<String>,
#[schemars(description = "Filter by module name")]
pub module: Option<String>,
#[schemars(description = "Filter by label name")]
pub label: Option<String>,
#[schemars(description = "Only return issues with no unresolved blockers")]
pub workable: Option<bool>,
#[schemars(
description = "Only issues created at/after this ISO date or datetime (e.g. 2026-06-01)"
)]
pub created_since: Option<String>,
#[schemars(description = "Only issues created before this ISO date or datetime (exclusive)")]
pub created_until: Option<String>,
#[schemars(
description = "Only issues updated at/after this ISO date or datetime. Handy for 'what changed recently'."
)]
pub updated_since: Option<String>,
#[schemars(description = "Only issues updated before this ISO date or datetime (exclusive)")]
pub updated_until: Option<String>,
#[schemars(
description = "Sort column: sort_order (default), sequence, created, or updated"
)]
pub order_by: Option<String>,
#[schemars(description = "Sort direction: asc (default) or desc")]
pub order: Option<String>,
#[schemars(description = "Max results (default 50)")]
pub limit: Option<i64>,
#[schemars(
description = "Zero-indexed offset for paging. The output appends a hint like 'has_more: use offset=N' when more results exist."
)]
pub offset: Option<i64>,
}
#[derive(Debug, Default, Deserialize, JsonSchema)]
pub struct GetIssueInput {
#[schemars(description = "Issue identifier like PRO-42 or ADA-7")]
pub identifier: String,
}
#[derive(Debug, Default, Deserialize, JsonSchema)]
pub struct GetActivityInput {
#[schemars(
description = "What to read history for: an issue identifier (PRO-42), a page identifier (PRO-DOC-3 or DOC-3), or a bare project identifier (PRO) for the whole project's feed"
)]
pub identifier: String,
#[schemars(description = "Max entries (default 30, cap 200)")]
pub limit: Option<i64>,
#[schemars(
description = "Zero-indexed offset for paging. Output appends a hint when more entries exist."
)]
pub offset: Option<i64>,
}
#[derive(Debug, Default, Deserialize, JsonSchema)]
pub struct CreateIssueInput {
#[schemars(description = "Project identifier (e.g. LIF)")]
pub project: String,
#[schemars(description = "Issue title")]
pub title: String,
#[schemars(description = "Markdown description")]
pub description: Option<String>,
#[schemars(description = "Status: backlog, todo, active, done, cancelled (default: backlog)")]
pub status: Option<String>,
#[schemars(description = "Priority: urgent, high, medium, low, none (default: none)")]
pub priority: Option<String>,
#[schemars(description = "Module name to assign to")]
pub module: Option<String>,
#[schemars(description = "Label names to attach")]
pub labels: Option<Vec<String>>,
}
#[derive(Debug, Default, Deserialize, JsonSchema)]
pub struct UpdateIssueInput {
#[schemars(description = "Issue identifier like PRO-42")]
pub identifier: String,
#[schemars(description = "New title")]
pub title: Option<String>,
#[schemars(description = "New description (markdown)")]
pub description: Option<String>,
#[schemars(description = "New status: backlog, todo, active, done, cancelled")]
pub status: Option<String>,
#[schemars(description = "New priority: urgent, high, medium, low, none")]
pub priority: Option<String>,
#[schemars(description = "New module name")]
pub module: Option<String>,
#[schemars(description = "Replace labels")]
pub labels: Option<Vec<String>>,
}
#[derive(Debug, Default, Deserialize, JsonSchema)]
pub struct GetBoardInput {
#[schemars(description = "Project identifier (e.g. LIF)")]
pub project: String,
#[schemars(description = "Group by: status, priority, or module (default: status)")]
pub group_by: Option<String>,
}
#[derive(Debug, Default, Deserialize, JsonSchema)]
pub struct LinkIssuesInput {
#[schemars(description = "Source issue identifier (e.g. PRO-1)")]
pub source: String,
#[schemars(description = "Target issue identifier (e.g. PRO-2)")]
pub target: String,
#[schemars(description = "Relation type: blocks, relates_to, or duplicate")]
pub relation_type: String,
}
#[derive(Debug, Default, Deserialize, JsonSchema)]
pub struct UnlinkIssuesInput {
#[schemars(description = "First issue identifier")]
pub source: String,
#[schemars(description = "Second issue identifier")]
pub target: String,
}
#[derive(Debug, Default, Deserialize, JsonSchema)]
pub struct GetPageInput {
#[schemars(description = "Page identifier like LIF-DOC-1")]
pub identifier: String,
}
#[derive(Debug, Default, Deserialize, JsonSchema)]
pub struct CreatePageInput {
#[schemars(description = "Project identifier (e.g. LIF). Omit for workspace-level page.")]
pub project: Option<String>,
#[schemars(description = "Page title")]
pub title: String,
#[schemars(description = "Markdown content")]
pub content: Option<String>,
#[schemars(description = "Folder name to place page in")]
pub folder: Option<String>,
#[schemars(description = "Status: draft, active, complete, archived")]
pub status: Option<String>,
#[schemars(
description = "Label names to attach. Labels are project-scoped, so this is ignored on workspace pages (LIF-105)."
)]
pub labels: Option<Vec<String>>,
}
#[derive(Debug, Default, Deserialize, JsonSchema)]
pub struct UpdatePageInput {
#[schemars(description = "Page identifier like LIF-DOC-1")]
pub identifier: String,
#[schemars(description = "New title")]
pub title: Option<String>,
#[schemars(description = "New markdown content")]
pub content: Option<String>,
#[schemars(description = "Move to folder name")]
pub folder: Option<String>,
#[schemars(description = "Status: draft, active, complete, archived")]
pub status: Option<String>,
#[schemars(
description = "Replace labels. Pass [] to clear all. Labels are project-scoped (LIF-105)."
)]
pub labels: Option<Vec<String>>,
}
#[derive(Debug, Default, Deserialize, JsonSchema)]
pub struct EditIssueInput {
#[schemars(description = "Issue identifier like PRO-42")]
pub identifier: String,
#[schemars(description = "Exact string to find. Must be unique unless replace_all is true.")]
pub old_string: String,
#[schemars(description = "Replacement string (must differ from old_string)")]
pub new_string: String,
#[schemars(description = "Field to edit: 'description' (default) or 'title'")]
pub field: Option<String>,
#[schemars(description = "Replace all occurrences (default false)")]
pub replace_all: Option<bool>,
}
#[derive(Debug, Default, Deserialize, JsonSchema)]
pub struct EditPageInput {
#[schemars(description = "Page identifier like LIF-DOC-1")]
pub identifier: String,
#[schemars(description = "Exact string to find. Must be unique unless replace_all is true.")]
pub old_string: String,
#[schemars(description = "Replacement string (must differ from old_string)")]
pub new_string: String,
#[schemars(description = "Field to edit: 'content' (default) or 'title'")]
pub field: Option<String>,
#[schemars(description = "Replace all occurrences (default false)")]
pub replace_all: Option<bool>,
}
#[derive(Debug, Default, Deserialize, JsonSchema)]
pub struct DeleteInput {
#[schemars(
description = "Type of thing to delete: issue, page, project, module, label, or folder"
)]
pub resource_type: String,
#[schemars(
description = "Identifier or name (e.g. LIF-1, LIF-DOC-1, LIF for projects, or name for modules/labels/folders)"
)]
pub identifier: String,
#[schemars(
description = "Project identifier (required for deleting module/label/folder by name)"
)]
pub project: Option<String>,
}
#[derive(Debug, Default, Deserialize, JsonSchema)]
pub struct ListResourcesInput {
#[schemars(description = "Resource type: project, module, label, folder, page, or issue")]
pub resource_type: String,
#[schemars(description = "Project identifier (required for most types)")]
pub project: Option<String>,
#[schemars(description = "Folder name (for page filtering)")]
pub folder: Option<String>,
#[schemars(description = "Label name (for issue or page filtering — LIF-105)")]
pub label: Option<String>,
#[schemars(
description = "Status filter (for page lists): draft, active, complete, or archived"
)]
pub status: Option<String>,
#[schemars(
description = "Sort column (for page lists): sort_order (default), title, status, created, or updated"
)]
pub order_by: Option<String>,
#[schemars(description = "Sort direction (for page lists): asc (default) or desc")]
pub order: Option<String>,
#[schemars(description = "Max results (applies to issue/page lists; default 100 for issues)")]
pub limit: Option<i64>,
#[schemars(
description = "Zero-indexed offset for paging (applies to issue/page lists). Output appends a hint when more results exist."
)]
pub offset: Option<i64>,
}
#[derive(Debug, Default, Deserialize, JsonSchema)]
pub struct ManageResourceInput {
#[schemars(description = "Resource type: project, module, label, or folder")]
pub resource_type: String,
#[schemars(description = "Action: create or update")]
pub action: String,
#[schemars(description = "Resource name (required for update, identifies which to update)")]
pub current_name: Option<String>,
#[schemars(description = "Project identifier (for create, e.g. LIF)")]
pub project: Option<String>,
#[schemars(description = "Name")]
pub name: Option<String>,
#[schemars(description = "Identifier (for project create, e.g. PRO)")]
pub identifier: Option<String>,
#[schemars(description = "Description")]
pub description: Option<String>,
#[schemars(
description = "Status (for module: backlog, planned, active, paused, done, cancelled)"
)]
pub status: Option<String>,
#[schemars(description = "Color hex (for label, e.g. #EF4444)")]
pub color: Option<String>,
}
#[derive(Debug, Default, Deserialize, JsonSchema)]
pub struct AddCommentInput {
#[schemars(description = "Issue identifier (e.g. LIF-1)")]
pub identifier: String,
#[schemars(description = "Comment content (markdown)")]
pub content: String,
}
#[derive(Debug, Default, Deserialize, JsonSchema)]
pub struct ListCommentsInput {
#[schemars(description = "Issue identifier (e.g. LIF-1)")]
pub identifier: String,
#[schemars(description = "Filter to comments by this author username")]
pub author: Option<String>,
#[schemars(
description = "Sort direction by creation time: asc (default, oldest first) or desc (newest first)"
)]
pub order: Option<String>,
}
#[derive(Debug, Default, Deserialize, JsonSchema)]
pub struct ExportIssueInput {
#[schemars(description = "Issue identifier like PRO-42")]
pub identifier: String,
}
#[derive(Debug, Default, Deserialize, JsonSchema)]
pub struct ExportPageInput {
#[schemars(description = "Page identifier like LIF-DOC-1")]
pub identifier: String,
}
#[derive(Debug, Default, Deserialize, JsonSchema)]
pub struct ExportProjectInput {
#[schemars(description = "Project identifier (e.g. LIF)")]
pub project: String,
}