rag-mcp-azure
A lightweight RAG server deployed on Azure Container Apps that ingests PDFs, creates embeddings, and exposes a search_documents tool over MCP for retrieving relevant document chunks.
README
RAG MCP Azure - Lightweight Retrieval-Augmented Generation Service
A production-ready Retrieval-Augmented Generation (RAG) API deployed on Azure Container Apps. Built for efficiency with a CPU-only footprint, in-memory vector storage, Azure Blob Storage ingestion, and full MCP protocol compatibility β verified end-to-end.
π― Project Overview
What it does:
- Ingests PDF documents from Azure Blob Storage (with local folder fallback for development)
- Chunks and embeds them using sentence transformers
- Stores embeddings in FAISS (in-memory vector store)
- Serves FastAPI HTTP endpoints for document retrieval, reindexing, and ad-hoc PDF upload
- Exposes a real, tested MCP (Model Context Protocol) server over Streamable HTTP
- Returns only relevant document context (no final LLM synthesis β kept client-side by design)
Design philosophy:
- Lightweight: Optimized for 8 GB RAM, CPU-only environments
- Serverless: Deployed on Azure Container Apps (auto-scaling, managed infrastructure)
- Cost-effective: No heavy vector databases or GPU requirements
- Production-ready: Automated CI/CD with GitHub Actions, tested REST endpoints, and a verified MCP integration
π Tech Stack
| Component | Technology | Notes |
|---|---|---|
| Framework | FastAPI + Uvicorn | Async HTTP server |
| RAG Engine | LangChain + FAISS | PDF loading, text splitting, embeddings, vector search |
| Embeddings | HuggingFace Sentence Transformers | CPU-optimized models (all-MiniLM-L6-v2) |
| Document Storage | Azure Blob Storage | Source of truth for PDFs in production |
| MCP Server | MCP SDK v2 (mcp.server.mcpserver), Streamable HTTP transport | Real, tested tool interface for agentic retrieval |
| Containerization | Docker | CPU-optimized image (Python 3.12-slim, no GPU torch) |
| Orchestration | Azure Container Apps | Managed, auto-scaling, ingress |
| Container Registry | Azure Container Registry (ACR) | Image storage and management |
| CI/CD | GitHub Actions | Automated tests, build, push, and idempotent deploy |
ποΈ Project Structure
rag-mcp-azure/
βββ app/
β βββ data/ # PDF documents for local dev (fallback)
β β βββ *.pdf
β βββ main.py # FastAPI app + MCP server (mount, lifespan, security)
β βββ rag_engine.py # RAG logic (Blob/local ingestion, chunking, search)
βββ tests/
β βββ test_api.py # REST endpoint tests (run in CI)
β βββ test_mcp_integration.py # Real MCP client tests (manual, live server required)
βββ .github/
β βββ workflows/
β βββ deploy.yml # GitHub Actions CI/CD pipeline
βββ scripts/
β βββ deploy-aca.sh # Manual Azure deployment script
βββ Dockerfile # Production image definition
βββ .dockerignore
βββ .gitignore
βββ pytest.ini # Test markers and asyncio config
βββ requirements.txt
βββ README.md
π MCP Protocol Integration
What is MCP?
Model Context Protocol (MCP) is an open standard for connecting AI agents to external tools and data sources. Instead of embedding knowledge retrieval inside an LLM, MCP exposes it as a discoverable tool that any compatible agent (Claude, Gemini, custom LLMs) can invoke over a standard transport.
Key advantage for interviews: Demonstrates a real, working implementation of an emerging agentic AI standard, verified end-to-end with the official MCP client SDK β not just a REST API with an MCP label attached.
Transport & Endpoint
This server exposes MCP over Streamable HTTP (the modern MCP transport, superseding SSE), mounted on the same FastAPI app that serves the REST endpoints.
| Environment | MCP endpoint |
|---|---|
| Local | http://localhost:8000/mcp-server/mcp |
| Production | https://rag-mcp-azure.redsand-f0795bb6.francecentral.azurecontainerapps.io/mcp-server/mcp |
The MCP session manager is initialized via FastAPI's lifespan, so it starts and stops cleanly alongside the web server (see app/main.py).
Exposed Tool
| Tool | Input | Output | Purpose |
|---|---|---|---|
search_documents |
query: string |
Document chunks (top-3 by relevance) | Search the RAG knowledge base |
Tool Schema
{
"tools": [
{
"name": "search_documents",
"description": "Search the RAG knowledge base for relevant document chunks matching a query.",
"inputSchema": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "The search query to find relevant document chunks (e.g., 'What is the contract duration?')"
}
},
"required": ["query"]
}
}
]
}
A note on testing with curl
A plain curl GET request to the MCP endpoint returns a 400 Bad Request with a JSON-RPC error:
{"jsonrpc":"2.0","id":null,"error":{"code":-32600,"message":"Bad Request: Missing session ID"}}
This is expected, not a bug. MCP over Streamable HTTP requires a session handshake before any tool call β curl alone doesn't perform this. This response confirms the server correctly speaks the MCP JSON-RPC protocol; it's just rejecting an incomplete request. A real MCP client handles this handshake automatically.
DNS Rebinding Protection
The MCP Python SDK enables DNS rebinding protection by default, restricting the Host header to localhost/127.0.0.1 unless explicitly configured otherwise. Since this server is deployed on a public Azure domain, TransportSecuritySettings is configured in app/main.py to explicitly allow both local development hosts and the production Azure Container Apps hostname:
security_settings = TransportSecuritySettings(
enable_dns_rebinding_protection=True,
allowed_hosts=[
"127.0.0.1:*", "localhost:*", "[::1]:*",
"rag-mcp-azure.redsand-f0795bb6.francecentral.azurecontainerapps.io",
],
allowed_origins=[
"http://127.0.0.1:*", "http://localhost:*", "http://[::1]:*",
"https://rag-mcp-azure.redsand-f0795bb6.francecentral.azurecontainerapps.io",
],
)
Without this, requests to the production URL fail with 421 Misdirected Request: Invalid Host header β the protection is working correctly, it just needs the production host explicitly allow-listed.
Connect with an MCP Client
Claude Desktop (claude_desktop_config.json β on Windows: %APPDATA%\Claude\claude_desktop_config.json):
{
"mcpServers": {
"rag-mcp-azure": {
"url": "https://rag-mcp-azure.redsand-f0795bb6.francecentral.azurecontainerapps.io/mcp-server/mcp"
}
}
}
(Exact config keys depend on your MCP client version β some clients use url, others require a transport: "streamable_http" field. Check your client's MCP documentation if the connection fails.)
Python MCP client β verified working end-to-end against production:
import asyncio
from mcp.client.streamable_http import streamable_http_client
from mcp import ClientSession
async def test_search():
url = "https://rag-mcp-azure.redsand-f0795bb6.francecentral.azurecontainerapps.io/mcp-server/mcp"
async with streamable_http_client(url) as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
tools = await session.list_tools()
print(f"Available tools: {[t.name for t in tools.tools]}")
result = await session.call_tool(
"search_documents", {"query": "durΓ©e maximale contrat intΓ©rimaire"}
)
for content in result.content:
if hasattr(content, "text"):
print(content.text)
asyncio.run(test_search())
Sample output:
Available tools: ['search_documents']
Extrait 1:
Article 26
Β§1er. Par poste de travail, pas plus de trois tentatives, de maximum six mois par intΓ©rimaire...
Automated Integration Testing
tests/test_mcp_integration.py contains automated tests using the same client flow, marked with @pytest.mark.integration and excluded from the CI pipeline (since they require a live deployed server and shouldn't run against a service mid-deployment). Run them manually with:
pytest tests/test_mcp_integration.py -v
Or against a local instance:
$env:MCP_TEST_URL="http://localhost:8000/mcp-server/mcp"
pytest tests/test_mcp_integration.py -v
Known limitation
The MCP mount path (/mcp-server/mcp) is a workaround for a routing conflict between the MCP SDK's internal /mcp route and FastAPI's REST routes at root level. A cleaner path structure is a possible future improvement, but the current setup is fully functional and tested end-to-end.
π Quick Start
Local Development
1. Clone and setup:
git clone https://github.com/oumniya03/rag-mcp-azure.git
cd rag-mcp-azure
python -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\Activate
pip install -r requirements.txt
2. Add PDF documents (local dev fallback, used when BLOB_CONTAINER_URL is not set):
cp your-documents.pdf app/data/
3. Run locally:
python -m uvicorn app.main:app --host 0.0.0.0 --port 8000
4. Test the endpoints:
Health check:
curl http://localhost:8000/health
# Response: {"status":"ok"}
RAG query:
curl -X POST http://localhost:8000/query \
-H "Content-Type: application/json" \
-d '{"query":"What is the contract duration?"}'
Response format:
{
"query": "What is the contract duration?",
"context_extrait": "Excerpt 1:\n...\n\nExcerpt 2:\n..."
}
π³ Docker
Build locally
docker build -t rag-mcp-azure:latest .
Run locally
docker run --rm -p 8000:8000 rag-mcp-azure:latest
Image size optimization
- Base image:
python:3.12.8-slim(~150 MB) - Torch: CPU-only wheel (no CUDA libraries)
- Cache layers: Maximize reuse during builds
- Result: ~500 MB final image (compressed on ACR)
π¦ Azure Blob Storage Integration
This service ingests documents from Azure Blob Storage in production. This is the recommended approach β PDFs live outside the Docker image, so the knowledge base can be updated without a rebuild.
Architecture
ββββββββββββββββββββββββββββββββββββββββ
β Azure Blob Storage (documents/) β
β - travail_interimaire.pdf β
ββββββββββββββββββββ¬ββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββ
β RAG Engine β
β (rag_engine.py) β
β - Download to temp β
β file (PyPDFLoader β
β needs a real path) β
β - Chunk & embed β
ββββββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββ
β FAISS Index β
β (in-memory) β
ββββββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββ
β FastAPI Endpoints β
β /query, /reindex, β
β /upload β
ββββββββββββββββββββββββ
Setup Instructions
1. Create a storage account and container:
az storage account create --name ragmcpstorage26 --resource-group rg-rag-mcp-azure --location francecentral --sku Standard_LRS
az storage container create --name documents --account-name ragmcpstorage26 --auth-mode login
The container name is hardcoded as
"documents"inrag_engine.pyβ keep this name or update the code if you change it.
2. Upload PDF files:
az storage blob upload-batch --destination documents --source app/data --account-name ragmcpstorage26 --auth-mode key
3. Store the connection string as a Container App secret (not a plaintext env var):
$connString = az storage account show-connection-string --name ragmcpstorage26 --resource-group rg-rag-mcp-azure --query connectionString -o tsv
az containerapp secret set --name rag-mcp-azure --resource-group rg-rag-mcp-azure --secrets "blob-connection-string=$connString"
az containerapp update --name rag-mcp-azure --resource-group rg-rag-mcp-azure --set-env-vars "BLOB_CONTAINER_URL=secretref:blob-connection-string"
Important: this configuration is also codified in
.github/workflows/deploy.yml(see below) so it persists across every automated deployment β setting it manually alone would be overwritten by the nextgit push.
4. Trigger reindexing after adding new PDFs:
curl -X POST https://rag-mcp-azure.redsand-f0795bb6.francecentral.azurecontainerapps.io/reindex
# Response: {"status": "RΓ©indexation rΓ©ussie."}
How it Works
- On startup: If
BLOB_CONTAINER_URLis set, the service downloads all PDFs from thedocumentscontainer in Blob Storage to temporary files (PyPDFLoaderrequires a real file path, not an in-memory stream) and indexes them. Otherwise, it falls back to the localapp/data/folder. - On
/reindexcall: The service re-downloads all documents from Blob Storage and rebuilds the FAISS index from scratch. - Ephemeral uploads: Documents uploaded via
/uploadare added to the in-memory index only β they are not persisted to Blob Storage and will be lost on restart or on the next/reindexcall (which rebuilds from Blob Storage/local files only).
A real debugging lesson: BytesIO vs PyPDFLoader
An early version of this integration passed downloaded blob bytes directly to PyPDFLoader(BytesIO(blob_data)), which fails silently with File path <_io.BytesIO object> is not a valid file or url β PyPDFLoader requires an actual file path. The fix: write blob bytes to a tempfile.NamedTemporaryFile first, then load from that path, deleting it afterward. This is implemented in rag_engine.py.
βοΈ Azure Deployment
Current Production Environment
Live URL: https://rag-mcp-azure.redsand-f0795bb6.francecentral.azurecontainerapps.io
Resources:
- Container App Name:
rag-mcp-azure - Resource Group:
rg-rag-mcp-azure - ACA Environment:
cae-rag-mcp-azure - Region: France Central
- ACR:
ragmcpacr26(inrg-rag-mcp-ne) - Blob Storage:
ragmcpstorage26(container:documents) - Compute: 0.5 CPU, 1.0 Gi memory
GitHub Secrets (Required)
Set these in your GitHub repository settings (Settings β Secrets and variables β Actions):
| Secret | Description |
|---|---|
AZURE_CREDENTIALS |
Service principal JSON (from az ad sp create-for-rbac --sdk-auth) |
ACR_USERNAME |
ACR admin username (from az acr credential show) |
ACR_PASSWORD |
ACR admin password (from az acr credential show) |
BLOB_CONNECTION_STRING |
Azure Blob Storage connection string, re-applied as a Container App secret on every deploy |
Deployment Pipeline
The workflow .github/workflows/deploy.yml runs on every push to main:
- Checkout code
- Python setup (3.12) and dependency install
- Run tests (
pytest tests/ -v -m "not integration"β REST endpoint tests only; MCP integration tests are excluded since they require a live server) - Azure login (service principal)
- Docker Buildx setup, login to ACR, build & push image
- Verify the Container Apps environment exists
- Deploy: if the Container App already exists,
az containerapp secret set(refreshing the Blob Storage secret) followed byaz containerapp update; otherwiseaz containerapp createwith the secret and image set from scratch β this idempotent logic prevents accidentally wiping the app's configuration on redeploy
Deploy on push:
git push origin main # Triggers the workflow
Manual deploy (if needed):
bash scripts/deploy-aca.sh
π‘ API Endpoints
GET /health
Health check endpoint.
Response:
{"status": "ok"}
POST /query
Retrieve document context for a given query.
Request:
{"query": "your question here"}
Response:
{
"query": "your question here",
"context_extrait": "Excerpt 1:\n...\n\nExcerpt 2:\n...\n\nExcerpt 3:\n..."
}
POST /reindex
Refresh the in-memory FAISS index from Blob Storage (if configured) or local files.
curl -X POST http://localhost:8000/reindex
# Response: {"status": "RΓ©indexation rΓ©ussie."}
Use case: After uploading new PDFs to Blob Storage, call this endpoint to update the search index without restarting the service.
POST /upload
Upload a PDF document and add it to the RAG index (ephemeral, in-memory only).
curl -X POST http://localhost:8000/upload \
-F "file=@your-document.pdf"
Response:
{
"status": "Succès: 42 chunks ajoutés à l'index.",
"success": true,
"filename": "your-document.pdf"
}
Important: Uploaded documents are lost on restart or on the next /reindex call. To persist documents permanently, upload them directly to Blob Storage instead.
MCP Endpoint (/mcp-server/mcp)
See the MCP Protocol Integration section above.
π§ Configuration
Environment variables
BLOB_CONTAINER_URL(optional): Azure Blob Storage connection string. If set, documents load from thedocumentsBlob container instead of local files. In production this is injected via a Container App secret reference, never as plaintext.
Local tweaking
Edit app/rag_engine.py to customize:
DATA_DIR: local PDF fallback folderchunk_size/chunk_overlap: passed toRecursiveCharacterTextSplitter(default: 500 / 50)k: number of results returned bysearch()(default: 3)- Embedding model: change the
HuggingFaceEmbeddingsmodel name
π Key Files Explained
app/main.py
- FastAPI application with four REST endpoints (
/health,/query,/reindex,/upload) - MCP server (Streamable HTTP) mounted at
/mcp-server/mcp, exposing thesearch_documentstool - FastAPI
lifespanmanages the MCP session manager's async lifecycle (required β without it, MCP requests fail withRuntimeError: Task group is not initialized) TransportSecuritySettingsconfigured to allow the production Azure host (DNS rebinding protection)
app/rag_engine.py
SimpleRAGEngineclass: orchestrates the RAG pipelineinitialize_store(): loads PDFs from Blob Storage or local folder, chunks, embeds, indexes_load_documents_from_blob(): downloads blobs to temp files before parsing (see PyPDFLoader note above)add_documents_from_bytes(): powers/upload(ephemeral, in-memory only)ingest(): powers/reindexsearch(): FAISS similarity search, returns raw context (no LLM synthesis)
Dockerfile
- CPU-only PyTorch wheel (no CUDA libraries)
- Minimal layer footprint,
python:3.12.8-slimbase - Runs as non-root user
.github/workflows/deploy.yml
- Runs REST tests, builds and pushes the Docker image, deploys idempotently to Azure Container Apps
- Re-applies the Blob Storage secret on every deploy so it survives redeployment
π§ͺ Testing
Automated tests (CI)
pytest tests/ -v -m "not integration"
15 tests covering /health, /query, /reindex, /upload β runs automatically in GitHub Actions on every push to main.
MCP integration tests (manual, requires a live server)
pytest tests/test_mcp_integration.py -v
3 tests using the real MCP client SDK: session handshake, tool discovery, and tool invocation β run against production by default (override with the MCP_TEST_URL environment variable).
Production endpoint test (PowerShell)
Invoke-RestMethod -Uri "https://rag-mcp-azure.redsand-f0795bb6.francecentral.azurecontainerapps.io/health"
$body = @{query="test"} | ConvertTo-Json
Invoke-RestMethod -Method Post -Uri "https://rag-mcp-azure.redsand-f0795bb6.francecentral.azurecontainerapps.io/query" -ContentType "application/json" -Body $body
PowerShell note:
Invoke-RestMethod/Invoke-WebRequestsometimes mis-encode accented characters (Γ©, Γ¨) typed directly in a query string, showing mojibake likedurΓΒ©ein the terminal. This is a display artifact of PowerShell 5.1, not a server-side bug β the API itself handles UTF-8 correctly (verified against production).
π Azure Prerequisites (First-time setup)
1. Register required providers (one-time)
az provider register --namespace Microsoft.App --wait
az provider register --namespace Microsoft.ContainerRegistry --wait
az provider register --namespace Microsoft.Storage --wait
2. Create service principal
az ad sp create-for-rbac --name "rag-mcp-github" --role Contributor --sdk-auth
# Copy the JSON output β set as AZURE_CREDENTIALS secret in GitHub
3. Enable ACR admin account
az acr update --name ragmcpacr26 --admin-enabled true
az acr credential show --name ragmcpacr26
# Copy username/password β set as ACR_USERNAME, ACR_PASSWORD secrets in GitHub
4. Verify ACA environment
az containerapp env list -o table
# Should show: cae-rag-mcp-azure in rg-rag-mcp-azure, France Central
Note: an Azure subscription can only have one global Container App Environment by default. Reuse the existing one rather than creating a new one β attempting to create a second will fail with
MaxNumberOfGlobalEnvironmentsInSubExceeded.
βοΈ Troubleshooting
Docker build fails
- Check
requirements.txtfor incompatible packages - Ensure Python 3.12 compatibility
- Review Dockerfile for typos
GitHub Actions workflow fails
- Check all four secrets are set in repository settings
- Verify ACR admin is enabled
- Run
az containerapp env showlocally to confirm the environment exists az containerapp createdoes not accept a--locationparameter β location is inherited from the environment
Blob Storage authentication errors (401, MissingSubscriptionRegistration)
- Ensure
Microsoft.Storageprovider is registered (see Prerequisites above) - Blob upload via Azure CLI requires either
--auth-mode keyor an RBAC role like "Storage Blob Data Contributor" assigned to your account with--auth-mode login
MCP endpoint returns 421 Misdirected Request
- The production host isn't in
TransportSecuritySettings.allowed_hostsβ see the DNS Rebinding Protection section above
MCP endpoint returns 500 Internal Server Error: Task group is not initialized
- The MCP session manager wasn't started via FastAPI's
lifespanβ a plainapp.mount()alone is not enough
/query endpoint returns empty context
- Check that PDFs exist in Blob Storage (or
app/data/for local fallback) - Check startup logs for
Base vectorielle prΓͺte ! - Try
/reindexto force a rebuild
π Performance & Constraints
| Metric | Value |
|---|---|
| Target RAM | 8 GB |
| Deployment CPU | 0.5 CPU |
| Deployment Memory | 1.0 Gi |
| Embedding Model | all-MiniLM-L6-v2 (33 MB) |
| Torch | CPU-only wheel |
| Max PDF size | Limited by available RAM |
| Vector search K | 3 results (configurable) |
π Security & Future Improvements
Current Security Architecture
- β Secrets Management: GitHub repository secrets for Azure, ACR, and Blob Storage credentials β never committed to source
- β
Container App Secrets: Blob Storage connection string stored as a Container App secret (
secretref), not a plaintext environment variable - β Network Isolation: Azure Container Apps runs in a managed environment with ingress control
- β Service Principal: Deployment uses an Azure AD service principal (not the subscription owner account)
- β API Validation: FastAPI validates all request schemas with Pydantic
- β MCP DNS Rebinding Protection: explicitly scoped to known hosts rather than disabled
- β Key rotation practiced: the Blob Storage account key was rotated after being inadvertently exposed in application logs during initial debugging β a concrete lesson in why secrets should never be logged, even for troubleshooting
Known Limitations & Planned Improvements
1. ACR Authentication (Priority: Medium)
Current approach: Admin username/password stored in GitHub Secrets.
Limitation: Credentials are long-lived and stored as plaintext secrets.
Recommended improvement: Migrate to OIDC Federated Authentication between GitHub Actions and Azure β short-lived tokens, no stored credentials to rotate, native Azure AD audit trail.
# Future
- uses: azure/login@v2
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
How to implement:
- Create an Azure Entra ID application
- Configure federated credentials for this GitHub repo
- Store client ID, tenant ID, subscription ID as secrets
- Update
deploy.ymlto use OIDC-basedazure/login@v2 - Remove the
AZURE_CREDENTIALSand ACR admin secrets
Resources: GitHub OIDC in Azure Β· azure/login OIDC support
2. Additional Enhancements
- [ ] Persist ephemeral
/uploaddocuments to Blob Storage instead of memory-only - [ ] API authentication (API key or Bearer token) on
/queryand/upload - [ ] Rate limiting
- [ ] Observability via Azure Application Insights (latency, error rate, request volume)
- [ ] Multi-region deployment for high availability
π£οΈ Roadmap
- [x] Real MCP protocol support with end-to-end client verification
- [x] Azure Blob Storage document pipeline
- [x] Automated REST + MCP integration tests
- [ ] Add LLM endpoint for final answer synthesis
- [ ] Support multiple file formats (DOCX, TXT, etc.)
- [ ] API authentication
- [ ] OIDC federated auth for CI/CD
- [ ] Application Insights monitoring
- [ ] Support external vector database (Pinecone, Weaviate) for larger corpora
π License
This project is provided as-is for educational and portfolio purposes.
π€ Author
Oumniya Moutaouakil β AI Engineer, LLM/Agentic AI & RAG Systems.
Project Status: β Production-Ready β deployed on Azure Container Apps, REST + MCP endpoints verified end-to-end against production.
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.
E2B
Using MCP to run code via e2b.