lean_ctx/tools/registered/
ctx_provider.rs1use rmcp::model::Tool;
2use rmcp::ErrorData;
3use serde_json::{json, Map, Value};
4
5use crate::server::tool_trait::{McpTool, ToolContext, ToolOutput};
6use crate::tool_defs::tool_def;
7
8pub struct CtxProviderTool;
9
10impl McpTool for CtxProviderTool {
11 fn name(&self) -> &'static str {
12 "ctx_provider"
13 }
14
15 fn tool_def(&self) -> Tool {
16 tool_def(
17 "ctx_provider",
18 "External context providers (GitHub, GitLab, more). \
19 Use action=discover to list available providers. \
20 Use action=query with provider+resource for registry-based access. \
21 Legacy GitLab actions still supported. \
22 Set GITHUB_TOKEN or GITLAB_TOKEN to enable providers.",
23 json!({
24 "type": "object",
25 "properties": {
26 "action": {
27 "type": "string",
28 "enum": [
29 "discover",
30 "query",
31 "mcp_resources",
32 "gitlab_issues",
33 "gitlab_issue",
34 "gitlab_mrs",
35 "gitlab_pipelines"
36 ],
37 "description": "Provider action. 'discover' lists all. 'query' uses registry routing. 'mcp_resources' lists MCP bridge resources."
38 },
39 "provider": {
40 "type": "string",
41 "description": "Provider ID (e.g. 'github', 'mcp:my-kb'). For action=query requires provider+resource."
42 },
43 "resource": {
44 "type": "string",
45 "description": "Resource type for action=query (e.g. 'issues', 'pull_requests', 'read_resource')"
46 },
47 "mode": {
48 "type": "string",
49 "enum": ["compact", "chunks"],
50 "description": "Output mode for action=query. 'compact' (default) returns formatted text. 'chunks' returns ContentChunk metadata for BM25/embedding ingest."
51 },
52 "state": {
53 "type": "string",
54 "description": "Filter by state (open, closed, merged, all)"
55 },
56 "labels": {
57 "type": "string",
58 "description": "Comma-separated labels filter (GitLab)"
59 },
60 "iid": {
61 "type": "integer",
62 "description": "Issue/MR IID for single-item lookup (GitLab)"
63 },
64 "status": {
65 "type": "string",
66 "description": "Pipeline/Actions status filter (running, success, failed)"
67 },
68 "limit": {
69 "type": "integer",
70 "description": "Max results (default 20, max 100)"
71 }
72 },
73 "required": ["action"]
74 }),
75 )
76 }
77
78 fn handle(
79 &self,
80 args: &Map<String, Value>,
81 ctx: &ToolContext,
82 ) -> Result<ToolOutput, ErrorData> {
83 let result = crate::tools::ctx_provider::handle(args, ctx);
84 Ok(ToolOutput::simple(result))
85 }
86}