File size: 3,810 Bytes
d557d77
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
"""MCP tool definitions for CodeRAG."""

from typing import Optional

from coderag.mcp.handlers import get_mcp_handlers
from coderag.mcp.server import mcp


@mcp.tool()
async def index_repository(
    url: str,
    branch: str = "",
    include_patterns: Optional[list[str]] = None,
    exclude_patterns: Optional[list[str]] = None,
) -> dict:
    """Index a GitHub repository for code Q&A.

    Args:
        url: GitHub repository URL (e.g., https://github.com/owner/repo)
        branch: Branch to index (defaults to main/master)
        include_patterns: File patterns to include (e.g., ["*.py", "*.ts"])
        exclude_patterns: File patterns to exclude (e.g., ["*_test.py"])

    Returns:
        dict with success status, repo_id, files_processed, and chunks_indexed
    """
    handlers = get_mcp_handlers()
    return await handlers.index_repository(
        url=url,
        branch=branch,
        include_patterns=include_patterns,
        exclude_patterns=exclude_patterns,
    )


@mcp.tool()
async def query_code(
    repo_id: str,
    question: str,
    top_k: int = 5,
) -> dict:
    """Ask questions about indexed code with citations.

    Args:
        repo_id: Repository ID (full or first 8 characters)
        question: Question about the code
        top_k: Number of code chunks to retrieve for context (default: 5)

    Returns:
        dict with answer, citations, evidence, and grounded flag
    """
    handlers = get_mcp_handlers()
    return await handlers.query_code(
        repo_id=repo_id,
        question=question,
        top_k=top_k,
    )


@mcp.tool()
async def list_repositories() -> dict:
    """List all indexed repositories.

    Returns:
        dict with repositories array and count
    """
    handlers = get_mcp_handlers()
    return await handlers.list_repositories()


@mcp.tool()
async def get_repository_info(repo_id: str) -> dict:
    """Get detailed repository information.

    Args:
        repo_id: Repository ID (full or first 8 characters)

    Returns:
        dict with repository metadata including name, url, branch, chunk_count, status, and indexed_files
    """
    handlers = get_mcp_handlers()
    return await handlers.get_repository_info(repo_id=repo_id)


@mcp.tool()
async def delete_repository(repo_id: str) -> dict:
    """Remove an indexed repository.

    Args:
        repo_id: Repository ID (full or first 8 characters)

    Returns:
        dict with success status and chunks_deleted
    """
    handlers = get_mcp_handlers()
    return await handlers.delete_repository(repo_id=repo_id)


@mcp.tool()
async def update_repository(repo_id: str) -> dict:
    """Incremental update of a repository (only changed files).

    Args:
        repo_id: Repository ID (full or first 8 characters)

    Returns:
        dict with success status, files_changed, chunks_added, chunks_deleted
    """
    handlers = get_mcp_handlers()
    return await handlers.update_repository(repo_id=repo_id)


@mcp.tool()
async def search_code(
    repo_id: str,
    query: str,
    top_k: int = 10,
    file_filter: Optional[str] = None,
    chunk_type: Optional[str] = None,
) -> dict:
    """Semantic code search without LLM generation.

    Args:
        repo_id: Repository ID (full or first 8 characters)
        query: Search query
        top_k: Maximum number of results (default: 10)
        file_filter: File pattern filter (e.g., "*.py")
        chunk_type: Filter by chunk type (e.g., "function", "class")

    Returns:
        dict with results array containing file_path, start_line, end_line, content, and relevance_score
    """
    handlers = get_mcp_handlers()
    return await handlers.search_code(
        repo_id=repo_id,
        query=query,
        top_k=top_k,
        file_filter=file_filter,
        chunk_type=chunk_type,
    )