Server Registration
# Server Identity Registration
This guide covers setting up a verifiable identity for your MCP server.
## Why Server Identity?
MCP servers expose powerful tools—file systems, databases, APIs. But how do clients know they're connecting to the **real** server and not an imposter?
Server identity registration solves this by:
- **Generating a keypair** for cryptographic signing
- **Creating a DID** (Decentralized Identifier) for the server
- **Registering with the CapiscIO Registry** for discoverability
## Quick Start
```python
from capiscio_mcp import setup_server_identity
# One-step setup: generate keys + register with registry
result = await setup_server_identity(
server_id="550e8400-e29b-41d4-a716-446655440000", # From dashboard
api_key="sk_live_...", # Registry API key
output_dir="./keys",
)
print(f"Server DID: {result['did']}")
# did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK
```
## Prerequisites
1. **Create your MCP server in the CapiscIO Dashboard**
- Go to [dashboard.capisc.io](https://dashboard.capisc.io)
- Navigate to Servers → Create Server
- Copy the server UUID
2. **Get an API key**
- In the dashboard, go to Settings → API Keys
- Create a key with `servers:write` permission
3. **capiscio-core must be running**
- Either embedded (auto-downloaded) or external
## Step-by-Step Registration
### Step 1: Generate Keypair
Generate an Ed25519 keypair for your server:
```python
from capiscio_mcp import generate_server_keypair
keys = await generate_server_keypair(output_dir="./keys")
print(f"DID: {keys['did_key']}")
print(f"Private key: {keys['private_key_path']}")
```
Returns:
| Key | Description |
|-----|-------------|
| `key_id` | Unique key identifier |
| `did_key` | The derived `did:key:z6Mk...` URI |
| `public_key_pem` | PEM-encoded public key |
| `private_key_pem` | PEM-encoded private key |
| `private_key_path` | Path to saved key file (if `output_dir` provided) |
### Step 2: Register with Registry
Register the DID with the CapiscIO registry:
```python
from capiscio_mcp import register_server_identity
await register_server_identity(
server_id="550e8400-e29b-41d4-a716-446655440000",
api_key="sk_live_...",
did=keys["did_key"],
public_key=keys["public_key_pem"],
)
```
### Combined: setup_server_identity
For convenience, use the combined function:
```python
from capiscio_mcp import setup_server_identity
result = await setup_server_identity(
server_id="550e8400-e29b-41d4-a716-446655440000",
api_key="sk_live_...",
output_dir="./keys",
)
# Returns everything you need
print(f"DID: {result['did']}")
print(f"Private key: {result['private_key_path']}")
```
## Synchronous API
All functions have sync wrappers:
```python
from capiscio_mcp import (
generate_server_keypair_sync,
register_server_identity_sync,
setup_server_identity_sync,
)
# Sync version
result = setup_server_identity_sync(
server_id="550e8400-e29b-41d4-a716-446655440000",
api_key="sk_live_...",
output_dir="./keys",
)
```
## Using the Identity
After registration, use the DID and private key for server identity disclosure:
### With CapiscioMCPServer
```python
from capiscio_mcp.integrations.mcp import CapiscioMCPServer
server = CapiscioMCPServer(
name="filesystem",
did=result["did"],
private_key_path=result["private_key_path"],
)
@server.tool(min_trust_level=2)
async def read_file(path: str) -> str:
"""Server identity is automatically disclosed."""
with open(path) as f:
return f.read()
```
### Manual Disclosure
Add identity headers to responses:
```python
from fastapi import FastAPI, Response
app = FastAPI()
@app.middleware("http")
async def add_server_identity(request, call_next):
response = await call_next(request)
response.headers["Capiscio-Server-DID"] = SERVER_DID
response.headers["Capiscio-Server-Badge"] = SERVER_BADGE
return response
```
## Error Handling
```python
from capiscio_mcp import (
setup_server_identity,
RegistrationError,
KeyGenerationError,
)
from capiscio_mcp.errors import CoreConnectionError
try:
result = await setup_server_identity(
server_id="550e8400-e29b-41d4-a716-446655440000",
api_key="sk_live_...",
)
except CoreConnectionError as e:
print("Could not connect to capiscio-core")
print("Ensure it's running: capiscio mcp serve")
except KeyGenerationError as e:
print(f"Key generation failed: {e}")
except RegistrationError as e:
print(f"Registration failed: {e}")
if e.status_code == 401:
print("Invalid API key")
elif e.status_code == 404:
print("Server not found - create it in the dashboard first")
```
## Environment Variables
| Variable | Description |
|----------|-------------|
| `CAPISCIO_CORE_ADDR` | External core address (default: embedded) |
| `CAPISCIO_SERVER_DID` | Pre-configured server DID |
| `CAPISCIO_SERVER_PRIVATE_KEY` | Path to private key PEM |
## Security Best Practices
1. **Never commit private keys**
```gitignore
# .gitignore
*.pem
keys/
capiscio_keys/
```
2. **Use restrictive permissions**
```bash
chmod 600 ./keys/*.pem
```
3. **Rotate keys periodically**
- Generate new keypair
- Update registry with new DID
- Keep old key for transition period
4. **Store API keys securely**
```bash
# Use environment variables
export CAPISCIO_REGISTRY_API_KEY="sk_live_..."
```
## Next Steps
- [Protect MCP Tools](server-side.md) - Add trust-level requirements
- [Client-Side Verification](client-side.md) - Verify servers before connecting
- [Evidence Logging](evidence.md) - Audit trail for all tool calls