surreal-mcp
# SurrealDB MCP Server
<div align="center">
<img src="assets/images/surreal-logo.jpg" alt="SurrealDB Logo" width="200">
**A Model Context Protocol (MCP) server that enables AI assistants to interact with SurrealDB databases**
[](https://github.com/YOUR_USERNAME/surreal-mcp/actions/workflows/test.yml)
[](https://www.python.org/downloads/)
[](https://github.com/jlowin/fastmcp)
[](https://surrealdb.com/)
</div>
<a href="https://glama.ai/mcp/servers/@lfnovo/surreal-mcp">
<img width="380" height="200" src="https://glama.ai/mcp/servers/@lfnovo/surreal-mcp/badge" alt="surreal-mcp MCP server" />
</a>
## =� Overview
The SurrealDB MCP Server bridges the gap between AI assistants and SurrealDB, providing a standardized interface for database operations through the Model Context Protocol. This enables LLMs to:
- Execute complex SurrealQL queries
- Perform CRUD operations on records
- Manage graph relationships
- Handle bulk operations efficiently
- Work with SurrealDB's unique features like record IDs and graph edges
## Features
- **Full SurrealQL Support**: Execute any SurrealQL query directly
- **Comprehensive CRUD Operations**: Create, read, update, delete with ease
- **Graph Database Operations**: Create and traverse relationships between records
- **Bulk Operations**: Efficient multi-record inserts
- **Smart Updates**: Full updates, merges, and patches
- **Type-Safe**: Proper handling of SurrealDB's RecordIDs
- **Connection Pooling**: Efficient database connection management
- **Multi-Database Support**: Override namespace/database per tool call
- **Detailed Documentation**: Extensive docstrings for AI comprehension
## =� Prerequisites
- Python 3.10 or higher
- SurrealDB instance (local or remote)
- MCP-compatible client (Claude Desktop, MCP CLI, etc.)
## =� Installation
### Using uvx (Simplest - No Installation Required)
```bash
# Run directly from PyPI (once published)
uvx surreal-mcp
# Or run from GitHub
uvx --from git+https://github.com/yourusername/surreal-mcp.git surreal-mcp
```
### Using uv (Recommended for Development)
```bash
# Clone the repository
git clone https://github.com/yourusername/surreal-mcp.git
cd surreal-mcp
# Install dependencies
uv sync
# Run the server (multiple ways)
uv run surreal-mcp
# or
uv run python -m surreal_mcp
# or
uv run python main.py
```
### Using pip
```bash
# Clone the repository
git clone https://github.com/yourusername/surreal-mcp.git
cd surreal-mcp
# Create virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install package
pip install -e .
# Run the server
surreal-mcp
# or
python -m surreal_mcp
```
## � Configuration
The server uses environment variables for configuration.
### Required Variables (at startup)
| Variable | Description | Example |
|----------|-------------|---------|
| `SURREAL_URL` | SurrealDB connection URL | `ws://localhost:8000/rpc` |
| `SURREAL_USER` | Database username | `root` |
| `SURREAL_PASSWORD` | Database password | `root` |
### Optional Variables (can be overridden per tool call)
| Variable | Description | Example |
|----------|-------------|---------|
| `SURREAL_NAMESPACE` | Default SurrealDB namespace | `test` |
| `SURREAL_DATABASE` | Default SurrealDB database | `test` |
> **Note**: If `SURREAL_NAMESPACE` and `SURREAL_DATABASE` are not set as environment variables, you must provide `namespace` and `database` parameters in each tool call.
### Setting Environment Variables
You can copy `.env.example` to `.env` and update with your values:
```bash
cp .env.example .env
# Edit .env with your database credentials
```
Or set them manually:
```bash
export SURREAL_URL="ws://localhost:8000/rpc"
export SURREAL_USER="root"
export SURREAL_PASSWORD="root"
export SURREAL_NAMESPACE="test"
export SURREAL_DATABASE="test"
```
### MCP Client Configuration
Add to your MCP client settings (e.g., Claude Desktop):
**Using uvx (recommended):**
```json
{
"mcpServers": {
"surrealdb": {
"command": "uvx",
"args": ["surreal-mcp"],
"env": {
"SURREAL_URL": "ws://localhost:8000/rpc",
"SURREAL_USER": "root",
"SURREAL_PASSWORD": "root",
"SURREAL_NAMESPACE": "test",
"SURREAL_DATABASE": "test"
}
}
}
}
```
**Using local installation:**
```json
{
"mcpServers": {
"surrealdb": {
"command": "uv",
"args": ["run", "surreal-mcp"],
"env": {
"SURREAL_URL": "ws://localhost:8000/rpc",
"SURREAL_USER": "root",
"SURREAL_PASSWORD": "root",
"SURREAL_NAMESPACE": "test",
"SURREAL_DATABASE": "test"
}
}
}
}
```
## =' Available Tools
All tools support optional `namespace` and `database` parameters to override the default values from environment variables.
### 1. query
Execute raw SurrealQL queries for complex operations.
```surrealql
-- Example: Complex query with graph traversal
SELECT *, ->purchased->product FROM user WHERE age > 25
```
```python
# Query with namespace/database override
query("SELECT * FROM user", namespace="production", database="main")
```
### 2. select
Retrieve all records from a table or a specific record by ID.
```python
# Get all users
select("user")
# Get specific user
select("user", "john")
# Select from a different database
select("user", namespace="other_ns", database="other_db")
```
### 3. create
Create a new record with auto-generated ID.
```python
create("user", {
"name": "Alice",
"email": "alice@example.com",
"age": 30
})
```
### 4. update
Replace entire record content (preserves ID and timestamps).
```python
update("user:john", {
"name": "John Smith",
"email": "john.smith@example.com",
"age": 31
})
```
### 5. delete
Permanently remove a record from the database.
```python
delete("user:john")
```
### 6. merge
Partially update specific fields without affecting others.
```python
merge("user:john", {
"email": "newemail@example.com",
"verified": True
})
```
### 7. patch
Apply JSON Patch operations (RFC 6902) to records.
```python
patch("user:john", [
{"op": "replace", "path": "/email", "value": "new@example.com"},
{"op": "add", "path": "/verified", "value": True}
])
```
### 8. upsert
Create or update a record with specific ID.
```python
upsert("settings:global", {
"theme": "dark",
"language": "en"
})
```
### 9. insert
Bulk insert multiple records efficiently.
```python
insert("product", [
{"name": "Laptop", "price": 999.99},
{"name": "Mouse", "price": 29.99},
{"name": "Keyboard", "price": 79.99}
])
```
### 10. relate
Create graph relationships between records.
```python
relate(
"user:john", # from
"purchased", # relation name
"product:laptop-123", # to
{"quantity": 1, "date": "2024-01-15"} # relation data
)
```
## =� Examples
### Basic CRUD Operations
```python
# Create a user
user = create("user", {"name": "Alice", "email": "alice@example.com"})
# Update specific fields
merge(user["id"], {"verified": True, "last_login": "2024-01-01"})
# Query with conditions
results = query("SELECT * FROM user WHERE verified = true ORDER BY created DESC")
# Delete when done
delete(user["id"])
```
### Working with Relationships
```python
# Create entities
user = create("user", {"name": "John"})
product = create("product", {"name": "Laptop", "price": 999})
# Create relationship
relate(user["id"], "purchased", product["id"], {
"quantity": 1,
"total": 999,
"date": "2024-01-15"
})
# Query relationships
purchases = query(f"SELECT * FROM {user['id']}->purchased->product")
```
### Bulk Operations
```python
# Insert multiple records
products = insert("product", [
{"name": "Laptop", "category": "Electronics", "price": 999},
{"name": "Mouse", "category": "Electronics", "price": 29},
{"name": "Desk", "category": "Furniture", "price": 299}
])
# Bulk update with query
query("UPDATE product SET on_sale = true WHERE category = 'Electronics'")
```
<<<<<<< HEAD
## <� Architecture
=======
### Multi-Database Operations
You can work with multiple databases in a single session by using the `namespace` and `database` parameters:
```python
# Create a record in the production database
create("user", {"name": "Alice"}, namespace="prod", database="main")
# Query from staging database
select("user", namespace="staging", database="main")
# Copy data between databases
users = select("user", namespace="staging", database="main")
for user in users["data"]:
create("user", user, namespace="prod", database="main")
```
**Behavior Summary:**
| Scenario | Result |
|----------|--------|
| Env vars set, no params | Uses pooled connection (best performance) |
| Env vars set, params provided | Uses override connection with specified namespace/database |
| No env vars, params provided | Uses override connection with specified namespace/database |
| No env vars, no params | Fails with clear error message |
## <� Architecture
>>>>>>> main
The server is built with:
- **FastMCP**: Simplified MCP server implementation
- **SurrealDB Python SDK**: Official database client
- **Connection Pooling**: Efficient connection management
- **Async/Await**: Non-blocking database operations
## >� Testing
The project includes a comprehensive test suite using pytest.
### Prerequisites
- SurrealDB instance running locally
- Test database access (uses temporary test databases)
### Running Tests
```bash
# Make sure SurrealDB is running
surreal start --user root --pass root
# Run all tests
uv run pytest
# Run with coverage
uv run pytest --cov=surreal_mcp
# Run specific test file
uv run pytest tests/test_tools.py
# Run specific test class or method
uv run pytest tests/test_tools.py::TestQueryTool
uv run pytest tests/test_tools.py::TestQueryTool::test_query_simple
# Run with verbose output
uv run pytest -v
# Run only tests matching a pattern
uv run pytest -k "test_create"
```
### Test Structure
```
tests/
├── __init__.py
├── conftest.py # Fixtures and test configuration
├── test_tools.py # Tests for all MCP tools
├── test_server.py # Tests for server configuration
└── test_namespace_override.py # Tests for namespace/database override
```
### Writing Tests
The test suite includes fixtures for common test data:
- `clean_db` - Ensures clean database state
- `sample_user_data` - Sample user data
- `created_user` - Pre-created user record
- `created_product` - Pre-created product record
Example test:
```python
@pytest.mark.asyncio
async def test_create_user(clean_db, sample_user_data):
result = await mcp._tools["create"].func(
table="user",
data=sample_user_data
)
assert result["success"] is True
assert result["data"]["email"] == sample_user_data["email"]
```
## > Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
1. Fork the repository
2. Create your feature branch (`git checkout -b feature/AmazingFeature`)
3. Commit your changes (`git commit -m 'Add some AmazingFeature'`)
4. Push to the branch (`git push origin feature/AmazingFeature`)
5. Open a Pull Request
## =� License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## =O Acknowledgments
- [SurrealDB](https://surrealdb.com/) for the amazing graph database
- [FastMCP](https://github.com/jlowin/fastmcp) for simplifying MCP server development
- [Model Context Protocol](https://modelcontextprotocol.io/) for the standardized AI-tool interface
## =� Support
- =� Email: your.email@example.com
- =� Discord: [Join our server](https://discord.gg/yourserver)
- = Issues: [GitHub Issues](https://github.com/yourusername/surreal-mcp/issues)
---
<div align="center">
Made with d for the SurrealDB and MCP communities
</div>TDQS
Scored across 10 tools
Most tools have distinct purposes, but there is some overlap between 'merge', 'patch', and 'update' that could cause confusion. 'merge' and 'patch' both handle partial updates with different syntaxes, and 'update' is for full replacements, which might be misselected by an agent. However, descriptions clarify these differences, and other tools like 'create', 'delete', and 'select' are clearly distinct.
All tool names follow a consistent verb-only pattern (e.g., create, delete, insert, merge, patch, query, relate, select, update, upsert). There are no deviations in style or convention, making the naming highly predictable and readable across the set.
With 10 tools, the server is well-scoped for a SurrealDB MCP server, covering essential CRUD operations, bulk inserts, queries, and graph relations. Each tool serves a clear purpose, and the count is neither too sparse nor overwhelming for database interaction tasks.
The tool set provides comprehensive coverage for SurrealDB operations, including create, read (select, query), update (update, merge, patch, upsert), delete, bulk operations (insert), and graph relations (relate). There are no obvious gaps; agents can perform full lifecycle management and complex queries without dead ends.