Skip to content
Draft
Show file tree
Hide file tree
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
13 changes: 13 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# TypeDB Connection Configuration
# Copy this file to .env and fill in your actual values

# TypeDB Server Configuration
TYPEDB_HOST=localhost
TYPEDB_PORT=1729

# Database Configuration
TYPEDB_DATABASE=your_database_name

# Authentication (optional, only if TypeDB server has authentication enabled)
TYPEDB_USERNAME=
TYPEDB_PASSWORD=
160 changes: 160 additions & 0 deletions PLAN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
# TypeDB MCP Server - Implementation Plan

## Overview

This document outlines the plan for building a Model Context Protocol (MCP) server for TypeDB, enabling AI assistants and other MCP clients to interact with TypeDB databases through a standardized interface.

## Architecture

### Dependencies
- **TypeDB Python Driver**: Official TypeDB Python SDK for database connectivity
- **MCP Python SDK**: The `mcp` Python package for MCP server implementation
- **Deployment**: Docker container (implementation details TBD - see Future Considerations)

## MCP Resources

Resources provide read-only access to schema information:

1. **get schema**
- Returns the complete database schema
- Format: TypeQL schema definition
- Supports multi-tenancy: database name can be passed as a query parameter in the URI
- URI format: `typedb://schema?database=<database_name>`
- If database parameter is omitted, uses default from configuration

## MCP Tools

### Core Tools

These tools provide direct query execution and transaction management:

1. **run_query**
- **Args**: `query` (string) - TypeQL query to execute
- **Returns**: Query response/result
- **Description**: Execute a TypeQL query in a read transaction

2. **analyze_query**
- **Args**: `query` (string) - TypeQL query to analyze
- **Returns**: Analysis response (query plan, optimization info, etc.)
- **Description**: Analyze a query without executing it

3. **open_transaction**
- **Args**: `type` (string) - Transaction type ("read" or "write")
- **Returns**: Transaction ID (string)
- **Description**: Open a new transaction and return its identifier

4. **commit_transaction**
- **Args**: `transaction_id` (string) - Transaction ID to commit
- **Returns**: Commit result (success/failure)
- **Description**: Commit a write transaction

5. **close_transaction**
- **Args**: `transaction_id` (string) - Transaction ID to close
- **Returns**: Success confirmation
- **Description**: Close a transaction (read or write)

6. **transaction_run_query**
- **Args**: `transaction_id` (string), `query` (string) - Transaction ID and TypeQL query
- **Returns**: Query response/result
- **Description**: Execute a query within a specific transaction context

7. **transaction_run_analyze**
- **Args**: `transaction_id` (string), `query` (string) - Transaction ID and TypeQL query
- **Returns**: Analysis response
- **Description**: Analyze a query within a specific transaction context

### Exploration Tools

These tools provide convenient ways to explore the graph structure:

1. **get_concept_with_attribute**
- **Args**:
- `attribute_type` (string) - Type of the attribute
- `attribute_value` (string) - Value of the attribute
- **Returns**: List of IIDs (Instance IDs) matching the criteria
- **Description**: Find concepts (entities/relations) that have a specific attribute value

2. **get_attributes_by_concept**
- **Args**: `iid` (string) - Instance ID of the concept
- **Returns**: JSON object with all attributes of the concept
- **Description**: Retrieve all attributes owned by a specific concept

3. **get_relations_of_concept**
- **Args**: `iid` (string) - Instance ID of the concept
- **Returns**: List of relation IIDs along with the role played by the concept
- **Description**: Find all relations where a concept participates and the role it plays

4. **get_players_of_relation**
- **Args**: `iid` (string) - Instance ID of the relation
- **Returns**: List of role+player pairs
- **Description**: Get all players (concepts) in a relation and their respective roles

## Implementation Phases

### Phase 1: Core Infrastructure
- [ ] Set up project structure
- [ ] Initialize MCP server with Python SDK
- [ ] Configure TypeDB connection
- [ ] Basic error handling and logging

### Phase 2: MCP Resources
- [ ] Implement `get_schema` resource
- [ ] Implement `get_schema_functions` resource
- [ ] Implement `get_schema_types` resource
- [ ] Test resource endpoints

### Phase 3: Core Tools
- [ ] Implement `run_query` tool
- [ ] Implement `analyze_query` tool
- [ ] Implement transaction management tools:
- [ ] `open_transaction`
- [ ] `commit_transaction`
- [ ] `close_transaction`
- [ ] Implement transaction-scoped query tools:
- [ ] `transaction_run_query`
- [ ] `transaction_run_analyze`
- [ ] Add transaction state management

### Phase 4: Exploration Tools
- [ ] Implement `get_concept_with_attribute`
- [ ] Implement `get_attributes_by_concept`
- [ ] Implement `get_relations_of_concept`
- [ ] Implement `get_players_of_relation`

### Phase 5: Testing & Documentation
- [ ] Unit tests for all tools and resources
- [ ] Integration tests with TypeDB
- [ ] API documentation
- [ ] Usage examples

### Phase 6: Docker Deployment
- [ ] Create Dockerfile
- [ ] Configure container orchestration (TBD - discuss with team)
- [ ] Environment variable configuration
- [ ] Health checks
- [ ] Documentation for deployment

## Future Considerations

### Docker Deployment
- **Status**: Pending discussion
- **Questions to resolve**:
- Container orchestration approach (Docker Compose, Kubernetes, etc.)
- Configuration management (environment variables, config files)
- Connection pooling and resource management
- Scaling strategy
- Health check endpoints

### Additional Features (Potential)
- Query result caching
- Batch query execution
- Schema validation tools
- Query optimization suggestions
- Performance monitoring/metrics

## Notes

- The exploration tools provide a GraphQL-like interface for traversing the TypeDB graph, which may be useful for AI assistants that need to explore the database structure.
- Transaction management allows for multi-step operations and write transactions.
- All tools should include proper error handling and validation of inputs.

14 changes: 9 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ This MCP server provides tools and resources for:
## Features

### MCP Resources
- **Schema Access**: Retrieve complete database schemas as TypeQL
- **Schema Access**: Retrieve complete database schemas as TypeQL (supports multi-tenancy via database parameter)

### MCP Tools
- **Query Execution**: Run and analyze TypeQL queries
Expand Down Expand Up @@ -54,7 +54,9 @@ Set the following environment variables. You can either:
Required variables:
- `TYPEDB_HOST`: TypeDB server host (default: `localhost`)
- `TYPEDB_PORT`: TypeDB server port (default: `1729`)
- `TYPEDB_DATABASE`: Database name to connect to

Optional variables:
- `TYPEDB_DATABASE`: Default database name (can also be specified per resource request)

Optional variables (only if TypeDB server has authentication enabled):
- `TYPEDB_USERNAME`: Username for authentication
Expand Down Expand Up @@ -139,9 +141,11 @@ pytest tests/

## MCP Resources Reference

- `schema`: Complete database schema
- `schema_functions`: All defined functions
- `schema_types`: All type definitions
- `schema`: Complete database schema in TypeQL format
- URI: `typedb://schema`
- Query parameter: `database` (optional) - database name to query
- Example: `typedb://schema?database=my_database`
- If database parameter is not provided, uses the default from `TYPEDB_DATABASE` environment variable

## Contributing

Expand Down
73 changes: 73 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
[project]
name = "typedb-mcp"
version = "0.1.0"
description = "Model Context Protocol server for TypeDB"
readme = "README.md"
requires-python = ">=3.9"
license = {text = "Apache-2.0"}
authors = [
{name = "Vaticle", email = "hello@vaticle.com"}
]
keywords = ["typedb", "mcp", "model-context-protocol", "database", "graph"]
classifiers = [
"Development Status :: 3 - Alpha",
"Intended Audience :: Developers",
"License :: OSI Approved :: Apache Software License",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
]

dependencies = [
"typedb-driver>=2.28.0",
"mcp>=0.1.0",
"python-dotenv>=1.0.0",
]

[project.optional-dependencies]
dev = [
"pytest>=7.0.0",
"pytest-asyncio>=0.21.0",
"pytest-cov>=4.0.0",
"black>=23.0.0",
"ruff>=0.1.0",
"mypy>=1.0.0",
]

[project.urls]
Homepage = "https://github.com/vaticle/typedb-mcp"
Documentation = "https://github.com/vaticle/typedb-mcp#readme"
Repository = "https://github.com/vaticle/typedb-mcp"
Issues = "https://github.com/vaticle/typedb-mcp/issues"

[build-system]
requires = ["setuptools>=61.0", "wheel"]
build-backend = "setuptools.build_meta"

[tool.black]
line-length = 100
target-version = ['py39', 'py310', 'py311', 'py312']

[tool.ruff]
line-length = 100
target-version = "py39"

[tool.ruff.lint]
select = ["E", "F", "I", "N", "W", "UP"]
ignore = ["E501"] # Line too long (handled by black)

[tool.pytest.ini_options]
testpaths = ["tests"]
python_files = ["test_*.py"]
python_classes = ["Test*"]
python_functions = ["test_*"]
asyncio_mode = "auto"

[tool.mypy]
python_version = "3.9"
warn_return_any = true
warn_unused_configs = true
disallow_untyped_defs = false

10 changes: 10 additions & 0 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Development dependencies
-r requirements.txt

pytest>=7.0.0
pytest-asyncio>=0.21.0
pytest-cov>=4.0.0
black>=23.0.0
ruff>=0.1.0
mypy>=1.0.0

8 changes: 8 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Core dependencies
typedb-driver>=2.28.0
mcp>=0.1.0
python-dotenv>=1.0.0

# Development dependencies (install with: pip install -r requirements.txt -r requirements-dev.txt)
# See pyproject.toml for dev dependencies

4 changes: 4 additions & 0 deletions typedb_mcp/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
"""TypeDB MCP Server - Model Context Protocol server for TypeDB."""

__version__ = "0.1.0"

2 changes: 2 additions & 0 deletions typedb_mcp/resources/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
"""MCP resources for TypeDB schema access."""

53 changes: 53 additions & 0 deletions typedb_mcp/resources/schema.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
"""Schema resources for MCP server."""

from typing import Optional

from typedb.common.exception import TypeDBDriverException

from typedb_mcp.utils.connection import TypeDBConnection


class SchemaResource:
"""MCP resource for accessing TypeDB schema information."""

def __init__(self, connection: TypeDBConnection):
"""Initialize schema resource.

Args:
connection: TypeDB connection manager
"""
self.connection = connection

def get_schema(self, database_name: Optional[str] = None) -> str:
"""Get the complete database schema as TypeQL.

Args:
database_name: Name of the database (if None, uses config default)

Returns:
Complete schema definition in TypeQL format

Raises:
ValueError: If database is not found or not specified
Exception: If schema retrieval fails
"""
# Use provided database name or fall back to config default
db_name = database_name or self.connection.config.database

if not db_name:
raise ValueError("Database name must be provided either as parameter or in config")

driver = self.connection.get_driver()
database = driver.databases.get(db_name)

if not database:
raise ValueError(f"Database '{db_name}' not found")

try:
# Get schema from database
schema = database.schema()
return schema
except TypeDBDriverException as e:
raise Exception(f"Failed to retrieve schema from database '{db_name}': {e}") from e


Loading