Metadata-Version: 2.4
Name: ags-mcp-server
Version: 1.2.0
Summary: Model Context Protocol (MCP) server for Anzo Graph Database with dual API support (5.4 + 6.0+), 50+ tools, discovery capabilities, and comprehensive skill-based workflows
Author-email: Paresh Khandelwal <khandelwal.paresh@siemens.com>
Maintainer-email: Paresh Khandelwal <khandelwal.paresh@siemens.com>
License: Apache-2.0
Project-URL: Homepage, https://pypi.org/project/ags-mcp-server/
Project-URL: Documentation, https://docs.cambridgesemantics.com/anzo/
Keywords: anzo,mcp,model-context-protocol,graph-database,sparql,rdf,knowledge-graph
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Database :: Front-Ends
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Operating System :: OS Independent
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: fastmcp>=1.2.0
Requires-Dist: python-dotenv>=1.0.0
Requires-Dist: requests>=2.31.0
Requires-Dist: pyanzo>=2.0.0
Requires-Dist: structlog>=24.1.0
Requires-Dist: uvicorn>=0.27.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
Requires-Dist: black>=23.0; extra == "dev"
Requires-Dist: flake8>=6.0; extra == "dev"
Requires-Dist: mypy>=1.0; extra == "dev"
Dynamic: license-file

# Anzo MCP Server

[![PyPI version](https://badge.fury.io/py/ags-mcp-server.svg)](https://badge.fury.io/py/ags-mcp-server)
[![Python Version](https://img.shields.io/pypi/pyversions/ags-mcp-server.svg)](https://pypi.org/project/ags-mcp-server/)
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
[![Downloads](https://pepy.tech/badge/ags-mcp-server)](https://pepy.tech/project/ags-mcp-server)

Enterprise-grade Model Context Protocol server for Anzo Graph Database. Connect AI assistants to your knowledge graphs with 51+ tools, comprehensive skill-based workflows, and dual API version support (5.4 + 6.0+).

## Why Anzo MCP Server?

Transform AI assistants into powerful knowledge graph operators with:

- **Plug-and-play Integration**: Works with Claude Desktop, Cursor IDE, and any MCP-compatible client
- **51+ Production-Ready Tools**: Complete graphmart lifecycle + discovery & optimization
- **15 Expert Prompts**: Pre-built workflows including step-by-step linking guides
- **Dual API Support**: Anzo 5.4 and 6.0+ from same installation
- **Enterprise Security**: Environment-based credential management
- **Dual Transport**: stdio for desktop apps, HTTP/SSE for web applications
- **SPARQL-First**: Native query execution with validation and optimization
- **Discovery Tools**: Relationship elicitation, coverage analysis, query optimization

---

## What's New in v1.2.0

### Dual API Version Support
- **Anzo 5.4**: Use `ags-mcp-http-54` or `ags-mcp-stdio-54`
- **Anzo 6.0+**: Use `ags-mcp-http` or `ags-mcp-stdio` (default)

### Enhanced Skill-Based Workflows
- **Internal Linking Guide**: 8-step workflow for single-domain entity connections
- **Cross-Domain Linking**: Minimum spanning tree methodology for multi-domain graphs
- **Ontology Design**: Best practices for robust ontology creation
- **Query Lens Visualization**: Interactive data exploration patterns

### Discovery & Optimization Tools
- `discover_potential_relationships` - Find foreign key patterns automatically
- `detect_cartesian_product_risk` - Prevent query explosions
- `calculate_link_coverage_metrics` - Analyze linking feasibility
- `suggest_minimum_spanning_tree` - Optimize cross-domain architecture
- `analyze_query_performance` - SPARQL optimization recommendations

---

## Installation

### From PyPI (Recommended)

```bash
pip install ags-mcp-server
```

### From Source

```bash
cd anzo-mcp-server
pip install -e .
```

---

## Quick Start

### 1. Set Up Credentials

Create a `.env` file in your project directory:

```bash
# Option 1: Copy the example template
curl -O https://raw.githubusercontent.com/cambridgesemantics/anzo-mcp-server/main/.env.example
mv .env.example .env

# Option 2: Create manually
cat > .env << 'EOF'
# Anzo Server Configuration
ANZO_HTTP_BASE=https://your-anzo-server.com
ANZO_PORT=443
ANZO_USERNAME=your-username
ANZO_PASSWORD=your-password

# GraphMart Configuration (optional)
ANZO_GRAPHMART_IRI=http://cambridgesemantics.com/Graphmart/YOUR-GRAPHMART-ID

# API Version Routing (optional)
# auto | 5.4 | 6.0
ANZO_API_VERSION=auto

# Client Configuration (optional)
REQUEST_TIMEOUT=30.0
MAX_RETRIES=3
LOG_LEVEL=INFO

# MCP HTTP/SSE bind settings (optional)
# Local default: MCP_HOST=127.0.0.1
# External access (EC2/container): MCP_HOST=0.0.0.0
MCP_HOST=127.0.0.1
MCP_PORT=8000

# Runtime State & Deterministic Discovery (optional, zero-config defaults)
RUNTIME_STATE_ENABLED=true
# RUNTIME_STATE_DB_PATH=.ags_mcp/runtime_state.db
RUNTIME_STATE_TTL_SECONDS=3600
DISCOVERY_MAX_QUERIES_PER_TASK=8
DISCOVERY_MAX_CLASSES=50
DISCOVERY_MAX_PROPERTIES=200
DISCOVERY_SAMPLE_LIMIT=10
EOF
```

**Security Note:** Never commit `.env` files to version control. The file is automatically excluded via `.gitignore`.

### 2. Start the Server

#### For Anzo 6.0+ (Default)

**Claude Desktop** (stdio transport):
```bash
ags-mcp-stdio
```

**Cursor IDE / Web Apps** (HTTP/SSE transport):
```bash
ags-mcp-http
```

#### For Anzo 5.4

**Claude Desktop** (stdio transport):
```bash
ags-mcp-stdio-54
```

**Cursor IDE / Web Apps** (HTTP/SSE transport):
```bash
ags-mcp-http-54
```

The HTTP server starts on `http://127.0.0.1:8000` by default.

### Remote Deployment Note

To accept external connections (EC2/container), bind HTTP to all interfaces:

```env
MCP_HOST=0.0.0.0
MCP_PORT=8000
```

Also allow inbound TCP on `MCP_PORT` in your cloud security group/firewall.

### 3. Verify Connection

The server logs will confirm successful startup:
```
[info] anzo_client_initialized base_url=https://your-anzo-server.com api_version=6.0
[info] mcp_tools_registered tools_count=51
[info] starting_mcp_server
```

---

## Client Configuration

### Claude Desktop

#### For Anzo 6.0+
Add to `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows):

```json
{
  "mcpServers": {
    "anzo-graphmart": {
      "command": "ags-mcp-stdio",
      "env": {
        "ANZO_HTTP_BASE": "https://your-anzo-server.com",
        "ANZO_USERNAME": "your-username",
        "ANZO_PASSWORD": "your-password"
      }
    }
  }
}
```

#### For Anzo 5.4
```json
{
  "mcpServers": {
    "anzo-graphmart-54": {
      "command": "ags-mcp-stdio-54",
      "env": {
        "ANZO_HTTP_BASE": "https://your-anzo-54-server.com",
        "ANZO_USERNAME": "your-username",
        "ANZO_PASSWORD": "your-password"
      }
    }
  }
}
```

### Cursor IDE

#### For Anzo 6.0+
Create `.cursor/mcp.json` in your workspace:

```json
{
  "mcpServers": {
    "anzo-graphmart": {
      "url": "http://localhost:8000/sse"
    }
  }
}
```

Then start: `ags-mcp-http`

#### For Anzo 5.4
```json
{
  "mcpServers": {
    "anzo-graphmart-54": {
      "url": "http://localhost:8001/sse"
    }
  }
}
```

Then start (Linux/macOS): `MCP_PORT=8001 ags-mcp-http-54`
Then start (PowerShell): `$env:MCP_PORT='8001'; ags-mcp-http-54`

### Custom MCP Client

#### stdio Transport
```python
import subprocess
import json

process = subprocess.Popen(
    ["ags-mcp-stdio"],  # or "ags-mcp-stdio-54" for Anzo 5.4
    stdin=subprocess.PIPE,
    stdout=subprocess.PIPE,
    env={"MCP_TRANSPORT": "stdio"}
)

# Send MCP requests via stdin, receive responses via stdout
```

#### HTTP/SSE Transport
```python
import requests

# Connect to SSE endpoint
response = requests.get("http://localhost:8000/sse", stream=True)

# Send tool requests
requests.post("http://localhost:8000/messages/", json={
    "method": "tools/call",
    "params": {
        "name": "list_graphmarts",
        "arguments": {}
    }
})
```

---

## Available Tools

### Graphmart Management (11 tools)
| Tool | Description |
|------|-------------|
| `list_graphmarts` | List all accessible graphmarts |
| `get_graphmart_info` | Get detailed graphmart metadata |
| `create_graphmart` | Create new graphmart with configuration |
| `modify_graphmart` | Update graphmart properties |
| `delete_graphmart` | Remove graphmart and all data |
| `activate_graphmart` | Start graphmart for queries |
| `deactivate_graphmart` | Stop graphmart |
| `refresh_graphmart` | Reload changed layers |
| `reload_graphmart` | Full reload of all layers |
| `retrieve_graphmart_status` | Check activation state |
| `retrieve_graphmart_layers` | List graphmart layers |

### Layer Operations (10 tools)
| Tool | Description |
|------|-------------|
| `list_layers` | List all layers |
| `get_layer_info` | Get layer details |
| `create_layer` | Create transformation layer |
| `modify_layer` | Update layer configuration |
| `delete_layer` | Remove layer |
| `get_layer_contents` | Retrieve layer RDF data |
| `list_layer_steps` | List transformation steps |
| `create_layer_step` | Add transformation step |
| `modify_layer_step` | Update step configuration |
| `delete_layer_step` | Remove step |

### Ontology Tools (8 tools)
| Tool | Description |
|------|-------------|
| `list_ontologies` | List all ontologies |
| `get_ontology_info` | Get ontology details |
| `create_ontology` | Create new ontology |
| `create_ontology_class` | Add class to ontology |
| `create_ontology_property` | Add property to ontology |
| `add_ontology_import` | Import external ontology |
| `validate_ontology` | Check ontology consistency |
| `delete_ontology` | Remove ontology |

### Dataset Operations (6 tools)
| Tool | Description |
|------|-------------|
| `list_datasets` | List all datasets |
| `get_dataset_info` | Get dataset metadata |
| `upload_dataset` | Upload RDF data |
| `modify_dataset` | Update dataset properties |
| `delete_dataset` | Remove dataset |
| `get_dataset_contents` | Retrieve dataset data |

### Pipeline Management (5 tools)
| Tool | Description |
|------|-------------|
| `list_pipelines` | List all pipelines |
| `create_pipeline` | Create data pipeline |
| `execute_pipeline` | Run pipeline |
| `get_pipeline_status` | Check execution status |
| `delete_pipeline` | Remove pipeline |

### Query Execution (5 tools)
| Tool | Description |
|------|-------------|
| `execute_sparql_query` | Run SPARQL query |
| `validate_sparql_query` | Check query syntax |
| `explain_query_plan` | Get query execution plan |
| `query_with_inference` | Execute with reasoning |
| `federated_query` | Query across graphmarts |

### Runtime Management (1 tool)
| Tool | Description |
|------|-------------|
| `get_server_capabilities` | Return effective API compatibility, deterministic discovery workflow, and runtime limits |

---

## 📚 Available Prompts

### 1. Knowledge Graph Linking Overview
Complete methodology index and conceptual guide for knowledge graph linking.

**Usage:**
```
Ask Claude: "Show me the knowledge graph linking overview"
```

### 2. Ontology & Data Layer Best Practices  
Step-by-step guide for building ontologies from data layers.

**Usage:**
```
Ask Claude: "How do I create an ontology from my data layer?"
```

### 3. SPARQL Query Guide
Comprehensive SPARQL syntax reference with optimization techniques.

**Usage:**
```
Ask Claude: "Help me write a SPARQL query to find..."
```

### 4. Graphmart Workflow
Complete workflow for creating and managing graphmarts.

**Usage:**
```
Ask Claude: "Walk me through creating a new graphmart"
```

### 5. Layer Management
Best practices for layer operations and ordering.

**Usage:**
```
Ask Claude: "How do I organize my transformation layers?"
```

### 6. Dataset Operations
Data upload and management workflows.

**Usage:**
```
Ask Claude: "How do I upload CSV data to my graphmart?"
```

### 7. AGS Query Lens Guide
Interactive graph visualization and exploration.

**Usage:**
```
Ask Claude: "Show me how to visualize my knowledge graph"
```

### 8. Cross-Domain Linking
Connecting entities across multiple knowledge domains.

**Usage:**
```
Ask Claude: "How do I link customer data with product catalogs?"
```

### 9. Internal Linking Guide
Fixing "islands" within a single domain.

**Usage:**
```
Ask Claude: "How do I connect isolated entities in my dataset?"
```

### 10. Troubleshooting Guide
Common issues and solutions.

**Usage:**
```
Ask Claude: "My graphmart won't activate, what's wrong?"
```

---

## 💡 Usage Examples

### Example 1: List All Graphmarts

**Natural language request:**
```
"List all available graphmarts"
```

**AI Assistant uses:**
```json
{
  "tool": "list_graphmarts",
  "arguments": {
    "expand": "*"
  }
}
```

**Response:**
```json
[
  {
    "uri": "http://cambridgesemantics.com/Graphmart/abc123",
    "name": "Customer Knowledge Graph",
    "status": "ONLINE",
    "layers": 5,
    "created": "2024-01-15T10:30:00Z"
  }
]
```

### Example 2: Execute SPARQL Query

**Natural language request:**
```
"Find all customers in New York"
```

**AI Assistant generates and executes:**
```sparql
PREFIX schema: <http://schema.org/>

SELECT ?customer ?name
WHERE {
  ?customer a schema:Customer ;
           schema:name ?name ;
           schema:address ?address .
  ?address schema:addressRegion "NY" .
}
LIMIT 100
```

**Tool call:**
```json
{
  "tool": "execute_sparql_query",
  "arguments": {
    "query": "PREFIX schema: <http://schema.org/> ...",
    "graphmart_uri": "http://cambridgesemantics.com/Graphmart/abc123"
  }
}
```

### Example 3: Create Ontology Class

**Natural language request:**
```
"Create a Product class in the ontology"
```

**AI Assistant uses:**
```json
{
  "tool": "create_ontology_class",
  "arguments": {
    "ontology_uri": "http://example.com/ontology/retail",
    "class_name": "Product",
    "label": "Product",
    "description": "A product offered for sale"
  }
}
```

---

## Architecture

```
┌─────────────────┐         ┌──────────────────┐
│   AI Assistant  │◄───────►│  Anzo MCP Server │
│  (Claude/Copilot│  MCP    │  (stdio/HTTP)    │
└─────────────────┘         └──────────────────┘
                                     │
                                     │ REST API
                                     │ pyanzo
                                     ▼
                            ┌──────────────────┐
                            │  Anzo GraphDB    │
                            │  Knowledge Graph │
                            └──────────────────┘
```

### Components

- **MCP Server**: Exposes tools and prompts via MCP protocol
- **Anzo Client**: REST API wrapper for graph operations
- **pyanzo**: Native SPARQL query execution
- **Transport Layer**: stdio for desktop, HTTP/SSE for web

---

## Security Best Practices

### Credential Management

**DO:**
- Store credentials in `.env` files (automatically excluded from git)
- Use environment variables in production
- Rotate passwords regularly
- Use service accounts with minimal permissions

**DON'T:**
- Hardcode credentials in code
- Commit `.env` files to git
- Share credentials in chat logs
- Use admin accounts for MCP access

### Production Deployment

**Docker:**
```dockerfile
FROM python:3.11-slim

WORKDIR /app
RUN pip install ags-mcp-server

# Use secrets management
ENV ANZO_HTTP_BASE=${ANZO_HTTP_BASE}
ENV ANZO_USERNAME=${ANZO_USERNAME}  
ENV ANZO_PASSWORD=${ANZO_PASSWORD}

CMD ["ags-mcp-http"]
```

**Kubernetes:**
```yaml
apiVersion: v1
kind: Secret
metadata:
  name: anzo-credentials
type: Opaque
stringData:
  ANZO_USERNAME: your-username
  ANZO_PASSWORD: your-password
---
apiVersion: apps/v1
kind: Deployment
spec:
  template:
    spec:
      containers:
      - name: anzo-mcp
        image: ags-mcp-server:latest
        envFrom:
        - secretRef:
            name: anzo-credentials
```

---

## Troubleshooting

### Server Won't Start

**Issue:** `ANZO_USERNAME environment variable must be set`

**Solution:**
```bash
# Verify .env file exists
ls -la .env

# Check contents
cat .env

# Ensure server reads .env
cd /path/to/project
ags-mcp-http
```

### Connection Timeout

**Issue:** `Max retries exceeded with url: /api/graphmarts`

**Solutions:**
1. Verify Anzo server is reachable:
   ```bash
   curl -u username:password https://your-anzo-server.com/api/graphmarts
   ```
2. Check firewall/VPN settings
3. Increase timeout in `.env`:
   ```env
   REQUEST_TIMEOUT=60.0
   MAX_RETRIES=5
   ```

### Claude Desktop Not Finding Tools

**Issue:** Tools don't appear in Claude Desktop

**Solutions:**
1. Restart Claude Desktop completely
2. Check config file location:
   - macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
   - Windows: `%APPDATA%\Claude\claude_desktop_config.json`
3. Verify JSON syntax:
   ```bash
   python -m json.tool < claude_desktop_config.json
   ```

### SPARQL Query Fails

**Issue:** `SPARQL query failed: ParseException`

**Solutions:**
1. Validate query syntax:
   ```
   Ask Claude: "Validate this SPARQL query: [your query]"
   ```
2. Check prefix declarations
3. Verify graphmart is activated:
   ```json
   {"tool": "retrieve_graphmart_status", "arguments": {"graphmart_uri": "..."}}
   ```

---

## Documentation

- **Anzo Documentation**: https://docs.cambridgesemantics.com/anzo/
- **PyPI Package**: https://pypi.org/project/ags-mcp-server/

---

## Contributing

We welcome contributions! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.

### Development Setup

```bash
# Clone repository
git clone https://github.com/cambridgesemantics/anzo-mcp-server.git
cd anzo-mcp-server

# Create virtual environment
python -m venv .venv
source .venv/bin/activate  # On Windows: .venv\Scripts\activate

# Install in development mode
pip install -e ".[dev]"

# Run tests
pytest

# Run security check
python check_credentials.py

# Format code
black ags_mcp/

# Type checking
mypy ags_mcp/
```

---

## 📄 License

This project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details.

---

## 🙏 Acknowledgments

- **Anzo Graph Database** by Cambridge Semantics
- **Model Context Protocol** by Anthropic
- **FastMCP** framework
- **pyanzo** SPARQL client

---

## Support

- **Email**: khandelwal.paresh@siemens.com

---

## Roadmap

### Completed in v1.2.0
- [x] Dual API support (Anzo 5.4 and 6.0+)
- [x] Skill-based prompt system with markdown workflows
- [x] Discovery and optimization tools
- [x] Enhanced error handling and logging

### Planned Features
- [ ] Observability with Prometheus and OpenTelemetry
- [ ] Response caching layer with Redis
- [ ] Advanced SPARQL optimization hints
- [ ] Bulk data upload operations
- [ ] Real-time change notifications via WebSocket
- [ ] Multi-tenant isolation patterns
- [ ] Docker Compose quickstart
- [ ] Helm chart for Kubernetes deployment

---

**Made by Paresh Khandelwal**
