Skip to content
This repository was archived by the owner on Jun 3, 2026. It is now read-only.

Commit 0d3785c

Browse files
authored
Merge pull request #130 from XortexAI/ishaan/dev
add tools for mcp
2 parents 332db1e + ccf27f0 commit 0d3785c

2 files changed

Lines changed: 65 additions & 0 deletions

File tree

‎src/api/routes/code.py‎

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
APIResponse,
2323
CodeQueryRequest,
2424
CodeQueryResponse,
25+
ExecuteToolRequest,
26+
ExecuteToolResponse,
2527
DirectoryNode,
2628
DirectoryTreeResponse,
2729
RepoListResponse,
@@ -123,6 +125,55 @@ async def code_query_stream(req: CodeQueryRequest, request: Request):
123125
)
124126

125127

128+
# ═══════════════════════════════════════════════════════════════════════════
129+
# POST /v1/code/execute-tool
130+
# ═══════════════════════════════════════════════════════════════════════════
131+
132+
@router.post(
133+
"/execute-tool",
134+
response_model=APIResponse,
135+
summary="Execute a raw native tool (like search_symbols or impact_analysis) natively",
136+
)
137+
async def execute_tool(req: ExecuteToolRequest, request: Request, user: dict = Depends(require_api_key)):
138+
start = time.perf_counter()
139+
username = user.get("username") or user.get("name") or user.get("id") or req.user_id
140+
141+
# Enforce privacy check!
142+
from src.api.routes.scanner import _scanner_chat_allowed
143+
store = _get_code_store()
144+
denied = _scanner_chat_allowed(store, username, req.org_id, req.repo)
145+
if denied:
146+
return _error(request, f"Permission Denied: {denied}", 403, 0)
147+
148+
pipeline = get_code_pipeline(org_id=req.org_id, repo=req.repo)
149+
150+
try:
151+
results = await pipeline._execute_tool(
152+
tool_name=req.tool_name,
153+
tool_args=req.tool_args,
154+
repo=req.repo,
155+
top_k=req.top_k,
156+
user_id=username,
157+
)
158+
159+
data = ExecuteToolResponse(
160+
records=[
161+
SourceRecord(
162+
domain=s.domain, content=s.content,
163+
score=round(s.score, 3), metadata=s.metadata,
164+
)
165+
for s in results
166+
]
167+
)
168+
elapsed = round((time.perf_counter() - start) * 1000, 2)
169+
return _wrap(request, data, elapsed)
170+
171+
except Exception as exc:
172+
elapsed = round((time.perf_counter() - start) * 1000, 2)
173+
logger.exception("Execute tool failed for org=%s repo=%s tool=%s", req.org_id, req.repo, req.tool_name)
174+
return _error(request, str(exc), 500, elapsed)
175+
176+
126177
# ═══════════════════════════════════════════════════════════════════════════
127178
# GET /v1/code/directory-tree
128179
# ═══════════════════════════════════════════════════════════════════════════

‎src/api/schemas.py‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,20 @@ class CodeQueryResponse(BaseModel):
206206
confidence: float = 0.0
207207

208208

209+
class ExecuteToolRequest(BaseModel):
210+
"""Execute a specific raw code retrieval tool natively."""
211+
org_id: str = Field(..., min_length=1, max_length=256)
212+
repo: str = Field(..., min_length=1, max_length=256)
213+
tool_name: str = Field(..., min_length=1, max_length=128)
214+
tool_args: Dict[str, Any] = Field(default_factory=dict)
215+
user_id: str = Field(default="", max_length=256)
216+
top_k: int = Field(default=10, ge=1, le=50)
217+
218+
219+
class ExecuteToolResponse(BaseModel):
220+
records: List[SourceRecord] = Field(default_factory=list)
221+
222+
209223
class DirectoryNode(BaseModel):
210224
name: str
211225
type: str = "file"

0 commit comments

Comments
 (0)