Files

411 lines
13 KiB
Markdown
Raw Permalink Normal View History

2026-02-21 03:10:39 +00:00
# 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.
<info added on 2026-02-21T02:33:52.473Z>
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
</info added on 2026-02-21T02:33:52.473Z>
### 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