LLM模型上下文协议生成工具

一个CLI工具,用于生成具有清晰架构、全面代码规范检查的LLM-ready的MCP(Model Context Protocol)服务器项目,适用于AI辅助开发场景。

  • by platform-q-ai
  • TypeScript
  • 本地部署
  • 更新于
在 GitHub 查看 platform-q-ai/mcp-4-llm

使用说明

mcp-4-llm

一个CLI工具,可生成LLM就绪的MCP(模型上下文协议)服务器项目,具有干净的架构、全面的linting和自主开发护栏。

快速开始

npx @pqai/mcp-4-llm my-service
cd my-service
npm run dev

为什么要为LLM开发提供干净的架构?

清洁架构不仅仅是关于代码组织——它是关于创建LLM可以理解、遵循和一致生成的可预测模式。

核心观点:法学硕士需要模式,而不是自由

当LLM处理您的代码库时,它会根据读取的代码构建一个心智模型。你的模式越一致和明确,LLM就越能:

  1. 理解现有代码 -根据文件的位置和命名识别每个文件的功能
  2. 生成新代码 -创建新功能时遵循既定模式
  3. 做出正确的决定 -知道把东西放在哪里,进口什么
  4. 抓住错误 -确定什么时候违反了既定的模式

非结构化代码库的问题

如果没有明确的架构,LLM将面临不断的模糊性:

问题 LLM后果
业务逻辑与HTTP处理程序混合 LLM将逻辑放在错误的地方
错误处理不一致 LLM生成混合 throw、返回代码和结果类型
无导入约定 LLM创建循环依赖关系
域逻辑中的数据库调用 LLM将业务规则耦合到基础架构
各种测试方法 LLM生成不一致的测试风格

这导致了 漂移--LLM生成的每个更改都会使代码库稍微不那么一致,随着时间的推移而复合。

清洁架构如何解决这个问题

清洁架构提供 明确的、机器可读的规则 限制LLM输出:

1.层分离=明确放置规则

src/
├── domain/           # Pure business logic, no imports from other layers
├── application/      # Use cases, orchestration, ports (interfaces)
├── infrastructure/   # External adapters (DB, HTTP, files)
├── mcp/              # MCP protocol layer (tools, server)
└── di/               # Dependency injection wiring

当LLM需要添加“验证电子邮件”功能时,它知道:

  • 纯验证逻辑→ domain/value-objects/
  • 协调多个验证→ application/use-cases/
  • 调用电子邮件验证API→ infrastructure/services/

没有歧义。无需讨论。

2.依赖规则=可预测的导入

图层 可以导入 无法导入
域 仅域 其他所有
应用程序 应用程序,域 基础设施,mcp,di
基础设施 基础设施、应用程序、域 mcp、di
mcp mcp,应用程序,di 域,基础设施
应用,基础设施,MCP

这些规则是 由ESLint在编译时强制执行LLM不能意外创建:

  • 导入的域代码 express
  • 直接调用数据库的用例
  • 层之间的循环依赖关系

3.桶出口=一致的进口模式

每个目录都有一个 index.ts 导出其公共API:

// LLM always writes this:
import { User, Email } from '../domain/index.js';

// Never this:
import { User } from '../domain/entities/user.entity.js';
import { Email } from '../domain/value-objects/email.vo.js';

这给LLMs一个 单一、可预测的导入模式 跟随。

4.结构化错误=丰富的错误上下文

每个错误都必须有:

{
  code: 'USER_NOT_FOUND',        // Machine-readable identifier
  message: 'User not found',     // Human-readable description
  suggestedFix: 'Check the user ID', // Actionable guidance
  isRetryable: false,            // Can the operation be retried?
  category: 'not_found'          // Error classification
}

当LLM生成错误处理时,它会生成 一致的、信息性错误 这有助于人类和其他LLM了解出了什么问题。

5.用例模式=可预测流

每个用例都遵循相同的结构:

class CreateUserUseCase {
  async execute(input: unknown): Promise<User> {
    // 1. Validate input with Zod
    const validated = CreateUserSchema.parse(input);

    // 2. Execute business logic
    const user = User.create(validated);

    // 3. Persist via port
    await this.userRepository.save(user);

    // 4. Return result
    return user;
  }
}

LLMs可以 可靠地生成新的用例 因为模式是明确的和强制的。

复合效应

每个约束都会使其他约束的有效性倍增:

  • 图层规则+桶导出=无导入混淆
  • 结构化错误+用例模式=一致的错误传播
  • 域隔离+端口/适配器=易于添加新集成
  • BDD功能+用例=符合业务需求的测试

结果:LLM生成的代码无缝地融入你的代码库,即使在数千次人工智能辅助的更改中也能保持一致性。

生成什么

my-service/
├── src/
│   ├── domain/           # Pure business logic (no external deps)
│   │   ├── entities/     # Core business objects
│   │   ├── value-objects/# Immutable, validated types
│   │   └── errors/       # Domain-specific errors
│   ├── application/      # Use cases and port interfaces
│   │   ├── use-cases/    # Business operations
│   │   ├── ports/        # Interface definitions
│   │   └── schemas/      # Zod validation schemas
│   ├── infrastructure/   # External adapters
│   ├── mcp/              # MCP server and tools
│   │   ├── server.ts     # MCP server setup
│   │   └── tools/        # MCP tool implementations
│   ├── di/               # Dependency injection
│   └── index.ts          # Entry point
├── tests/
│   ├── unit/             # Unit tests
│   ├── step-definitions/ # BDD step implementations
│   └── mocks/            # Test doubles
├── features/             # BDD feature files
├── scripts/
│   └── check-code-quality.sh
├── CLAUDE.md             # LLM development guide
├── AGENTS.md             # LLM development guide (identical)
└── [config files]

提交前质量检查

生成的项目包括 41次质量检查 该块提交包含不完整或不兼容的代码。所有检查均为 错误,而不是警告.

哲学:左转,快速失败

每个检查都有特定的原因:

  1. 在问题恶化之前抓住问题 -今天的TODO明天就会变成技术债务
  2. 保持LLM上下文质量 -不一致的代码混淆了未来的LLM交互
  3. 强制建筑边界 -预防违规比修复违规更容易
  4. 确保生产准备就绪 -生产中没有占位符代码

检查1:工作标记不完整

为什么? 不完整的工作应该在问题中跟踪,而不是隐藏在代码中。流入生产的TODO和存根变成了看不见的技术债务。

检查 模式 基本原理
1a TODO, FIXME, XXX, HACK, BUG 工作项属于问题跟踪器,而不是代码注释
1b not implemented, placeholder Stub代码表示未完成的工作
1c mock, fake, dummy, stub 测试公用设施不得泄漏到生产中
1c-2 MockService, FakeRepository (CamelCase) Catches测试加倍类样式命名
1d .only(, .skip( 集中/跳过测试会破坏CI并隐藏失败

LLM福利: LLM不会学习生成占位符代码,因为代码库中不存在占位符代码。


检查2:类型安全和代码质量

为什么? 类型安全旁路和棉绒抑制隐藏了真正的问题。他们还教法学硕士坏习惯。

检查 模式 基本原理
2a as any 类型断言绕过TypeScript的安全保证
2b @ts-ignore, @ts-expect-error 错误抑制隐藏了真正的类型问题
2c eslint-disable Lint绕过了隐藏代码质量问题
2d TODO/FIXME 在测试中 测试代码应与生产代码一样完整
2e throw new Error('not implemented') Stub实现表示未完成的工作
2f console.log MCP使用stdout作为协议;使用 console.error 用于日志记录
2g throw new Error() 在域/应用程序中 通用错误缺乏结构;使用 DomainError
2小时 reflect-metadata 不首先导入 tsyrange装饰器需要先加载元数据polyfill

LLM福利: LLM学会使用正确的类型和结构化错误,而不是快捷方式。


检查3:桶出口

为什么? 一致的导入模式降低了人类和LLM的认知负荷。桶导出为每个模块创建一个明确的公共API。

检查 内容 基本原理
3a 层 index.ts 存在 每个层必须公开一个公共API
3b 子目录 index.ts exists 嵌套模块(实体、模式)也需要桶
3c 无直接文件导入 使用 ../schemas/index.js 不 ../schemas/user.schema.js

LLM福利: LLM总是生成相同的导入模式: from '../layer/index.js'.


检查4:Zod验证

为什么? 所有外部输入都必须经过验证。Zod通过TypeScript类型推断提供运行时验证。

检查 内容 基本原理
4 用例调用 .parse() 或 .safeParse() 每个用例都必须验证其输入

LLM福利: LLM了解到验证是强制性的,而不是可选的。


检查5:域错误结构

为什么? 结构化错误支持一致的错误处理、有用的错误消息和重试逻辑。

检查 内容 基本原理
5a base.error.ts 具有抽象属性 基类定义错误契约
5b 错误 code, suggestedFix, isRetryable, category 每个错误都必须提供可操作的信息

LLM福利: LLM会生成所有必填字段的错误,从而在整个系统中实现丰富的错误处理。


检查6:BDD功能覆盖率

为什么? BDD功能充当可执行文档。他们确保业务需求得到测试,并为LLM提供示例。

检查 内容 基本原理
6a features/ 目录存在 BDD是核心架构要求
6b 功能文件存在 至少一个 .feature 需要文件
6c 功能有场景 空的功能文件没有价值
6d 存在步骤定义 功能需要实现才能执行
6e 功能涵盖的用例 业务逻辑应涵盖BDD
6f 最小场景数 每个用例推荐≥2个场景

LLM福利: LLM可以在生成代码之前阅读功能文件以了解业务需求。


检查7:值对象错误

为什么? 值对象是验证的第一行。他们必须抛出结构化错误,而不是通用错误。

检查 内容 基本原理
7 值对象抛出 DomainError 通用 Error 缺乏适当处理的结构

LLM福利: LLM学会使用域错误,即使是在最简单的验证代码中。


检查8:MCP工具错误处理

为什么? MCP工具是外部接口。他们必须优雅地处理错误并返回结构化的响应。

检查 内容 基本原理
8a 工具有try-catch 每个工具都必须处理错误
8b 工具返回结构化错误 返回 {isError: true, code, message, suggestedFix}

LLM福利: LLM生成健壮的工具实现,不会在意外输入时崩溃。


检查9:MCP工具注册

为什么? 工具必须连接好才能调用。未注册的工具是死代码。

检查 内容 基本原理
9 在中注册的工具 server.ts 工具必须从容器中导入和解析

LLM福利: LLMs学习完整的模式:创建工具→ 桶装出口→ 在服务器中注册。


检查10:用例暴露

为什么? 业务逻辑应可通过MCP访问。未公开的用例表明集成不完整。

检查 内容 基本原理
10 通过MCP工具公开的用例 每个用例都应该可以通过MCP调用

LLM福利: LLM明白用例需要相应的MCP工具。


检查11:桶出口使用情况

为什么? 服务器应该从桶中导入工具,而不是直接从文件中导入。

检查 内容 基本原理
11 从工具桶导入服务器 与桶导出模式一致

LLM福利: LLM在整个代码库中看到一致的导入模式。


测试覆盖要求

承诺前执行 80%覆盖率 在所有指标上:

度量 阈值 基本原理
语句 80% 应测试大多数代码路径
分支 80% 应涵盖条件逻辑
函数 80% 应测试公共API
行数 80% 总体代码覆盖率

LLM福利: 高覆盖率意味着LLM在生成新测试时有更多的测试示例可供学习。

ESLint规则(所有错误)

代码质量规则的执行方式如下 错误,而不是警告。警告被忽略;错误得到修复。

规则 设置 基本原理
complexity max 10 复杂的函数很难被人类和LLM理解
max-depth max 4 深度嵌套表示需要重构的代码
max-lines 最大750 大文件应拆分为重点模块
max-lines-per-function max 100 函数应该做好一件事
max-params max 4 许多参数表明需要一个options对象
no-console error(allow-warn,error) stdout保留用于MCP协议通信
@typescript-eslint/no-explicit-any 错误 类型安全不是可选的

LLM福利: LLM生成符合这些约束的代码,默认情况下生成可维护的代码。

建筑边界

ESLint边界规则在编译时强制执行层依赖关系:

图层 可以导入 无法导入 为什么
域 域 其他所有 域必须是纯的,没有外部依赖关系
应用程序 应用程序、领域 基础设施、mcp、di 用例编排但不了解基础设施
基础设施 基础设施、应用程序、域 mcp、di 适配器实现端口,不了解mcp
mcp mcp,应用程序,di 域,基础设施 mcp层通过di使用用例,而不是直接使用
应用,基础设施,MCP,域,将一切连接在一起。

为什么这对LLMs很重要: 当LLM试图导入 express 在域文件中,ESLint立即失败。LLM从错误反馈中学习边界。

用法

npx @pqai/mcp-4-llm <project-name>

或者以交互方式运行:

npx @pqai/mcp-4-llm
# Prompts for project name

生成的项目命令

命令 目的
npm run dev 从热重新加载开始
npm run build 编译TypeScript
npm run start 运行生产构建
npm run test 运行所有测试
npm run test:unit 仅限单元测试
npm run test:features 仅BDD测试
npm run test:coverage 覆盖测试
npm run lint 检查问题
npm run lint:fix 自动修复问题
npm run pre-commit 全质量闸门

预提交流程

npm run pre-commit
    │
    ├── check:code-quality    # Shell script checks (1-11)
    ├── lint                  # ESLint with boundaries
    ├── format:check          # Prettier formatting
    ├── typecheck             # TypeScript compilation
    ├── build                 # Production build
    ├── test:coverage         # Unit tests + 80% threshold
    └── test:features         # BDD/Cucumber tests

开发流程

生成的项目执行严格 红绿重构 TDD/BDD实践。每个功能都必须经历这个循环:

第1阶段:红色-写入失败的功能测试

步骤1.1:写入特征文件

# features/create-thing.feature
Feature: Create Thing
  As a user
  I want to create a thing
  So that I can track my things

  Scenario: Successfully create a thing
    Given I have valid thing data
    When I create the thing
    Then the thing should be created
    And I should receive the thing ID

步骤1.2:执行步骤定义

// tests/step-definitions/create-thing.steps.ts
import { Given, When, Then } from '@cucumber/cucumber';
import { expect } from 'chai';

Given('I have valid thing data', function () {
  this.input = { name: 'Test Thing' };
});

When('I create the thing', async function () {
  const useCase = this.container.resolve(CreateThingUseCase);
  this.result = await useCase.execute(this.input);
});

Then('the thing should be created', function () {
  expect(this.result).to.exist;
});

步骤1.3:验证功能测试失败(红色)

npm run test:features
# Expected: Tests should FAIL because the feature is not implemented yet
# This confirms your tests are actually testing something

关键的:如果测试在这个阶段通过,你的测试就不是在测试正确的东西!

第2阶段:红色-写入失败的单元测试

步骤2.1:为模板编写单元测试

// tests/unit/templates/new-template.test.ts
import { describe, it, expect } from 'vitest';

import { getNewTemplate } from '../../../templates/new-template';

describe('new-template', () => {
  it('should generate valid output', () => {
    const result = getNewTemplate('test-project');
    expect(result).toContain('test-project');
  });
});

步骤2.2:验证单元测试失败(红色)

npm run test:unit
# Expected: Tests should FAIL because the template doesn't exist yet

关键的:在继续之前,BDD测试和单元测试都必须为红色!

第3阶段:绿色-实施以通过测试

步骤3.1:实现模板/生成器代码

现在编写通过测试所需的最小代码:

// templates/new-template.ts
export function getNewTemplate(name: string): string {
  return `// Generated for ${name}`;
}

步骤3.2:验证单元测试通过(绿色)

npm run test:unit
# Expected: Unit tests should now PASS

步骤3.3:验证功能测试通过(绿色)

npm run test:features
# Expected: BDD tests should now PASS

步骤3.4:验证所有质量门是否通过

npm run pre-commit
# Expected: All checks pass (lint, typecheck, coverage, etc.)

第四阶段:REFACTOR-绿色清洁

步骤4.1:提高代码质量

  • 提取辅助函数
  • 改进命名
  • 添加文档
  • 优化性能

步骤4.2:验证测试是否仍然通过

npm run test
npm run pre-commit
# Expected: All tests still pass after refactoring

总结:红绿重构周期

┌─────────────────────────────────────────────────────────────────┐
│                    RED-GREEN-REFACTOR CYCLE                      │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  ┌─────────┐     ┌─────────┐     ┌───────────┐                 │
│  │   RED   │────▶│  GREEN  │────▶│  REFACTOR │──┐              │
│  └─────────┘     └─────────┘     └───────────┘  │              │
│       ▲                                          │              │
│       └──────────────────────────────────────────┘              │
│                                                                  │
│  RED:      1. Write feature file                                │
│            2. Write step definitions                            │
│            3. Run tests → MUST FAIL                             │
│            4. Write unit tests                                  │
│            5. Run tests → MUST FAIL                             │
│                                                                  │
│  GREEN:    6. Implement minimal code                            │
│            7. Run tests → MUST PASS                             │
│            8. Run pre-commit → MUST PASS                        │
│                                                                  │
│  REFACTOR: 9. Improve code quality                              │
│            10. Run tests → MUST STILL PASS                      │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

由内而外实施

从核心向外构建:

  1. 领域 -实体、值对象、域错误
  2. 应用 -用例、端口、模式
  3. 基础设施 -存储库实施、外部服务
  4. 主控程序 -公开用例的工具

LLM发展指南

生成的 CLAUDE.md 和 AGENTS.md 文件包含LLM的全面指导:

  • 关键规则 -从不做/总是做清单
  • 架构图 -视觉层次结构
  • 代码模式 -每种模式的示例
  • 错误处理 -如何创建和处理错误
  • 测试模式 -单元和BDD测试示例
  • 常见错误 -错误及其修复

这些文件由Claude Code和兼容的AI编码助手自动加载。

需求

  • Node.js 18+
  • npm 9+

许可证

麻省理工学院