# Task ID: 1 **Title:** Initialize Project Structure and Core Dependencies **Status:** pending **Dependencies:** None **Priority:** high **Description:** Set up the monorepo structure for mcpctl with CLI client, mcpd server, and shared libraries. Configure TypeScript, ESLint, and build tooling. **Details:** Create a monorepo using pnpm workspaces or npm workspaces with the following structure: ``` mcpctl/ ├── src/ │ ├── cli/ # mcpctl CLI tool │ ├── mcpd/ # Backend daemon server │ ├── shared/ # Shared types, utilities, constants │ └── local-proxy/ # Local LLM proxy component ├── docker/ │ └── docker-compose.yml ├── package.json ├── tsconfig.base.json └── pnpm-workspace.yaml ``` Dependencies to install: - TypeScript 5.x - Commander.js for CLI - Express/Fastify for mcpd HTTP server - Zod for schema validation - Winston/Pino for logging - Prisma or Drizzle for database ORM Create base tsconfig.json with strict mode, ES2022 target, and module resolution settings. Set up shared ESLint config with TypeScript rules. **Test Strategy:** Verify project builds successfully with `pnpm build`. Ensure all packages compile without errors. Test workspace linking works correctly between packages. ## Subtasks ### 1.1. Initialize pnpm workspace monorepo with future-proof directory structure **Status:** pending **Dependencies:** None Create the complete monorepo directory structure using pnpm workspaces that accommodates all 18 planned tasks without requiring future refactoring. **Details:** Create root package.json with pnpm workspaces configuration. Create pnpm-workspace.yaml defining all workspace packages. Initialize the following directory structure: ``` mcpctl/ ├── src/ │ ├── cli/ # mcpctl CLI tool (Task 7-10) │ │ ├── src/ │ │ ├── tests/ │ │ └── package.json │ ├── mcpd/ # Backend daemon server (Task 3-6, 14, 16) │ │ ├── src/ │ │ ├── tests/ │ │ └── package.json │ ├── shared/ # Shared types, utils, constants, validation │ │ ├── src/ │ │ │ ├── types/ # TypeScript interfaces/types │ │ │ ├── utils/ # Utility functions │ │ │ ├── constants/# Shared constants │ │ │ ├── validation/ # Zod schemas │ │ │ └── index.ts # Barrel export │ │ ├── tests/ │ │ └── package.json │ ├── local-proxy/ # Local LLM proxy (Task 11-13) │ │ ├── src/ │ │ ├── tests/ │ │ └── package.json │ └── db/ # Database package (Task 2) │ ├── src/ │ ├── prisma/ # Schema and migrations │ ├── seed/ # Seed data │ ├── tests/ │ └── package.json ├── docker/ │ └── docker-compose.yml # Local dev services (postgres) ├── tests/ │ ├── e2e/ # End-to-end tests (Task 18) │ └── integration/ # Integration tests ├── docs/ # Documentation (Task 18) ├── package.json # Root workspace config ├── pnpm-workspace.yaml └── turbo.json # Optional: Turborepo for build orchestration ``` Each package should have: - Empty src/index.ts with barrel export pattern ready - Empty tests/ directory - package.json with correct workspace dependencies (@mcpctl/shared, @mcpctl/db) Use dependency injection patterns from the start by creating interfaces in shared/src/types/ for key services. CRITICAL STRUCTURAL CHANGE: The monorepo workspace packages directory has been renamed from `packages/` to `src/`. All path references in this subtask must use `src/` instead of `packages/`. Updated directory structure to implement: ``` mcpctl/ ├── src/ # All application source code (pnpm workspace packages) │ ├── cli/ # @mcpctl/cli - CLI tool (Task 7-10) │ │ ├── src/ │ │ ├── tests/ │ │ └── package.json │ ├── mcpd/ # @mcpctl/mcpd - Backend daemon (Task 3-6, 14, 16) │ │ ├── src/ │ │ ├── tests/ │ │ └── package.json │ ├── shared/ # @mcpctl/shared - Shared types, utils, constants, validation │ │ ├── src/ │ │ │ ├── types/ # TypeScript interfaces/types │ │ │ ├── utils/ # Utility functions │ │ │ ├── constants/ # Shared constants │ │ │ ├── validation/ # Zod schemas │ │ │ └── index.ts # Barrel export │ │ ├── tests/ │ │ └── package.json │ ├── local-proxy/ # @mcpctl/local-proxy - LLM proxy (Task 11-13) │ │ ├── src/ │ │ ├── tests/ │ │ └── package.json │ └── db/ # @mcpctl/db - Database/Prisma (Task 2) │ ├── src/ │ ├── prisma/ # Schema and migrations │ ├── seed/ # Seed data │ ├── tests/ │ └── package.json ├── deploy/ # Deployment configs (docker-compose, k8s manifests) │ ├── docker-compose.yml │ ├── docker-compose.dev.yml │ └── Dockerfile.* ├── docs/ # Documentation (Task 18) ├── tests/ # E2E and integration tests │ ├── e2e/ │ └── integration/ ├── package.json # Root workspace config ├── pnpm-workspace.yaml # Points to src/* ├── tsconfig.base.json ├── eslint.config.js ├── vitest.workspace.ts └── turbo.json # Optional: Turborepo for build orchestration ``` The pnpm-workspace.yaml should contain: `packages: ["src/*"]` Key differences from previous structure: - `packages/` renamed to `src/` for cleaner separation of app source from project management files - `docker/` renamed to `deploy/` with additional files (docker-compose.dev.yml, Dockerfile.*) - Added root config files: eslint.config.js, vitest.workspace.ts - All workspace package references in pnpm-workspace.yaml use `src/*` pattern ### 1.2. Configure TypeScript with strict mode and project references **Status:** pending **Dependencies:** 1.1 Set up TypeScript configuration with strict mode, ES2022 target, and proper project references for monorepo build orchestration. **Details:** Create root tsconfig.base.json with shared compiler options: ```json { "compilerOptions": { "target": "ES2022", "module": "NodeNext", "moduleResolution": "NodeNext", "lib": ["ES2022"], "strict": true, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true, "declaration": true, "declarationMap": true, "sourceMap": true, "composite": true, "incremental": true, "noUnusedLocals": true, "noUnusedParameters": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, "exactOptionalPropertyTypes": true, "noUncheckedIndexedAccess": true } } ``` Create package-specific tsconfig.json in each package that extends the base and sets appropriate paths: - cli/tsconfig.json: outDir: dist, references to shared and db - mcpd/tsconfig.json: outDir: dist, references to shared and db - shared/tsconfig.json: outDir: dist (no references, it's the base) - local-proxy/tsconfig.json: references to shared - db/tsconfig.json: references to shared Create tsconfig.json at root with project references to all packages for unified builds. Install TypeScript 5.x as devDependency in root package.json. ### 1.3. Set up Vitest testing framework with workspace configuration **Status:** pending **Dependencies:** 1.2 Configure Vitest as the test framework across all packages with proper workspace setup, coverage reporting, and test-driven development infrastructure. **Details:** Install Vitest and related packages at root level: - vitest - @vitest/coverage-v8 - @vitest/ui (optional, for visual test running) Create root vitest.config.ts: ```typescript import { defineConfig } from 'vitest/config'; export default defineConfig({ test: { globals: true, coverage: { provider: 'v8', reporter: ['text', 'json', 'html'], exclude: ['**/node_modules/**', '**/dist/**', '**/*.config.*'] }, include: ['src/*/tests/**/*.test.ts', 'tests/**/*.test.ts'], testTimeout: 10000 } }); ``` Create vitest.workspace.ts for workspace-aware testing: ```typescript import { defineWorkspace } from 'vitest/config'; export default defineWorkspace([ 'src/cli', 'src/mcpd', 'src/shared', 'src/local-proxy', 'src/db' ]); ``` Create per-package vitest.config.ts files that extend root config. Add npm scripts to root package.json: - "test": "vitest" - "test:run": "vitest run" - "test:coverage": "vitest run --coverage" - "test:ui": "vitest --ui" Create initial test file in src/shared/tests/index.test.ts to verify setup works: ```typescript import { describe, it, expect } from 'vitest'; describe('shared package', () => { it('should be configured correctly', () => { expect(true).toBe(true); }); }); ``` ### 1.4. Configure ESLint with TypeScript rules and docker-compose for local development **Status:** pending **Dependencies:** 1.2 Set up shared ESLint configuration with TypeScript-aware rules, Prettier integration, and docker-compose.yml for local PostgreSQL database. **Details:** Install ESLint and plugins at root: - eslint - @typescript-eslint/parser - @typescript-eslint/eslint-plugin - eslint-config-prettier - eslint-plugin-import Create eslint.config.js (flat config, ESLint 9+): ```javascript import tseslint from '@typescript-eslint/eslint-plugin'; import tsparser from '@typescript-eslint/parser'; export default [ { files: ['src/*/src/**/*.ts'], languageOptions: { parser: tsparser, parserOptions: { project: ['./src/*/tsconfig.json'], tsconfigRootDir: import.meta.dirname } }, plugins: { '@typescript-eslint': tseslint }, rules: { '@typescript-eslint/explicit-function-return-type': 'error', '@typescript-eslint/no-explicit-any': 'error', '@typescript-eslint/no-unused-vars': 'error', '@typescript-eslint/strict-boolean-expressions': 'error', 'no-console': ['warn', { allow: ['warn', 'error'] }] } } ]; ``` Create deploy/docker-compose.yml for local development: ```yaml version: '3.8' services: postgres: image: postgres:16-alpine container_name: mcpctl-postgres ports: - "5432:5432" environment: POSTGRES_USER: mcpctl POSTGRES_PASSWORD: mcpctl_dev POSTGRES_DB: mcpctl volumes: - mcpctl-pgdata:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U mcpctl"] interval: 5s timeout: 5s retries: 5 volumes: mcpctl-pgdata: ``` Add scripts to root package.json: - "lint": "eslint src/*/src/**/*.ts" - "lint:fix": "eslint src/*/src/**/*.ts --fix" - "db:up": "docker-compose -f deploy/docker-compose.yml up -d" - "db:down": "docker-compose -f deploy/docker-compose.yml down" Create .env.example at root with DATABASE_URL template: ``` DATABASE_URL="postgresql://mcpctl:mcpctl_dev@localhost:5432/mcpctl" ``` ### 1.5. Install core dependencies and perform security/architecture review **Status:** pending **Dependencies:** 1.1, 1.3, 1.4 Install all required production dependencies across packages, run security audit, and validate the directory structure supports all 18 planned tasks. **Details:** Install dependencies per package: **src/cli/package.json:** - commander (CLI framework) - chalk (colored output) - js-yaml (YAML parsing) - inquirer (interactive prompts) **src/mcpd/package.json:** - fastify (HTTP server) - @fastify/cors, @fastify/helmet, @fastify/rate-limit (middleware) - zod (schema validation) - also add to shared - pino (logging, built into Fastify) **src/shared/package.json:** - zod (shared validation schemas) **src/db/package.json:** - prisma (ORM) - @prisma/client **src/local-proxy/package.json:** - @modelcontextprotocol/sdk (MCP protocol) **Root devDependencies:** - typescript - vitest, @vitest/coverage-v8 - eslint and plugins (already specified) - tsx (for running TypeScript directly) - rimraf (cross-platform rm -rf for clean scripts) **Security Review Checklist:** 1. Run 'pnpm audit' and verify no high/critical vulnerabilities 2. Verify .gitignore excludes: .env, node_modules, dist, *.log 3. Verify .env.example has no real secrets, only templates 4. Ensure no API keys or secrets in any committed files 5. Document security audit results in SECURITY_AUDIT.md **Architecture Review Checklist:** 1. Verify structure supports Task 2 (db package with prisma/) 2. Verify structure supports Tasks 3-6 (mcpd with src/routes/, src/services/) 3. Verify structure supports Tasks 7-10 (cli with src/commands/) 4. Verify structure supports Tasks 11-13 (local-proxy with src/providers/) 5. Verify tests/ directories exist at package and root level 6. Verify dependency injection interfaces are defined in shared/src/types/ 7. Verify barrel exports in shared/src/index.ts 8. Document architecture decisions in ARCHITECTURE.md