# grep-mcp Dependencies Explained: How aiohttp, Starlette, and uvicorn Power the MCP Server

> Explore how grep-mcp utilizes aiohttp, Starlette, and uvicorn. Understand the roles of these key dependencies in powering the MCP server for efficient API interaction and SSE transport.

- Repository: [gal peretz/grep-mcp](https://github.com/galprz/grep-mcp)
- Tags: internals
- Published: 2026-02-16

---

**TLDR:** The `grep-mcp` project relies on **aiohttp** for asynchronous HTTP requests to the grep.app API, **Starlette** as the ASGI framework handling Server-Sent Events (SSE) transport, and **uvicorn** as the high-performance ASGI server that runs the web application.

`galprz/grep-mcp` is a lightweight MCP (Model Context Protocol) server that exposes the **grep.app** search API to LLMs. Understanding the `grep-mcp` dependencies is essential for developers extending the server or deploying it in production. The project leverages modern Python async libraries to handle external API calls and internal transport mechanisms without blocking the event loop.

## aiohttp: Asynchronous HTTP Client for grep.app API

**aiohttp** provides the asynchronous HTTP client capabilities that allow `grep-mcp` to query the remote grep.app REST API without blocking the server’s event loop.

In [`src/grep_mcp/server.py`](https://github.com/galprz/grep-mcp/blob/main/src/grep_mcp/server.py), the `grep_query` function creates a client session using `aiohttp.ClientSession` with a 30-second timeout. The implementation sends a GET request to `https://grep.app/api/search` with the user’s query parameters【/src/grep_mcp/server.py#L25-L33】【/src/grep_mcp/server.py#L27-L30】.

```python
import aiohttp
import asyncio

async def search_grep(query: str):
    async with aiohttp.ClientSession(timeout=aiohttp.ClientTimeout(total=30)) as session:
        url = "https://grep.app/api/search"
        params = {"q": query}
        async with session.get(url, params=params) as resp:
            data = await resp.json()
            return data

# Example usage

result = asyncio.run(search_grep("asyncio"))
print(result)

```

This pattern ensures that while waiting for the grep.app API to respond, the MCP server can handle other concurrent operations.

## Starlette: ASGI Framework for SSE Transport

**Starlette** supplies the ASGI web framework used when `grep-mcp` runs in SSE (Server-Sent Events) transport mode. It handles HTTP routing, request/response objects, and mounts the SSE endpoint.

The `create_starlette_app` function in [`src/grep_mcp/server.py`](https://github.com/galprz/grep-mcp/blob/main/src/grep_mcp/server.py) instantiates a `Starlette` application, registers the `/sse` route, and mounts the message handler under `/messages/`【/src/grep_mcp/server.py#L61-L64】【/src/grep_mcp/server.py#L98-L105】.

When the `--transport sse` flag is passed, the server uses Starlette to expose the MCP protocol over HTTP, allowing clients to connect via Server-Sent Events rather than standard input/output.

## uvicorn: High-Performance ASGI Server

**uvicorn** serves as the ASGI server that runs the Starlette application. It listens on the configured host and port and drives the event loop for the SSE transport mode.

In the `main()` function of [`src/grep_mcp/server.py`](https://github.com/galprz/grep-mcp/blob/main/src/grep_mcp/server.py), the code checks for the `sse` transport option and calls `uvicorn.run` to launch the web server【/src/grep_mcp/server.py#L38-L42】.

```bash

# Run in stdio mode (default) - does not use Starlette or uvicorn

python -m grep_mcp --transport stdio

# Run in SSE mode - uses Starlette and uvicorn

python -m grep_mcp --transport sse --host 0.0.0.0 --port 8080

```

When running in SSE mode, uvicorn handles the low-level HTTP protocol and concurrency, while Starlette manages the application logic.

## Dependency Declaration and Installation

All three dependencies are declared in [`pyproject.toml`](https://github.com/galprz/grep-mcp/blob/main/pyproject.toml) under the project dependencies section【/pyproject.toml#L27-L32】. The `mcp` library is also included as the fourth core dependency that implements the MCP protocol itself, but the three libraries above handle the networking and transport layers.

To install these dependencies:

```bash
pip install aiohttp starlette uvicorn

```

Or install the complete package:

```bash
pip install grep-mcp

```

## How the Dependencies Work Together

The `grep-mcp` dependencies form a layered architecture:

1. **aiohttp** operates at the data layer, fetching search results from the external grep.app API asynchronously.
2. **Starlette** operates at the transport layer, providing the HTTP framework when SSE mode is enabled.
3. **uvicorn** operates at the server layer, executing the ASGI application and managing the event loop.

In **stdio mode** (the default), only **aiohttp** is active, as the MCP protocol communicates over standard input/output. In **SSE mode**, all three libraries collaborate: uvicorn runs the Starlette app, which exposes the SSE endpoint, while aiohttp continues to query the external API.

## Summary

- **aiohttp** provides the asynchronous HTTP client for querying the grep.app API without blocking the event loop, implemented in [`src/grep_mcp/server.py`](https://github.com/galprz/grep-mcp/blob/main/src/grep_mcp/server.py) within the `grep_query` function.
- **Starlette** serves as the ASGI framework for SSE transport mode, handling HTTP routing and endpoint mounting via `create_starlette_app`.
- **uvicorn** acts as the high-performance ASGI server that runs the Starlette application when `--transport sse` is specified, launched in the `main()` function.
- These dependencies are declared in [`pyproject.toml`](https://github.com/galprz/grep-mcp/blob/main/pyproject.toml) and enable `grep-mcp` to operate in both stdio and HTTP/SSE modes.

## Frequently Asked Questions

### What is the difference between stdio and SSE mode in grep-mcp?

In **stdio mode** (the default), the MCP server communicates over standard input and output streams, making it ideal for local integration with LLM clients. This mode only requires **aiohttp** for external API calls. In **SSE mode**, the server exposes an HTTP endpoint using **Starlette** and **uvicorn**, enabling remote clients to connect via Server-Sent Events over the network.

### Why does grep-mcp use aiohttp instead of the standard requests library?

**aiohttp** is an asynchronous HTTP client that integrates with Python's `asyncio` event loop. Since `grep-mcp` is built as an async MCP server, using `aiohttp` prevents blocking the event loop when querying the grep.app API. This allows the server to remain responsive to other concurrent operations while waiting for external API responses, which would not be possible with the synchronous `requests` library.

### Can I run grep-mcp without installing Starlette and uvicorn?

Yes, if you only intend to use **stdio mode** (the default transport), you can technically run the core functionality without Starlette and uvicorn, as these are only imported when the `--transport sse` flag is used. However, both libraries are declared as mandatory dependencies in [`pyproject.toml`](https://github.com/galprz/grep-mcp/blob/main/pyproject.toml), so they will be installed by default. To run in SSE mode, both are strictly required.

### Where are the dependency versions specified for grep-mcp?

The dependency specifications are located in the [`pyproject.toml`](https://github.com/galprz/grep-mcp/blob/main/pyproject.toml) file at the repository root, specifically within the `[project]` section under `dependencies`【/pyproject.toml#L27-L32】. This file lists **aiohttp**, **starlette**, **uvicorn**, and the **mcp** library along with their version constraints, ensuring compatible versions are installed when deploying the server.