Coverage for src/qdrant_loader_mcp_server/mcp/schemas.py: 100%

35 statements  

« prev     ^ index     » next       coverage.py v7.10.3, created at 2025-08-13 09:20 +0000

1"""MCP Tool Schema Definitions.""" 

2 

3from typing import Any 

4 

5 

6class MCPSchemas: 

7 """Tool schema definitions for MCP server.""" 

8 

9 @staticmethod 

10 def get_search_tool_schema() -> dict[str, Any]: 

11 """Get the basic search tool schema.""" 

12 return { 

13 "name": "search", 

14 "description": "Perform semantic search across multiple data sources", 

15 "annotations": {"read-only": True}, 

16 "inputSchema": { 

17 "type": "object", 

18 "properties": { 

19 "query": { 

20 "type": "string", 

21 "description": "The search query in natural language", 

22 }, 

23 "source_types": { 

24 "type": "array", 

25 "items": { 

26 "type": "string", 

27 "enum": [ 

28 "git", 

29 "confluence", 

30 "jira", 

31 "documentation", 

32 "localfile", 

33 ], 

34 }, 

35 "description": "Optional list of source types to filter results", 

36 }, 

37 "project_ids": { 

38 "type": "array", 

39 "items": { 

40 "type": "string", 

41 }, 

42 "description": "Optional list of project IDs to filter results", 

43 }, 

44 "limit": { 

45 "type": "integer", 

46 "description": "Maximum number of results to return", 

47 "default": 5, 

48 }, 

49 }, 

50 "required": ["query"], 

51 }, 

52 "outputSchema": { 

53 "type": "object", 

54 "properties": { 

55 "results": { 

56 "type": "array", 

57 "items": { 

58 "type": "object", 

59 "properties": { 

60 "score": {"type": "number"}, 

61 "title": {"type": "string"}, 

62 "content": {"type": "string"}, 

63 "source_type": {"type": "string"}, 

64 "metadata": { 

65 "type": "object", 

66 "properties": { 

67 "file_path": {"type": "string"}, 

68 "project_id": {"type": "string"}, 

69 "created_at": {"type": "string"}, 

70 "last_modified": {"type": "string"}, 

71 }, 

72 }, 

73 }, 

74 }, 

75 }, 

76 "total_found": {"type": "integer"}, 

77 "query_context": { 

78 "type": "object", 

79 "properties": { 

80 "original_query": {"type": "string"}, 

81 "source_types_filtered": { 

82 "type": "array", 

83 "items": {"type": "string"}, 

84 }, 

85 "project_ids_filtered": { 

86 "type": "array", 

87 "items": {"type": "string"}, 

88 }, 

89 }, 

90 }, 

91 }, 

92 }, 

93 } 

94 

95 @staticmethod 

96 def get_hierarchy_search_tool_schema() -> dict[str, Any]: 

97 """Get the hierarchy search tool schema.""" 

98 return { 

99 "name": "hierarchy_search", 

100 "description": "Search Confluence documents with hierarchy-aware filtering and organization", 

101 "annotations": {"read-only": True}, 

102 "inputSchema": { 

103 "type": "object", 

104 "properties": { 

105 "query": { 

106 "type": "string", 

107 "description": "The search query in natural language", 

108 }, 

109 "hierarchy_filter": { 

110 "type": "object", 

111 "properties": { 

112 "depth": { 

113 "type": "integer", 

114 "description": "Filter by specific hierarchy depth (0 = root pages)", 

115 }, 

116 "parent_title": { 

117 "type": "string", 

118 "description": "Filter by parent page title", 

119 }, 

120 "root_only": { 

121 "type": "boolean", 

122 "description": "Show only root pages (no parent)", 

123 }, 

124 "has_children": { 

125 "type": "boolean", 

126 "description": "Filter by whether pages have children", 

127 }, 

128 }, 

129 }, 

130 "organize_by_hierarchy": { 

131 "type": "boolean", 

132 "description": "Group results by hierarchy structure", 

133 "default": False, 

134 }, 

135 "limit": { 

136 "type": "integer", 

137 "description": "Maximum number of results to return", 

138 "default": 10, 

139 }, 

140 }, 

141 "required": ["query"], 

142 }, 

143 "outputSchema": { 

144 "type": "object", 

145 "properties": { 

146 "results": { 

147 "type": "array", 

148 "items": { 

149 "type": "object", 

150 "properties": { 

151 "score": {"type": "number"}, 

152 "title": {"type": "string"}, 

153 "content": {"type": "string"}, 

154 "hierarchy_path": {"type": "string"}, 

155 "parent_title": {"type": "string"}, 

156 "metadata": { 

157 "type": "object", 

158 "properties": { 

159 "space_key": {"type": "string"}, 

160 "project_id": {"type": "string"}, 

161 "page_id": {"type": "string"}, 

162 "hierarchy_level": {"type": "integer"}, 

163 }, 

164 }, 

165 }, 

166 }, 

167 }, 

168 "total_found": {"type": "integer"}, 

169 "hierarchy_organization": { 

170 "type": "object", 

171 "properties": { 

172 "organized_by_hierarchy": {"type": "boolean"}, 

173 "hierarchy_groups": { 

174 "type": "array", 

175 "items": {"type": "object"}, 

176 }, 

177 }, 

178 }, 

179 }, 

180 }, 

181 } 

182 

183 @staticmethod 

184 def get_attachment_search_tool_schema() -> dict[str, Any]: 

185 """Get the attachment search tool schema.""" 

186 return { 

187 "name": "attachment_search", 

188 "description": "Search for file attachments and their parent documents across Confluence, Jira, and other sources", 

189 "annotations": {"read-only": True}, 

190 "inputSchema": { 

191 "type": "object", 

192 "properties": { 

193 "query": { 

194 "type": "string", 

195 "description": "The search query in natural language", 

196 }, 

197 "attachment_filter": { 

198 "type": "object", 

199 "properties": { 

200 "attachments_only": { 

201 "type": "boolean", 

202 "description": "Show only file attachments", 

203 }, 

204 "parent_document_title": { 

205 "type": "string", 

206 "description": "Filter by parent document title", 

207 }, 

208 "file_type": { 

209 "type": "string", 

210 "description": "Filter by file type (e.g., 'pdf', 'xlsx', 'png')", 

211 }, 

212 "file_size_min": { 

213 "type": "integer", 

214 "description": "Minimum file size in bytes", 

215 }, 

216 "file_size_max": { 

217 "type": "integer", 

218 "description": "Maximum file size in bytes", 

219 }, 

220 "author": { 

221 "type": "string", 

222 "description": "Filter by attachment author", 

223 }, 

224 }, 

225 }, 

226 "include_parent_context": { 

227 "type": "boolean", 

228 "description": "Include parent document information in results", 

229 "default": True, 

230 }, 

231 "limit": { 

232 "type": "integer", 

233 "description": "Maximum number of results to return", 

234 "default": 10, 

235 }, 

236 }, 

237 "required": ["query"], 

238 }, 

239 "outputSchema": { 

240 "type": "object", 

241 "properties": { 

242 "results": { 

243 "type": "array", 

244 "items": { 

245 "type": "object", 

246 "properties": { 

247 "score": {"type": "number"}, 

248 "title": {"type": "string"}, 

249 "content": {"type": "string"}, 

250 "attachment_info": { 

251 "type": "object", 

252 "properties": { 

253 "filename": {"type": "string"}, 

254 "file_type": {"type": "string"}, 

255 "file_size": {"type": "integer"}, 

256 "parent_document": {"type": "string"}, 

257 }, 

258 }, 

259 "metadata": { 

260 "type": "object", 

261 "properties": { 

262 "file_path": {"type": "string"}, 

263 "project_id": {"type": "string"}, 

264 "upload_date": {"type": "string"}, 

265 "author": {"type": "string"}, 

266 }, 

267 }, 

268 }, 

269 }, 

270 }, 

271 "total_found": {"type": "integer"}, 

272 "attachment_summary": { 

273 "type": "object", 

274 "properties": { 

275 "total_attachments": {"type": "integer"}, 

276 "file_types": { 

277 "type": "array", 

278 "items": {"type": "string"}, 

279 }, 

280 "attachments_only": {"type": "boolean"}, 

281 }, 

282 }, 

283 }, 

284 }, 

285 } 

286 

287 @staticmethod 

288 def get_analyze_relationships_tool_schema() -> dict[str, Any]: 

289 """Get the analyze document relationships tool schema.""" 

290 return { 

291 "name": "analyze_relationships", 

292 "description": "Analyze relationships between documents", 

293 "annotations": {"read-only": True}, 

294 "inputSchema": { 

295 "type": "object", 

296 "properties": { 

297 "query": { 

298 "type": "string", 

299 "description": "Search query to get documents for analysis", 

300 }, 

301 "limit": { 

302 "type": "integer", 

303 "description": "Maximum number of documents to analyze", 

304 "default": 20, 

305 }, 

306 "source_types": { 

307 "type": "array", 

308 "items": {"type": "string"}, 

309 "description": "Optional list of source types to filter by", 

310 }, 

311 "project_ids": { 

312 "type": "array", 

313 "items": {"type": "string"}, 

314 "description": "Optional list of project IDs to filter by", 

315 }, 

316 "use_llm": { 

317 "type": "boolean", 

318 "description": "Enable LLM validation for top pairs (budgeted)" 

319 }, 

320 "max_llm_pairs": { 

321 "type": "integer", 

322 "description": "Maximum number of pairs to analyze with LLM" 

323 }, 

324 "overall_timeout_s": { 

325 "type": "number", 

326 "description": "Overall analysis budget in seconds" 

327 }, 

328 "max_pairs_total": { 

329 "type": "integer", 

330 "description": "Maximum candidate pairs to analyze after tiering" 

331 }, 

332 "text_window_chars": { 

333 "type": "integer", 

334 "description": "Per-document text window size for lexical analysis" 

335 }, 

336 }, 

337 "required": ["query"], 

338 }, 

339 "outputSchema": { 

340 "type": "object", 

341 "properties": { 

342 "relationships": { 

343 "type": "array", 

344 "items": { 

345 "type": "object", 

346 "properties": { 

347 "document_1": {"type": "string"}, 

348 "document_2": {"type": "string"}, 

349 "relationship_type": {"type": "string"}, 

350 "score": {"type": "number"}, 

351 "description": {"type": "string"}, 

352 }, 

353 }, 

354 }, 

355 "total_analyzed": {"type": "integer"}, 

356 "summary": {"type": "string"}, 

357 }, 

358 }, 

359 } 

360 

361 @staticmethod 

362 def get_find_similar_tool_schema() -> dict[str, Any]: 

363 """Get the find similar documents tool schema.""" 

364 return { 

365 "name": "find_similar_documents", 

366 "description": "Find documents similar to a target document using multiple similarity metrics", 

367 "annotations": {"read-only": True}, 

368 "inputSchema": { 

369 "type": "object", 

370 "properties": { 

371 "target_query": { 

372 "type": "string", 

373 "description": "Query to find the target document", 

374 }, 

375 "comparison_query": { 

376 "type": "string", 

377 "description": "Query to get documents to compare against", 

378 }, 

379 "similarity_metrics": { 

380 "type": "array", 

381 "items": { 

382 "type": "string", 

383 "enum": [ 

384 "entity_overlap", 

385 "topic_overlap", 

386 "semantic_similarity", 

387 "metadata_similarity", 

388 "hierarchical_distance", 

389 "content_features", 

390 ], 

391 }, 

392 "description": "Similarity metrics to use", 

393 }, 

394 "max_similar": { 

395 "type": "integer", 

396 "description": "Maximum number of similar documents to return", 

397 "default": 5, 

398 }, 

399 "source_types": { 

400 "type": "array", 

401 "items": {"type": "string"}, 

402 "description": "Optional list of source types to filter by", 

403 }, 

404 "project_ids": { 

405 "type": "array", 

406 "items": {"type": "string"}, 

407 "description": "Optional list of project IDs to filter by", 

408 }, 

409 }, 

410 "required": ["target_query", "comparison_query"], 

411 }, 

412 "outputSchema": { 

413 "type": "object", 

414 "properties": { 

415 "similar_documents": { 

416 "type": "array", 

417 "items": { 

418 "type": "object", 

419 "properties": { 

420 "document_id": {"type": "string"}, 

421 "title": {"type": "string"}, 

422 "similarity_score": {"type": "number"}, 

423 "similarity_metrics": { 

424 "type": "object", 

425 "properties": { 

426 "entity_overlap": {"type": "number"}, 

427 "topic_overlap": {"type": "number"}, 

428 "semantic_similarity": {"type": "number"}, 

429 "metadata_similarity": {"type": "number"}, 

430 }, 

431 }, 

432 "similarity_reason": {"type": "string"}, 

433 "content_preview": {"type": "string"}, 

434 }, 

435 }, 

436 }, 

437 "target_document": { 

438 "type": "object", 

439 "properties": { 

440 "title": {"type": "string"}, 

441 "content_preview": {"type": "string"}, 

442 "source_type": {"type": "string"}, 

443 }, 

444 }, 

445 "similarity_summary": { 

446 "type": "object", 

447 "properties": { 

448 "total_compared": {"type": "integer"}, 

449 "similar_found": {"type": "integer"}, 

450 "highest_similarity": {"type": "number"}, 

451 "metrics_used": { 

452 "type": "array", 

453 "items": {"type": "string"}, 

454 }, 

455 }, 

456 }, 

457 }, 

458 }, 

459 } 

460 

461 @staticmethod 

462 def get_detect_conflicts_tool_schema() -> dict[str, Any]: 

463 """Get the detect conflicts tool schema.""" 

464 return { 

465 "name": "detect_document_conflicts", 

466 "description": "Detect conflicts and contradictions between documents", 

467 "annotations": {"read-only": True, "compute-intensive": True}, 

468 "inputSchema": { 

469 "type": "object", 

470 "properties": { 

471 "query": { 

472 "type": "string", 

473 "description": "Search query to get documents for conflict analysis", 

474 }, 

475 "limit": { 

476 "type": "integer", 

477 "description": "Maximum number of documents to analyze", 

478 "default": 10, 

479 }, 

480 "source_types": { 

481 "type": "array", 

482 "items": {"type": "string"}, 

483 "description": "Optional list of source types to filter by", 

484 }, 

485 "project_ids": { 

486 "type": "array", 

487 "items": {"type": "string"}, 

488 "description": "Optional list of project IDs to filter by", 

489 }, 

490 }, 

491 "required": ["query"], 

492 }, 

493 "outputSchema": { 

494 "type": "object", 

495 "properties": { 

496 "conflicts_detected": { 

497 "type": "array", 

498 "items": { 

499 "type": "object", 

500 "properties": { 

501 "conflict_id": {"type": "string"}, 

502 "document_1": { 

503 "type": "object", 

504 "properties": { 

505 "title": {"type": "string"}, 

506 "content_preview": {"type": "string"}, 

507 "source_type": {"type": "string"}, 

508 }, 

509 }, 

510 "document_2": { 

511 "type": "object", 

512 "properties": { 

513 "title": {"type": "string"}, 

514 "content_preview": {"type": "string"}, 

515 "source_type": {"type": "string"}, 

516 }, 

517 }, 

518 "conflict_type": {"type": "string"}, 

519 "conflict_score": {"type": "number"}, 

520 "conflict_description": {"type": "string"}, 

521 "conflicting_statements": { 

522 "type": "array", 

523 "items": { 

524 "type": "object", 

525 "properties": { 

526 "from_doc1": {"type": "string"}, 

527 "from_doc2": {"type": "string"}, 

528 }, 

529 }, 

530 }, 

531 }, 

532 }, 

533 }, 

534 "conflict_summary": { 

535 "type": "object", 

536 "properties": { 

537 "total_documents_analyzed": {"type": "integer"}, 

538 "conflicts_found": {"type": "integer"}, 

539 "conflict_types": { 

540 "type": "array", 

541 "items": {"type": "string"}, 

542 }, 

543 "highest_conflict_score": {"type": "number"}, 

544 }, 

545 }, 

546 "analysis_metadata": { 

547 "type": "object", 

548 "properties": { 

549 "query_used": {"type": "string"}, 

550 "analysis_date": {"type": "string"}, 

551 "processing_time_ms": {"type": "number"}, 

552 }, 

553 }, 

554 }, 

555 }, 

556 } 

557 

558 @staticmethod 

559 def get_find_complementary_tool_schema() -> dict[str, Any]: 

560 """Get the find complementary content tool schema.""" 

561 return { 

562 "name": "find_complementary_content", 

563 "description": "Find content that complements a target document", 

564 "annotations": {"read-only": True}, 

565 "inputSchema": { 

566 "type": "object", 

567 "properties": { 

568 "target_query": { 

569 "type": "string", 

570 "description": "Query to find the target document", 

571 }, 

572 "context_query": { 

573 "type": "string", 

574 "description": "Query to get contextual documents", 

575 }, 

576 "max_recommendations": { 

577 "type": "integer", 

578 "description": "Maximum number of recommendations", 

579 "default": 5, 

580 }, 

581 "source_types": { 

582 "type": "array", 

583 "items": {"type": "string"}, 

584 "description": "Optional list of source types to filter by", 

585 }, 

586 "project_ids": { 

587 "type": "array", 

588 "items": {"type": "string"}, 

589 "description": "Optional list of project IDs to filter by", 

590 }, 

591 }, 

592 "required": ["target_query", "context_query"], 

593 }, 

594 "outputSchema": { 

595 "type": "object", 

596 "properties": { 

597 "complementary_content": { 

598 "type": "array", 

599 "items": { 

600 "type": "object", 

601 "properties": { 

602 "document_id": {"type": "string"}, 

603 "title": {"type": "string"}, 

604 "content_preview": {"type": "string"}, 

605 "complementary_score": {"type": "number"}, 

606 "complementary_reason": {"type": "string"}, 

607 "relationship_type": {"type": "string"}, 

608 "source_type": {"type": "string"}, 

609 "metadata": { 

610 "type": "object", 

611 "properties": { 

612 "project_id": {"type": "string"}, 

613 "created_date": {"type": "string"}, 

614 "author": {"type": "string"}, 

615 }, 

616 }, 

617 }, 

618 }, 

619 }, 

620 "target_document": { 

621 "type": "object", 

622 "properties": { 

623 "title": {"type": "string"}, 

624 "content_preview": {"type": "string"}, 

625 "source_type": {"type": "string"}, 

626 }, 

627 }, 

628 "complementary_summary": { 

629 "type": "object", 

630 "properties": { 

631 "total_analyzed": {"type": "integer"}, 

632 "complementary_found": {"type": "integer"}, 

633 "highest_score": {"type": "number"}, 

634 "relationship_types": { 

635 "type": "array", 

636 "items": {"type": "string"}, 

637 }, 

638 }, 

639 }, 

640 }, 

641 }, 

642 } 

643 

644 @staticmethod 

645 def get_cluster_documents_tool_schema() -> dict[str, Any]: 

646 """Get the cluster documents tool schema.""" 

647 return { 

648 "name": "cluster_documents", 

649 "description": "Cluster documents based on similarity and relationships", 

650 "annotations": {"read-only": True, "compute-intensive": True}, 

651 "inputSchema": { 

652 "type": "object", 

653 "properties": { 

654 "query": { 

655 "type": "string", 

656 "description": "Search query to get documents for clustering", 

657 }, 

658 "strategy": { 

659 "type": "string", 

660 "enum": [ 

661 "mixed_features", 

662 "entity_based", 

663 "topic_based", 

664 "project_based", 

665 "hierarchical", 

666 "adaptive", 

667 ], 

668 "description": "Clustering strategy to use (adaptive automatically selects the best strategy)", 

669 "default": "mixed_features", 

670 }, 

671 "max_clusters": { 

672 "type": "integer", 

673 "description": "Maximum number of clusters to create", 

674 "default": 10, 

675 }, 

676 "min_cluster_size": { 

677 "type": "integer", 

678 "description": "Minimum size for a cluster", 

679 "default": 2, 

680 }, 

681 "limit": { 

682 "type": "integer", 

683 "description": "Maximum number of documents to cluster", 

684 "default": 25, 

685 }, 

686 "source_types": { 

687 "type": "array", 

688 "items": {"type": "string"}, 

689 "description": "Optional list of source types to filter by", 

690 }, 

691 "project_ids": { 

692 "type": "array", 

693 "items": {"type": "string"}, 

694 "description": "Optional list of project IDs to filter by", 

695 }, 

696 }, 

697 "required": ["query"], 

698 }, 

699 "outputSchema": { 

700 "type": "object", 

701 "properties": { 

702 "clusters": { 

703 "type": "array", 

704 "items": { 

705 "type": "object", 

706 "properties": { 

707 "cluster_id": {"type": "string"}, 

708 "cluster_name": {"type": "string"}, 

709 "cluster_theme": {"type": "string"}, 

710 "document_count": {"type": "integer"}, 

711 "cohesion_score": {"type": "number"}, 

712 "documents": { 

713 "type": "array", 

714 "items": { 

715 "type": "object", 

716 "properties": { 

717 "document_id": {"type": "string"}, 

718 "title": {"type": "string"}, 

719 "content_preview": {"type": "string"}, 

720 "source_type": {"type": "string"}, 

721 "cluster_relevance": {"type": "number"}, 

722 }, 

723 }, 

724 }, 

725 "cluster_keywords": { 

726 "type": "array", 

727 "items": {"type": "string"}, 

728 }, 

729 "cluster_summary": {"type": "string"}, 

730 }, 

731 }, 

732 }, 

733 "clustering_metadata": { 

734 "type": "object", 

735 "properties": { 

736 "total_documents": {"type": "integer"}, 

737 "clusters_created": {"type": "integer"}, 

738 "strategy": {"type": "string"}, 

739 "unclustered_documents": {"type": "integer"}, 

740 "clustering_quality": {"type": "number"}, 

741 "processing_time_ms": {"type": "number"}, 

742 }, 

743 }, 

744 "cluster_relationships": { 

745 "type": "array", 

746 "items": { 

747 "type": "object", 

748 "properties": { 

749 "cluster_1": {"type": "string"}, 

750 "cluster_2": {"type": "string"}, 

751 "relationship_type": {"type": "string"}, 

752 "relationship_strength": {"type": "number"}, 

753 }, 

754 }, 

755 }, 

756 }, 

757 }, 

758 } 

759 

760 @staticmethod 

761 def get_expand_cluster_tool_schema() -> dict[str, Any]: 

762 """Get the expand cluster tool schema for lazy loading cluster documents.""" 

763 return { 

764 "name": "expand_cluster", 

765 "description": "Retrieve all documents from a specific cluster for lazy loading", 

766 "annotations": {"read-only": True}, 

767 "inputSchema": { 

768 "type": "object", 

769 "properties": { 

770 "cluster_id": { 

771 "type": "string", 

772 "description": "The ID of the cluster to expand and retrieve all documents", 

773 }, 

774 "limit": { 

775 "type": "integer", 

776 "description": "Maximum number of documents to return from cluster (default: 20)", 

777 "default": 20, 

778 }, 

779 "offset": { 

780 "type": "integer", 

781 "description": "Number of documents to skip for pagination (default: 0)", 

782 "default": 0, 

783 }, 

784 "include_metadata": { 

785 "type": "boolean", 

786 "description": "Include detailed metadata for each document (default: true)", 

787 "default": True, 

788 }, 

789 }, 

790 "required": ["cluster_id"], 

791 }, 

792 "outputSchema": { 

793 "type": "object", 

794 "properties": { 

795 "cluster_id": { 

796 "type": "string", 

797 "description": "The expanded cluster ID", 

798 }, 

799 "cluster_info": { 

800 "type": "object", 

801 "description": "Detailed cluster information", 

802 }, 

803 "documents": { 

804 "type": "array", 

805 "description": "Full list of documents in the cluster", 

806 }, 

807 "pagination": { 

808 "type": "object", 

809 "description": "Pagination information", 

810 }, 

811 }, 

812 }, 

813 } 

814 

815 @staticmethod 

816 def get_expand_document_tool_schema() -> dict[str, Any]: 

817 """Get the expand document tool schema for lazy loading - uses same format as search.""" 

818 return { 

819 "name": "expand_document", 

820 "description": "Retrieve full document content by document ID for lazy loading", 

821 "annotations": {"read-only": True}, 

822 "inputSchema": { 

823 "type": "object", 

824 "properties": { 

825 "document_id": { 

826 "type": "string", 

827 "description": "The ID of the document to expand and retrieve full content", 

828 }, 

829 "include_metadata": { 

830 "type": "boolean", 

831 "description": "Include detailed metadata (default: true)", 

832 "default": True, 

833 }, 

834 "include_hierarchy": { 

835 "type": "boolean", 

836 "description": "Include hierarchy information for Confluence documents (default: true)", 

837 "default": True, 

838 }, 

839 "include_attachments": { 

840 "type": "boolean", 

841 "description": "Include attachment information if available (default: true)", 

842 "default": True, 

843 }, 

844 }, 

845 "required": ["document_id"], 

846 }, 

847 "outputSchema": { 

848 "type": "object", 

849 "properties": { 

850 "results": { 

851 "type": "array", 

852 "items": { 

853 "type": "object", 

854 "properties": { 

855 "score": {"type": "number"}, 

856 "title": {"type": "string"}, 

857 "content": {"type": "string"}, 

858 "source_type": {"type": "string"}, 

859 "metadata": { 

860 "type": "object", 

861 "properties": { 

862 "file_path": {"type": "string"}, 

863 "project_id": {"type": "string"}, 

864 "created_at": {"type": "string"}, 

865 "last_modified": {"type": "string"}, 

866 }, 

867 }, 

868 }, 

869 }, 

870 }, 

871 "total_found": {"type": "integer"}, 

872 "query_context": { 

873 "type": "object", 

874 "properties": { 

875 "original_query": {"type": "string"}, 

876 "source_types_filtered": { 

877 "type": "array", 

878 "items": {"type": "string"}, 

879 }, 

880 "project_ids_filtered": { 

881 "type": "array", 

882 "items": {"type": "string"}, 

883 }, 

884 }, 

885 }, 

886 }, 

887 }, 

888 } 

889 

890 @classmethod 

891 def get_all_tool_schemas(cls) -> list[dict[str, Any]]: 

892 """Get all tool schemas.""" 

893 return [ 

894 cls.get_search_tool_schema(), 

895 cls.get_hierarchy_search_tool_schema(), 

896 cls.get_attachment_search_tool_schema(), 

897 cls.get_analyze_relationships_tool_schema(), 

898 cls.get_find_similar_tool_schema(), 

899 cls.get_detect_conflicts_tool_schema(), 

900 cls.get_find_complementary_tool_schema(), 

901 cls.get_cluster_documents_tool_schema(), 

902 cls.get_expand_document_tool_schema(), # ✅ Add expand_document tool 

903 cls.get_expand_cluster_tool_schema(), # ✅ Add expand_cluster tool 

904 ]