# Task ID: 3

**Title:** Implement mcpd Core Server Framework

**Status:** pending

**Dependencies:** 1, 2

**Priority:** high

**Description:** Build the mcpd daemon server with Express/Fastify, including middleware for authentication, logging, and error handling. Design for horizontal scalability.

**Details:**

Create mcpd server in `src/mcpd/src/`:

```typescript
// server.ts
import Fastify from 'fastify';
import { PrismaClient } from '@prisma/client';

const app = Fastify({ logger: true });
const prisma = new PrismaClient();

// Middleware
app.register(require('@fastify/cors'));
app.register(require('@fastify/helmet'));
app.register(require('@fastify/rate-limit'), { max: 100, timeWindow: '1 minute' });

// Health check for load balancers
app.get('/health', async () => ({ status: 'ok', timestamp: new Date().toISOString() }));

// Auth middleware
app.addHook('preHandler', async (request, reply) => {
  if (request.url === '/health') return;
  const token = request.headers.authorization?.replace('Bearer ', '');
  if (!token) return reply.status(401).send({ error: 'Unauthorized' });
  // Validate token against session table
});

// Audit logging middleware
app.addHook('onResponse', async (request, reply) => {
  await prisma.auditLog.create({
    data: {
      action: request.method,
      resource: request.url,
      details: { statusCode: reply.statusCode },
      userId: request.user?.id
    }
  });
});
```

Design principles:
- Stateless: All state in PostgreSQL, no in-memory session storage
- Scalable: Can run multiple instances behind load balancer
- Configurable via environment variables
- Graceful shutdown handling

**Test Strategy:**

Unit test middleware functions. Integration test health endpoint. Load test with multiple concurrent requests. Verify statelessness by running two instances and alternating requests.

## Subtasks

### 3.1. Set up mcpd package structure with clean architecture layers and TDD infrastructure

**Status:** pending  
**Dependencies:** None  

Create the src/mcpd directory structure following clean architecture principles with separate layers for routes, controllers, services, and repositories, along with Vitest test configuration.

**Details:**

Create src/mcpd/src/ directory structure with the following layers:

- routes/ - HTTP route definitions (thin layer, delegates to controllers)
- controllers/ - Request/response handling, input validation
- services/ - Business logic, orchestrates repositories
- repositories/ - Data access layer, Prisma abstraction
- middleware/ - Auth, logging, error handling, rate limiting
- config/ - Environment configuration with Zod validation
- types/ - TypeScript interfaces for dependency injection
- utils/ - Utility functions (graceful shutdown, health checks)

Create src/mcpd/tests/ with matching structure:
- unit/ (routes, controllers, services, repositories, middleware)
- integration/ (API endpoint tests)
- fixtures/ (mock data, Prisma mock setup)

Set up vitest.config.ts extending root config with mcpd-specific settings. Create test-utils.ts with Prisma mock factory and Fastify test helpers. Install dependencies: fastify, @fastify/cors, @fastify/helmet, @fastify/rate-limit, zod, pino. DevDependencies: vitest, @vitest/coverage-v8, supertest.

### 3.2. Implement Fastify server core with health endpoint and database connectivity verification

**Status:** pending  
**Dependencies:** 3.1  

Create the core Fastify server with health check endpoint that verifies PostgreSQL database connectivity, environment configuration validation, and server lifecycle management.

**Details:**

Create src/mcpd/src/server.ts with Fastify instance factory function createServer(config: ServerConfig) for testability via dependency injection. Implement:

- config/env.ts: Zod schema for environment variables (DATABASE_URL, PORT, NODE_ENV, LOG_LEVEL)
- config/index.ts: loadConfig() function that validates env with Zod
- utils/health.ts: checkDatabaseConnectivity(prisma) function
- routes/health.ts: GET /health endpoint returning { status: 'ok' | 'degraded', timestamp: ISO8601, db: 'connected' | 'disconnected' }

Server requirements:
- Fastify with pino logger enabled (configurable log level)
- Health endpoint bypasses auth middleware
- Health endpoint checks actual DB connectivity via prisma.$queryRaw
- Server does NOT start if DATABASE_URL is missing (fail fast)
- Export createServer() and startServer() separately for testing

Write TDD tests FIRST in tests/unit/routes/health.test.ts and tests/unit/config/env.test.ts before implementing.

### 3.3. Implement authentication middleware with JWT validation and session management

**Status:** pending  
**Dependencies:** 3.2  

Create authentication preHandler hook that validates Bearer tokens against the Session table in PostgreSQL, with proper error responses and request decoration for downstream handlers.

**Details:**

Create src/mcpd/src/middleware/auth.ts with:

- authMiddleware(prisma: PrismaClient) factory function (dependency injection)
- Fastify preHandler hook implementation
- Extract Bearer token from Authorization header
- Validate token exists and format is correct
- Query Session table: find by token, check expiresAt > now()
- Query User by session.userId for request decoration
- Decorate request with user: { id, email, name } via fastify.decorateRequest
- Return 401 Unauthorized with { error: 'Unauthorized', code: 'TOKEN_REQUIRED' } for missing token
- Return 401 with { error: 'Unauthorized', code: 'TOKEN_EXPIRED' } for expired session
- Return 401 with { error: 'Unauthorized', code: 'TOKEN_INVALID' } for invalid token

Create types/fastify.d.ts with FastifyRequest augmentation for user property.

Write unit tests in tests/unit/middleware/auth.test.ts with mocked Prisma client before implementation.

### 3.4. Implement security middleware stack with CORS, Helmet, rate limiting, and input sanitization

**Status:** pending  
**Dependencies:** 3.2  

Configure and register security middleware including CORS policy, Helmet security headers, rate limiting, and create input sanitization utilities to prevent injection attacks.

**Details:**

Create src/mcpd/src/middleware/security.ts with:

- registerSecurityPlugins(app: FastifyInstance, config: SecurityConfig) function
- CORS configuration: configurable origins (default: same-origin for production, * for development), credentials support, allowed methods/headers
- Helmet configuration: contentSecurityPolicy, hsts (enabled in production), noSniff, frameguard
- Rate limiting: 100 requests per minute default, configurable via env, different limits for auth endpoints (stricter)

Create src/mcpd/src/utils/sanitize.ts:
- sanitizeInput(input: unknown): sanitized value
- stripHtmlTags(), escapeHtml() for XSS prevention
- Validate JSON input doesn't exceed size limits

Create src/mcpd/src/middleware/validate.ts:
- createValidationMiddleware(schema: ZodSchema) factory
- Validates request.body against Zod schema
- Returns 400 Bad Request with Zod errors formatted

Document security decisions in src/mcpd/SECURITY.md with rationale for each configuration choice.

### 3.5. Implement error handling, audit logging middleware, and graceful shutdown with comprehensive tests

**Status:** pending  
**Dependencies:** 3.2, 3.3, 3.4  

Create global error handler, audit logging onResponse hook that records all operations to database, and graceful shutdown handling with connection draining and proper signal handling.

**Details:**

Create src/mcpd/src/middleware/error-handler.ts:
- Global Fastify error handler via setErrorHandler
- Handle Zod validation errors -> 400 Bad Request
- Handle Prisma errors (P2002 unique, P2025 not found) -> appropriate HTTP codes
- Handle custom application errors with error codes
- Log errors with pino, include stack trace in development only
- Never expose internal errors to clients in production

Create src/mcpd/src/middleware/audit.ts:
- auditMiddleware(prisma: PrismaClient, auditLogger: AuditLogger) factory
- Fastify onResponse hook
- Create AuditLog record with: userId (from request.user), action (HTTP method), resource (URL), details ({ statusCode, responseTime, ip })
- Skip audit logging for /health endpoint
- Async write - don't block response
- Handle audit write failures gracefully (log warning, don't fail request)

Create src/mcpd/src/utils/shutdown.ts:
- setupGracefulShutdown(app: FastifyInstance, prisma: PrismaClient) function
- Handle SIGTERM, SIGINT signals
- Stop accepting new connections
- Wait for in-flight requests (configurable timeout, default 30s)
- Disconnect Prisma client
- Exit with appropriate code

Create services/audit-logger.ts interface that Task 14 will implement.
