Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 120 additions & 0 deletions codebase_rag/mcp/client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
"""MCP client for querying the code graph via the MCP server.



This module provides a simple CLI client that connects to the MCP server

and executes the ask_agent tool with a provided question.

"""
Comment on lines +1 to +9
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

According to the project's general rules, docstrings are not allowed. Please remove this module docstring.

References
  1. Docstrings are not allowed in this project, as enforced by a pre-commit hook.


import asyncio
import json
import os
import sys
from typing import Any
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any type is explicitly prohibited. Remove this import and use TypedDict for dict shapes.

Context Used: Rule from dashboard - ## Technical Requirements

Agentic Framework

  • PydanticAI Only: This project uses PydanticAI... (source)
Prompt To Fix With AI
This is a comment left during a code review.
Path: codebase_rag/mcp/client.py
Line: 15

Comment:
`Any` type is explicitly prohibited. Remove this import and use TypedDict for dict shapes.

**Context Used:** Rule from `dashboard` - ## Technical Requirements

### Agentic Framework
- **PydanticAI Only**: This project uses PydanticAI... ([source](https://app.greptile.com/review/custom-context?memory=d4240b05-b763-467a-a6bf-94f73e8b6859))

How can I resolve this? If you propose a fix, please make it concise.


import typer
from mcp import ClientSession
from mcp.client.stdio import StdioServerParameters, stdio_client

app = typer.Typer()


async def query_mcp_server(question: str) -> dict[str, Any]:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dict[str, Any] violates strict typing requirements. Use TypedDict instead:

Suggested change
async def query_mcp_server(question: str) -> dict[str, Any]:
async def query_mcp_server(question: str) -> MCPResponse:

Then define:

class MCPResponse(TypedDict):
    output: str

Context Used: Rule from dashboard - ## Technical Requirements

Agentic Framework

  • PydanticAI Only: This project uses PydanticAI... (source)
Prompt To Fix With AI
This is a comment left during a code review.
Path: codebase_rag/mcp/client.py
Line: 24

Comment:
`dict[str, Any]` violates strict typing requirements. Use TypedDict instead:

```suggestion
async def query_mcp_server(question: str) -> MCPResponse:
```

Then define:
```python
class MCPResponse(TypedDict):
    output: str
```

**Context Used:** Rule from `dashboard` - ## Technical Requirements

### Agentic Framework
- **PydanticAI Only**: This project uses PydanticAI... ([source](https://app.greptile.com/review/custom-context?memory=d4240b05-b763-467a-a6bf-94f73e8b6859))

How can I resolve this? If you propose a fix, please make it concise.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

"""Query the MCP server with a question.



Args:

question: The question to ask about the codebase



Returns:

Dictionary with the response from the server

Comment on lines +25 to +38
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Docstrings are not allowed per the Comment Policy. Code should be self-documenting. Only comments with (H) prefix are allowed.

Context Used: Rule from dashboard - ## Technical Requirements

Agentic Framework

  • PydanticAI Only: This project uses PydanticAI... (source)
Prompt To Fix With AI
This is a comment left during a code review.
Path: codebase_rag/mcp/client.py
Line: 25-38

Comment:
Docstrings are not allowed per the Comment Policy. Code should be self-documenting. Only comments with `(H)` prefix are allowed.

**Context Used:** Rule from `dashboard` - ## Technical Requirements

### Agentic Framework
- **PydanticAI Only**: This project uses PydanticAI... ([source](https://app.greptile.com/review/custom-context?memory=d4240b05-b763-467a-a6bf-94f73e8b6859))

How can I resolve this? If you propose a fix, please make it concise.

"""
Comment on lines +25 to +39
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

According to the project's general rules, docstrings are not allowed. Please remove this function docstring. You can convert it to a regular comment if you wish to keep the explanation.

References
  1. Docstrings are not allowed in this project, as enforced by a pre-commit hook.


# Start the MCP server as a subprocess with stderr redirected to /dev/null

# This suppresses all server logs while keeping stdout/stdin for MCP communication

with open(os.devnull, "w") as devnull:
server_params = StdioServerParameters(
command="python",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Hardcoding command="python" can lead to issues if the user's environment has multiple Python versions or is not on the system's PATH. It's more robust to use sys.executable to ensure the MCP server subprocess runs with the same Python interpreter as the client script.

Suggested change
command="python",
command=sys.executable,

args=["-m", "codebase_rag.main", "mcp-server"],
)

async with stdio_client(server=server_params, errlog=devnull) as (read, write):
async with ClientSession(read, write) as session:
# Initialize the session

await session.initialize()

# Call the ask_agent tool

result = await session.call_tool("ask_agent", {"question": question})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-high high

This line passes the untrusted question directly to the ask_agent tool. If the agent is configured with sensitive tools (like shell access), this represents a significant security risk through prompt injection, especially in non-interactive environments like CI/CD.

References
  1. For security-sensitive features like shell command execution by an LLM agent, prioritize fail-safe behavior. Prefer false positives (blocking a safe command) over false negatives (allowing a dangerous one), especially if the fix for the false positive adds complexity.

Comment on lines +47 to +59
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hardcoded strings should be moved to a constants file. Create codebase_rag/mcp/constants.py for strings like "python", "-m", "codebase_rag.main", "mcp-server", "ask_agent", "question".

Context Used: Rule from dashboard - ## Technical Requirements

Agentic Framework

  • PydanticAI Only: This project uses PydanticAI... (source)
Prompt To Fix With AI
This is a comment left during a code review.
Path: codebase_rag/mcp/client.py
Line: 47-59

Comment:
Hardcoded strings should be moved to a constants file. Create `codebase_rag/mcp/constants.py` for strings like `"python"`, `"-m"`, `"codebase_rag.main"`, `"mcp-server"`, `"ask_agent"`, `"question"`.

**Context Used:** Rule from `dashboard` - ## Technical Requirements

### Agentic Framework
- **PydanticAI Only**: This project uses PydanticAI... ([source](https://app.greptile.com/review/custom-context?memory=d4240b05-b763-467a-a6bf-94f73e8b6859))

How can I resolve this? If you propose a fix, please make it concise.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!


# Extract the response text

if result.content:
response_text = result.content[0].text
Comment on lines +63 to +64
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No type narrowing before accessing result.content[0]. This will raise IndexError if content is empty. Add length check:

Suggested change
if result.content:
response_text = result.content[0].text
if result.content and len(result.content) > 0:
response_text = result.content[0].text
Prompt To Fix With AI
This is a comment left during a code review.
Path: codebase_rag/mcp/client.py
Line: 63-64

Comment:
No type narrowing before accessing `result.content[0]`. This will raise `IndexError` if content is empty. Add length check:

```suggestion
                if result.content and len(result.content) > 0:
                    response_text = result.content[0].text
```

How can I resolve this? If you propose a fix, please make it concise.


# Parse JSON response

try:
parsed = json.loads(response_text)

if isinstance(parsed, dict):
return parsed

return {"output": str(parsed)}

except json.JSONDecodeError:
return {"output": response_text}

return {"output": "No response from server"}


@app.command()
def main(
question: str = typer.Option(
..., "--ask-agent", "-a", help="Question to ask about the codebase"
),
Comment on lines +84 to +86
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-high high

The main function in codebase_rag/mcp/client.py accepts a natural language question via a CLI option and passes it directly to the ask_agent tool on the MCP server. According to the project's architecture (seen in codebase_rag/main.py), the agent has access to highly sensitive tools, including shell_command_tool, file_writer_tool, and file_editor_tool.

The PR description explicitly states that this client is "Useful for scripting and CI pipelines." In such environments, the question input may be derived from untrusted sources, such as Pull Request titles, commit messages, or issue descriptions. An attacker could use prompt injection techniques to manipulate the LLM agent into executing arbitrary shell commands or making unauthorized modifications to the codebase.

Furthermore, unlike the primary CLI implementation in codebase_rag/main.py, this MCP client lacks any confirmation prompts or safety checks (e.g., the confirm_edits_globally logic) before executing potentially destructive operations.

References
  1. For security-sensitive features like shell command execution by an LLM agent, prioritize fail-safe behavior. Prefer false positives (blocking a safe command) over false negatives (allowing a dangerous one), especially if the fix for the false positive adds complexity.

) -> None:
"""Query the code graph via MCP server.



Example:

python -m codebase_rag.mcp.client --ask-agent "What functions call UserService.create_user?"

Comment on lines +88 to +95
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Docstrings are not allowed per the Comment Policy. Code should be self-documenting.

Context Used: Rule from dashboard - ## Technical Requirements

Agentic Framework

  • PydanticAI Only: This project uses PydanticAI... (source)
Prompt To Fix With AI
This is a comment left during a code review.
Path: codebase_rag/mcp/client.py
Line: 88-95

Comment:
Docstrings are not allowed per the Comment Policy. Code should be self-documenting.

**Context Used:** Rule from `dashboard` - ## Technical Requirements

### Agentic Framework
- **PydanticAI Only**: This project uses PydanticAI... ([source](https://app.greptile.com/review/custom-context?memory=d4240b05-b763-467a-a6bf-94f73e8b6859))

How can I resolve this? If you propose a fix, please make it concise.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

"""
Comment on lines +88 to +96
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

According to the project's general rules, docstrings are not allowed. Please remove this function docstring. The example can be moved to a regular comment if you wish to keep it.

References
  1. Docstrings are not allowed in this project, as enforced by a pre-commit hook.


try:
# Run the async query

result = asyncio.run(query_mcp_server(question))

# Print only the output (clean for scripting)

if isinstance(result, dict) and "output" in result:
print(result["output"])

Check failure on line 106 in codebase_rag/mcp/client.py

View workflow job for this annotation

GitHub Actions / Lint & Format

Ruff (T201)

codebase_rag/mcp/client.py:106:13: T201 `print` found

else:
print(json.dumps(result))

Check failure on line 109 in codebase_rag/mcp/client.py

View workflow job for this annotation

GitHub Actions / Lint & Format

Ruff (T201)

codebase_rag/mcp/client.py:109:13: T201 `print` found

except Exception as e:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Catching bare Exception is too broad. Catch specific exceptions like ConnectionError, TimeoutError, or create a custom exception type.

Context Used: Rule from dashboard - ## Technical Requirements

Agentic Framework

  • PydanticAI Only: This project uses PydanticAI... (source)
Prompt To Fix With AI
This is a comment left during a code review.
Path: codebase_rag/mcp/client.py
Line: 111

Comment:
Catching bare `Exception` is too broad. Catch specific exceptions like `ConnectionError`, `TimeoutError`, or create a custom exception type.

**Context Used:** Rule from `dashboard` - ## Technical Requirements

### Agentic Framework
- **PydanticAI Only**: This project uses PydanticAI... ([source](https://app.greptile.com/review/custom-context?memory=d4240b05-b763-467a-a6bf-94f73e8b6859))

How can I resolve this? If you propose a fix, please make it concise.

# Print error to stderr and exit with error code

Comment on lines +41 to +113
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inline comments without (H) prefix violate the Comment Policy. Remove all comments or prefix them with (H) if they provide essential human context that cannot be expressed in code.

Context Used: Rule from dashboard - ## Technical Requirements

Agentic Framework

  • PydanticAI Only: This project uses PydanticAI... (source)
Prompt To Fix With AI
This is a comment left during a code review.
Path: codebase_rag/mcp/client.py
Line: 41-113

Comment:
Inline comments without `(H)` prefix violate the Comment Policy. Remove all comments or prefix them with `(H)` if they provide essential human context that cannot be expressed in code.

**Context Used:** Rule from `dashboard` - ## Technical Requirements

### Agentic Framework
- **PydanticAI Only**: This project uses PydanticAI... ([source](https://app.greptile.com/review/custom-context?memory=d4240b05-b763-467a-a6bf-94f73e8b6859))

How can I resolve this? If you propose a fix, please make it concise.

print(f"Error: {str(e)}", file=sys.stderr)

Check failure on line 114 in codebase_rag/mcp/client.py

View workflow job for this annotation

GitHub Actions / Lint & Format

Ruff (T201)

codebase_rag/mcp/client.py:114:9: T201 `print` found
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use loguru for error logging instead of print() to stderr:

Suggested change
print(f"Error: {str(e)}", file=sys.stderr)
logger.error(f"Error: {str(e)}")
sys.exit(1)

Context Used: Rule from dashboard - ## Technical Requirements

Agentic Framework

  • PydanticAI Only: This project uses PydanticAI... (source)
Prompt To Fix With AI
This is a comment left during a code review.
Path: codebase_rag/mcp/client.py
Line: 114

Comment:
Use `loguru` for error logging instead of `print()` to stderr:

```suggestion
        logger.error(f"Error: {str(e)}")
        sys.exit(1)
```

**Context Used:** Rule from `dashboard` - ## Technical Requirements

### Agentic Framework
- **PydanticAI Only**: This project uses PydanticAI... ([source](https://app.greptile.com/review/custom-context?memory=d4240b05-b763-467a-a6bf-94f73e8b6859))

How can I resolve this? If you propose a fix, please make it concise.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!


sys.exit(1)


if __name__ == "__main__":
app()
Loading