Skip to content

Deploy without OIDC Authentication

Quick setup guide for deploying Seed MCP Server without authentication for local development and testing.

Development Only

This configuration disables all authentication. Never use this in production or expose it to untrusted networks!

Use cases:

  • ✅ Local development and testing
  • ✅ Personal single-user environments
  • ✅ Learning and experimentation

NOT for:

  • ❌ Production deployments
  • ❌ Multi-user environments
  • ❌ Public or shared networks
  • ❌ Sensitive data or operations

Overview

This guide covers:

  1. Deploy Seed Server (No Auth)
  2. Configure Claude Code
  3. Configure Claude Desktop
  4. Verify Setup

Deploy Seed Server

Step 1: Create Configuration

Create a minimal .env file:

bash
# .env

# Server
PORT=3000

# Authentication - DISABLED
AUTH_REQUIRED=false

That's it! No OIDC provider, no Redis, no OAuth configuration needed.

TIP

When AUTH_REQUIRED=false, all OIDC and Redis configuration is optional and ignored.

Step 2: Start the Server

Choose your preferred deployment method:

The quickest way to get started with local development:

bash
# From project root
./scripts/seed --local

What this does:

  • Builds the Docker image with no cache (fresh build)
  • Deploys a local Docker stack named seed-local
  • Automatically configures services
  • Makes server available at http://localhost:3000

To stop:

bash
docker stack rm seed-local

TIP

The seed script uses docker-stack.local.yml which is pre-configured for local development without authentication.

Option B: Docker

bash
docker run -d \
  --name seed \
  -p 3000:3000 \
  -e AUTH_REQUIRED=false \
  seed-mcp-server:latest

Option C: Docker Compose

Create docker-compose.yml:

yaml
version: '3.8'

services:
  seed:
    image: seed-mcp-server:latest
    ports:
      - "3000:3000"
    environment:
      PORT: 3000
      AUTH_REQUIRED: "false"
    restart: unless-stopped

Start:

bash
docker-compose up -d

Option D: From Source

bash
# Install dependencies
npm install

# Create .env with AUTH_REQUIRED=false
echo "AUTH_REQUIRED=false" > .env

# Start development server
npm run dev

Step 3: Verify Server is Running

bash
# Health check
curl http://localhost:3000/health

# Expected:
# {"status":"ok","timestamp":"2025-12-09T..."}

# MCP endpoint (no auth required)
curl -X POST http://localhost:3000/mcp \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "initialize",
    "params": {
      "protocolVersion": "2024-11-05",
      "capabilities": {},
      "clientInfo": {"name": "test", "version": "1.0"}
    }
  }'

# Should work without Authorization header!

Claude Code Setup

Configure Claude Code to connect to your unauthenticated Seed MCP Server.

Step 1: Locate Configuration File

Claude Code configuration is at:

bash
~/.config/claude/config.json

Create if it doesn't exist:

bash
mkdir -p ~/.config/claude
touch ~/.config/claude/config.json

Step 2: Add MCP Server Configuration

You can configure the MCP server using either the CLI command or manual configuration.

Use the claude mcp add command to automatically configure the server:

bash
claude mcp add --scope user --transport http seed http://localhost:3000/mcp

This automatically adds the configuration to ~/.config/claude/config.json.

Option B: Manual Configuration

Alternatively, manually edit ~/.config/claude/config.json:

json
{
  "mcpServers": {
    "seed": {
      "url": "http://localhost:3000/mcp",
      "transport": "http"
    }
  }
}

Simple Configuration

Notice there's no authentication section - just the URL and transport type!

Configuration breakdown:

  • url: MCP endpoint - http://localhost:3000/mcp
  • transport: Always http for HTTP-based MCP servers
  • No authentication - The server doesn't require it

Step 3: Test Connection

Start Claude Code:

bash
claude

Expected output:

✓ Connected to seed MCP server
Available tools: seed_ping

That's it - no OAuth flow, no browser redirect, just instant connection!

Troubleshooting Claude Code

"Failed to connect to MCP server"

Check server is running:

bash
curl http://localhost:3000/health

Check configuration URL:

bash
# Test MCP endpoint
curl -X POST http://localhost:3000/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'

# Should work without auth

Check config file syntax:

bash
# Validate JSON
cat ~/.config/claude/config.json | jq .

# Should show valid JSON with no errors

"Connection works but no tools available"

This is normal if Seed has no tools registered. The base server includes seed_ping.

Verify tools endpoint:

bash
curl -X POST http://localhost:3000/mcp \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 2,
    "method": "tools/list",
    "params": {}
  }'

# Should return list of available tools

Claude Desktop Setup

Configure Claude Desktop to connect to your unauthenticated Seed MCP Server.

Step 1: Open Claude Desktop Settings

  1. Open Claude Desktop application
  2. Click Settings (gear icon)
  3. Navigate to MCP Servers or Developer section

Step 2: Add MCP Server Configuration

In Claude Desktop's MCP server configuration:

json
{
  "mcpServers": {
    "seed": {
      "url": "http://localhost:3000/mcp"
    }
  }
}

Minimal Configuration

Just the URL - no authentication, no OAuth, no client registration!

Step 3: Connect

After adding the configuration:

  1. Click "Connect" or restart Claude Desktop
  2. Connected! - Instant connection, no authentication flow

Visual confirmation:

  • ✅ Green dot next to "seed" MCP server
  • Status shows "Connected"
  • No user info (anonymous access)

Step 4: Verify Tools are Available

In Claude Desktop chat:

Can you ping the seed server?

Claude should respond using the seed_ping tool immediately.

Troubleshooting Claude Desktop

"Failed to connect"

Check server is accessible:

bash
# From your desktop machine
curl http://localhost:3000/health

If running Docker on a remote machine, replace localhost with the server's IP:

json
{
  "mcpServers": {
    "seed": {
      "url": "http://192.168.1.100:3000/mcp"
    }
  }
}

"Connection drops frequently"

Check server logs for errors:

bash
# Docker
docker logs seed

# Docker Compose
docker-compose logs seed

# Should show MCP requests and responses

Verify network stability:

bash
# Ping test
ping localhost

# Should have low latency and no packet loss

"Tools not working"

Test tool execution directly:

bash
curl -X POST http://localhost:3000/mcp \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 3,
    "method": "tools/call",
    "params": {
      "name": "seed_ping",
      "arguments": {}
    }
  }'

# Should return successful tool response

Verify Setup

1. Test MCP Connection

Without authentication:

bash
curl -X POST http://localhost:3000/mcp \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "initialize",
    "params": {
      "protocolVersion": "2024-11-05",
      "capabilities": {},
      "clientInfo": {"name": "test", "version": "1.0"}
    }
  }'

Expected response:

json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "protocolVersion": "2024-11-05",
    "serverInfo": {
      "name": "seed",
      "version": "0.1.3"
    },
    "capabilities": {
      "tools": {}
    }
  }
}

2. List Available Tools

bash
curl -X POST http://localhost:3000/mcp \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 2,
    "method": "tools/list",
    "params": {}
  }'

Expected:

json
{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "tools": [
      {
        "name": "seed_ping",
        "description": "Health check tool - returns server status",
        "inputSchema": {
          "type": "object",
          "properties": {},
          "additionalProperties": false
        }
      }
    ]
  }
}

3. Call a Tool

bash
curl -X POST http://localhost:3000/mcp \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 3,
    "method": "tools/call",
    "params": {
      "name": "seed_ping",
      "arguments": {}
    }
  }'

Expected:

json
{
  "jsonrpc": "2.0",
  "id": 3,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "{\"status\":\"ok\",\"version\":\"0.1.3\",\"timestamp\":\"2025-12-09T...\"}"
      }
    ]
  }
}

4. Test in Claude

Claude Code:

bash
claude

Then ask:

Can you ping the seed server and tell me the status?

Claude Desktop: Use the same prompt in chat.

Expected: Claude uses the seed_ping tool and reports server status.

Limitations Without Authentication

When running without authentication:

No User Context

Tools receive no user information. The user context will be empty or default:

typescript
// What tools receive
const userContext = {
  sub: "anonymous",  // No real user ID
  email: undefined,
  name: undefined,
  groups: undefined
}

Impact:

  • Can't personalize responses based on user
  • Can't implement user-based authorization
  • Can't audit actions by user
  • All requests are anonymous

No Access Control

Anyone who can reach the server can use it:

  • No user authentication
  • No permission checks
  • No rate limiting per user
  • No audit trail

Mitigation:

  • Only run on localhost or trusted networks
  • Use firewall rules to restrict access
  • Don't expose to public internet
  • Monitor server logs

No OAuth Features

OAuth-related endpoints are disabled:

  • /oauth/authorize - Not available
  • /oauth/token - Not available
  • /oauth/register - Not available
  • No dynamic client registration
  • No token management

Impact:

  • Can't test OAuth flow
  • Can't integrate with OAuth-based systems
  • Can't use refresh tokens

When to Move to OIDC Authentication

Consider adding OIDC authentication when:

  1. Multiple users - More than just yourself using the server
  2. Shared network - Server accessible by others
  3. Sensitive operations - Tools that access private data or perform privileged actions
  4. Production readiness - Moving beyond development
  5. Compliance requirements - Need user identification and audit trails
  6. Remote access - Accessing from outside your local machine

Migration path:

  1. Set up OIDC provider (Authentik, Okta, etc.)
  2. Set up Redis for session storage
  3. Update .env with OIDC configuration
  4. Set AUTH_REQUIRED=true
  5. Update Claude Code/Desktop configs with OAuth settings
  6. Test authentication flow

See Deploy with OIDC Authentication for detailed guide.

Security Best Practices

Even without authentication, follow these practices:

Network Security

Bind to localhost only:

bash
# .env
HOST=127.0.0.1  # Only accept local connections
PORT=3000

Firewall rules:

bash
# Block external access to port 3000
sudo ufw deny 3000/tcp
sudo ufw allow from 127.0.0.1 to any port 3000

Access Restrictions

Docker network isolation:

yaml
# docker-compose.yml
version: '3.8'
services:
  seed:
    image: seed-mcp-server:latest
    networks:
      - internal
    # Don't expose ports externally

networks:
  internal:
    driver: bridge
    internal: true

SSH tunnel for remote access:

bash
# Instead of exposing port, use SSH tunnel
ssh -L 3000:localhost:3000 user@remote-server

# Now access via http://localhost:3000 (tunneled)

Monitoring

Watch server logs:

bash
# Docker
docker logs -f seed

# Docker Compose
docker-compose logs -f seed

# From source
# Logs appear in console

Log MCP requests: The server logs all MCP requests. Review regularly to detect:

  • Unexpected tool calls
  • Unusual patterns
  • Error spikes

Development Workflow

Quick Iteration

Without auth, you can rapidly test changes:

bash
# 1. Make code changes
vim src/mcp/tools/my-tool.ts

# 2. Restart server
npm run dev

# 3. Test immediately (no re-auth needed)
claude
# > Ask Claude to use your tool

Testing Tools

Create test scripts without OAuth complexity:

bash
#!/bin/bash
# test-tool.sh

curl -X POST http://localhost:3000/mcp \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "my_tool",
      "arguments": {"param": "value"}
    }
  }' | jq .

Debugging

Enable verbose logging:

bash
# .env
AUTH_REQUIRED=false
LOG_LEVEL=debug  # or trace for very verbose

Check logs for detailed request/response info.

Next Steps

Once you're ready to add authentication:

  1. Deploy with OIDC - Add authentication
  2. Create Custom Tools - Extend functionality
  3. Configuration Guide - All environment variables
  4. Architecture Overview - Understand the system

Released under the MIT License.