数据生产者消费者模式检测引擎

静态分析引擎,用于检测数据生产者和消费者之间的模式不匹配。

  • by Mnehmos
  • TypeScript
  • 本地部署
  • 更新于
在 GitHub 查看 Mnehmos/mnehmos.trace.mcp

使用说明

mnehmos.trace.mcp

静态分析引擎,用于检测数据生产者和消费者之间的模式不匹配。

它做什么

跟踪MCP发现以下各项之间不匹配:

  • 后端API响应和前端期望
  • MCP工具输出和使用它们的客户端代码
  • 服务A的事件和服务B的处理程序
  • REST端点和HTTP客户端调用
  • GraphQL模式和Apollo客户端钩子
Producer returns:    { characterClass: "Fighter", hitPoints: 45 }
Consumer expects:    { class: "Fighter", hp: 45 }
Result:              ❌ Mismatch detected before runtime

特性

核心能力

特性 描述
模式提取 从MCP工具、OpenAPI、TypeScript、tRPC、REST端点、GraphQL中提取模式
使用情况跟踪 跟踪客户端代码如何通过属性访问模式使用模式
失配检测 将生产者模式与消费者期望进行比较
代码生成 从生产者模式构建消费者代码(反之亦然)
观看模式 持续验证文件更改

第二阶段能力

特性 描述
模式匹配器 支持调用、装饰器、属性、导出和链模式的可扩展模式检测
导入分辨率 具有导入图构建和循环依赖处理的跨文件类型解析
REST检测 通过验证中间件支持快速提取端点
HTTP客户端跟踪 fetch()和axios调用检测与URL提取和类型推断
GraphQL支持 SDL模式解析、Apollo服务器解析器和Apollo客户端钩子跟踪

第三阶段能力

特性 描述
Python AST解析器 支持Pydantic模型的FastAPI、Flask和MCP工具提取
Go语言分析器 使用Chi、Gin和stdlib HTTP处理程序检测进行结构/接口提取
gRPC/Protobuf支持 Proto3解析,包括消息、枚举、服务和流式RPC提取
Python HTTP客户端 通过响应属性跟踪进行请求、httpx和aiohttp库检测

测试覆盖率

1047项测试通过 在16个测试套件中:

测试套件 测试
图案匹配器 85
REST检测 87
HTTP客户端跟踪 90
GraphQL支持 109
导入分辨率 56
核心(适配器、OpenAPI、tRPC) 234
Python AST 121
gRPC/Protobuf 124
Go解析器 106
Python HTTP客户端 35

安装

# Clone the repository
git clone https://github.com/Mnehmos/mnehmos.trace.mcp.git

# Navigate to the directory
cd mnehmos.trace.mcp

# Install dependencies
npm install

# Build the project
npm run build

配置

添加到您的MCP客户端配置中(例如。, claude_desktop_config.json 或Roo代码设置):

{
  "mcpServers": {
    "trace-mcp": {
      "command": "node",
      "args": ["/path/to/trace-mcp/dist/index.js"],
      "env": {}
    }
  }
}

支持格式

Trace MCP通过可插拔适配器注册表支持跨多种规范格式的模式提取和比较。

支持的框架概述

类别 框架
API规范 OpenAPI 3.0+,Swagger
远程过程调用 MCP(Zod)、tRPC、gRPC/原蟾蜍
REST服务器 Express、Fastify、FastAPI、Flask、Chi、Gin、Go stdlib
HTTP客户端 fetch()、axios、请求、httpx、aiohttp
图查询语言 SDL模式、Apollo服务器、Apollo客户端
类型系统 TypeScript接口、Zod模式、Pydantic模型、Go结构

支持的语言

语言 生产者检测 消费者追踪
TypeScript MCP工具、tRPC、Express、Fastify、GraphQL解析器 callTool()、fetch、axios、Apollo客户端
python FastAPI、Flask、MCP工具、Pydantic模型 请求、httpx、aiohttp
走 Chi、Gin、stdlib处理程序、结构体、接口 --
协议缓冲区 消息、枚举、服务、流式RPC --

MCP服务器架构(Zod)

使用Zod模式从服务器源代码中提取MCP工具定义。

server.tool(
  "get_character",
  "Fetch character data",
  {
    characterId: z.string().describe("Character ID"),
  },
  async (args) => {
    // implementation
  }
);

架构ID格式: endpoint:GET:/tools/get_character@./server.ts


OpenAPI/Swagger规格

从OpenAPI 3.0+规范中提取模式,支持端点、请求体、响应和组件模式。

openapi: 3.0.0
info:
  title: Character API
  version: 1.0.0
paths:
  /characters/{id}:
    get:
      parameters:
        - name: id
          in: path
          schema:
            type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Character'
components:
  schemas:
    Character:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        class:
          type: string
      required:
        - id
        - name
        - class

架构ID格式: endpoint:GET:/characters/{id}@./api.yaml

使用示例:

const result = await client.callTool("extract_schemas", {
  rootDir: "./backend",
  include: ["**/*.openapi.yaml", "**/*.swagger.json"],
});

TypeScript接口和类型

从TypeScript源文件中提取导出的接口、类型别名和枚举。支持的实用程序类型包括 Pick, Omit, Partial, Required,以及 Record.

export interface Character {
  id: string;
  name: string;
  class: "Fighter" | "Wizard" | "Rogue";
  hitPoints: number;
  stats: {
    strength: number;
    dexterity: number;
    constitution: number;
  };
}

export type ReadonlyCharacter = Readonly<Character>;

export enum CharacterClass {
  Fighter = "Fighter",
  Wizard = "Wizard",
  Rogue = "Rogue",
}

架构ID格式: interface:Character@./types.ts

支持的实用程序类型:

  • Pick<T, K> -从界面中选择属性
  • Omit<T, K> -从界面中排除属性
  • Partial<T> -将所有属性设置为可选
  • Required<T> -将所有属性设置为必需
  • Record<K, T> -具有特定键和值类型的对象

使用示例:

const result = await client.callTool("extract_schemas", {
  rootDir: "./shared",
  include: ["**/*.ts", "**/*.tsx"],
});
// Returns interfaces with ID format: interface:CharacterClass@./types.ts

tRPC路由器

从tRPC路由器中提取过程模式,包括输入/输出类型、查询、变异和订阅处理程序。处理嵌套路由器和中间件。

import { z } from "zod";
import { publicProcedure, router } from "./trpc";

export const appRouter = router({
  users: router({
    getById: publicProcedure
      .input(z.string())
      .output(z.object({
        id: z.string(),
        name: z.string(),
        email: z.string().email(),
      }))
      .query(async ({ input }) => {
        // implementation
      }),
    
    create: publicProcedure
      .input(z.object({
        name: z.string(),
        email: z.string().email(),
      }))
      .output(z.object({
        id: z.string(),
        name: z.string(),
        email: z.string(),
      }))
      .mutation(async ({ input }) => {
        // implementation
      }),

    onChange: publicProcedure
      .output(z.object({
        userId: z.string(),
        action: z.enum(["created", "updated", "deleted"]),
      }))
      .subscription(async () => {
        // implementation
      }),
  }),
});

架构ID格式: trpc:users.getById@./router.ts

检测到的元素:

  • 路由器定义(router({ ... }))
  • 嵌套路由器(users: router({ ... }))
  • 程序(.query(), .mutation(), .subscription())
  • 输入模式(.input(zod_schema))
  • 输出模式(.output(zod_schema))

使用示例:

const result = await client.callTool("extract_schemas", {
  rootDir: "./backend/trpc",
  include: ["**/*.router.ts"],
});
// Returns procedures with ID format: trpc:users.getById@./router.ts

REST端点(快速和快速)

从Express和Fastify应用程序中提取端点模式,包括路由参数、请求体、响应类型和验证中间件。

快速

import express from "express";
import { z } from "zod";

const app = express();

// Basic route with typed response
app.get("/users/:id", (req, res) => {
  const user: User = getUserById(req.params.id);
  res.json(user);
});

// Route with Zod validation middleware
app.post("/users", 
  validate(z.object({
    name: z.string(),
    email: z.string().email(),
  })),
  (req, res) => {
    res.status(201).json({ id: "123", ...req.body });
  }
);

// Router-based routes
const router = express.Router();
router.get("/health", (req, res) => res.json({ status: "ok" }));
app.use("/api", router);

架构ID格式: rest:GET:/users/:id@./app.ts

快车

import Fastify from "fastify";

const fastify = Fastify();

// Route with JSON Schema validation
fastify.post("/users", {
  schema: {
    body: {
      type: "object",
      properties: {
        name: { type: "string" },
        email: { type: "string", format: "email" },
      },
      required: ["name", "email"],
    },
    response: {
      201: {
        type: "object",
        properties: {
          id: { type: "string" },
          name: { type: "string" },
        },
      },
    },
  },
}, async (request, reply) => {
  return { id: "123", name: request.body.name };
});

// Shorthand methods
fastify.get("/health", async () => ({ status: "ok" }));

架构ID格式: rest:POST:/users@./server.ts

检测到的元素:

  • HTTP方法:GET、POST、PUT、PATCH、DELETE
  • 路径参数(:id, :userId)
  • 请求主体模式(Zod、Joi、celebrate、JSON模式)
  • 响应类型推断
  • 路由器前缀和安装

使用示例:

const result = await client.callTool("extract_schemas", {
  rootDir: "./backend",
  include: ["**/*.ts"],
});
// Returns endpoints with ID format: rest:GET:/users/:id@./routes.ts

HTTP客户端(fetch和axios)

跟踪HTTP客户端调用,以检测消费者对API响应的期望。

fetch()API

// Basic fetch with type assertion
const response = await fetch("/api/users");
const users: User[] = await response.json();

// fetch with request options
const newUser = await fetch("/api/users", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ name: "Alice" }),
}).then(res => res.json()) as CreateUserResponse;

// Template literal URLs
const userId = "123";
const user = await fetch(`/api/users/${userId}`).then(r => r.json());

// Property access tracking
console.log(user.name, user.email, user.profile.avatar);

检测到的元素:

  • URL提取(静态字符串、模板文字、变量)
  • HTTP方法检测
  • 类型断言和泛型
  • 响应数据的属性访问模式

轴

import axios from "axios";

// Basic GET request
const { data: users } = await axios.get<User[]>("/api/users");

// POST with typed response
const response = await axios.post<CreateUserResponse>("/api/users", {
  name: "Bob",
  email: "bob@example.com",
});

// Instance with base URL
const api = axios.create({ baseURL: "https://api.example.com" });
const profile = await api.get<Profile>("/me");

// Destructured property access
const { name, email } = response.data;

架构ID格式: http-client:GET:/api/users@./client.ts

检测到的元素:

  • axios方法: .get(), .post(), .put(), .patch(), .delete()
  • 泛型类型参数(axios.get<User>)
  • 通过以下方式创建实例 axios.create()
  • 基本URL解析
  • 响应数据属性访问

使用示例:

const result = await client.callTool("trace_usage", {
  rootDir: "./frontend/src",
  include: ["**/*.ts", "**/*.tsx"],
});
// Returns HTTP client calls with ID format: http-client:GET:/api/users@./api.ts

GraphQL(SDL和Apollo)

从GraphQL SDL文件中提取模式,并跟踪Apollo服务器解析器和Apollo客户端钩子。

SDL架构文件

# schema.graphql
type User {
  id: ID!
  name: String!
  email: String!
  posts: [Post!]!
}

type Post {
  id: ID!
  title: String!
  content: String!
  author: User!
}

type Query {
  user(id: ID!): User
  users: [User!]!
  post(id: ID!): Post
}

type Mutation {
  createUser(name: String!, email: String!): User!
  createPost(title: String!, content: String!, authorId: ID!): Post!
}

架构ID格式: graphql:Query.user@./schema.graphql

Apollo服务器解析程序

import { ApolloServer } from "@apollo/server";

const resolvers = {
  Query: {
    user: async (_, { id }) => {
      return db.users.findById(id);
    },
    users: async () => {
      return db.users.findAll();
    },
  },
  Mutation: {
    createUser: async (_, { name, email }) => {
      return db.users.create({ name, email });
    },
  },
  User: {
    posts: async (parent) => {
      return db.posts.findByAuthor(parent.id);
    },
  },
};

const server = new ApolloServer({ typeDefs, resolvers });

架构ID格式: graphql-resolver:Query.user@./resolvers.ts

阿波罗客户端挂钩

import { useQuery, useMutation, gql } from "@apollo/client";

const GET_USER = gql`
  query GetUser($id: ID!) {
    user(id: $id) {
      id
      name
      email
    }
  }
`;

const CREATE_USER = gql`
  mutation CreateUser($name: String!, $email: String!) {
    createUser(name: $name, email: $email) {
      id
      name
    }
  }
`;

function UserProfile({ userId }: { userId: string }) {
  const { data, loading, error } = useQuery(GET_USER, {
    variables: { id: userId },
  });

  const [createUser] = useMutation(CREATE_USER);

  if (loading) return <Spinner />;
  if (error) return <Error message={error.message} />;

  return <div>{data.user.name}</div>;
}

架构ID格式: graphql-client:GetUser@./UserProfile.tsx

检测到的元素:

  • SDL类型:标量、对象、输入、枚举、接口、联合
  • 查询和突变定义
  • 字段参数和返回类型
  • Apollo客户端挂钩: useQuery, useMutation, useLazyQuery, useSubscription
  • 操作名称和变量
  • 查询中的选定字段

使用示例:

// Extract GraphQL schemas
const schemas = await client.callTool("extract_schemas", {
  rootDir: "./backend",
  include: ["**/*.graphql", "**/resolvers.ts"],
});

// Trace Apollo Client usage
const usage = await client.callTool("trace_usage", {
  rootDir: "./frontend/src",
  include: ["**/*.tsx"],
});

// Compare for mismatches
const report = await client.callTool("compare", {
  producerDir: "./backend",
  consumerDir: "./frontend/src",
  format: "markdown",
});

Python(FastAPI、Flask、MCP工具)

使用完整的Pydantic模型支持从Python web框架和MCP工具定义中提取端点模式。

快速API

from fastapi import FastAPI, APIRouter
from pydantic import BaseModel
from typing import Optional, List

class Character(BaseModel):
    id: str
    name: str
    character_class: str
    level: int = 1
    skills: List[str] = []

class CreateCharacterRequest(BaseModel):
    name: str
    character_class: str
    background: Optional[str] = None

app = FastAPI()
router = APIRouter(prefix="/api/v1")

@app.get("/characters/{character_id}")
async def get_character(character_id: str) -> Character:
    return Character(id=character_id, name="Hero", character_class="Fighter")

@router.post("/characters")
async def create_character(request: CreateCharacterRequest) -> Character:
    return Character(id="123", name=request.name, character_class=request.character_class)

app.include_router(router)

架构ID格式: python:GET:/characters/{character_id}@./main.py

烧瓶

from flask import Flask, Blueprint, request, jsonify

app = Flask(__name__)
api = Blueprint("api", __name__, url_prefix="/api")

@app.route("/health")
def health_check():
    return jsonify({"status": "ok"})

@api.route("/users/<user_id>", methods=["GET"])
def get_user(user_id):
    return jsonify({"id": user_id, "name": "Alice"})

@api.route("/users", methods=["POST"])
def create_user():
    data = request.get_json()
    return jsonify({"id": "123", **data}), 201

app.register_blueprint(api)

架构ID格式: python:GET:/api/users/<user_id>@./app.py

MCP工具(Python)

from mcp import Server

server = Server("character-tools")

@server.tool()
async def get_character(character_id: str) -> dict:
    """Fetch character data by ID."""
    return {"id": character_id, "name": "Hero", "class": "Fighter"}

@mcp.tool()
def roll_dice(dice: str, modifier: int = 0) -> dict:
    """Roll dice with optional modifier."""
    return {"result": 15, "expression": dice, "modifier": modifier}

架构ID格式: python-mcp:get_character@./tools.py

Pydantic模型

from pydantic import BaseModel, Field
from typing import Optional, List, Dict, Union, Literal
from enum import Enum

class CharacterClass(str, Enum):
    FIGHTER = "Fighter"
    WIZARD = "Wizard"
    ROGUE = "Rogue"

class Stats(BaseModel):
    strength: int = Field(ge=1, le=20)
    dexterity: int = Field(ge=1, le=20)
    constitution: int = Field(ge=1, le=20)

class Character(BaseModel):
    id: str
    name: str
    character_class: CharacterClass
    level: int = Field(default=1, ge=1, le=20)
    stats: Stats
    equipment: List[str] = []
    metadata: Optional[Dict[str, str]] = None

检测到的元素:

  • 装饰人员: @app.get(), @app.post(), @router.*, @app.route(), @blueprint.route()
  • MCP装饰师: @mcp.tool(), @server.tool()
  • 派丹蒂克 BaseModel 带字段提取的类
  • 类型注释: Optional, Union, List, Dict, Literal
  • 枚举类型的

使用示例:

const result = await client.callTool("extract_schemas", {
  rootDir: "./backend",
  include: ["**/*.py"],
});
// Returns endpoints with ID format: python:GET:/characters/{id}@./main.py

Go语言(池、金、stdlib)

从Go源文件中提取结构定义、接口和HTTP端点模式。

带有JSON标签的结构

package models

type Character struct {
    ID        string   `json:"id"`
    Name      string   `json:"name"`
    Class     string   `json:"class"`
    Level     int      `json:"level"`
    HitPoints int      `json:"hp"`
    Skills    []string `json:"skills,omitempty"`
}

type Stats struct {
    Strength     int `json:"str"`
    Dexterity    int `json:"dex"`
    Constitution int `json:"con"`
}

// Embedded struct
type CharacterWithStats struct {
    Character
    Stats Stats `json:"stats"`
}

架构ID格式: go-struct:Character@./models/character.go

接口

package services

type CharacterService interface {
    GetByID(id string) (*Character, error)
    Create(req CreateRequest) (*Character, error)
    Update(id string, req UpdateRequest) (*Character, error)
    Delete(id string) error
}

type Repository interface {
    Find(query Query) ([]Character, error)
    Save(character *Character) error
}

架构ID格式: go-interface:CharacterService@./services/character.go

stdlib HTTP处理程序

package main

import (
    "encoding/json"
    "net/http"
)

func main() {
    http.HandleFunc("/health", healthHandler)
    http.HandleFunc("/api/characters", charactersHandler)
    http.HandleFunc("/api/characters/", characterByIDHandler)
    http.ListenAndServe(":8080", nil)
}

func healthHandler(w http.ResponseWriter, r *http.Request) {
    json.NewEncoder(w).Encode(map[string]string{"status": "ok"})
}

func charactersHandler(w http.ResponseWriter, r *http.Request) {
    switch r.Method {
    case http.MethodGet:
        // List characters
    case http.MethodPost:
        // Create character
    }
}

架构ID格式: go-http:GET:/health@./main.go

Chi路由器

package main

import (
    "github.com/go-chi/chi/v5"
    "net/http"
)

func main() {
    r := chi.NewRouter()
    
    r.Get("/health", healthHandler)
    
    r.Route("/api/characters", func(r chi.Router) {
        r.Get("/", listCharacters)
        r.Post("/", createCharacter)
        r.Get("/{id}", getCharacter)        // Chi param: {id}
        r.Put("/{id}", updateCharacter)
        r.Delete("/{id}", deleteCharacter)
    })
    
    http.ListenAndServe(":8080", r)
}

架构ID格式: go-http:GET:/api/characters/{id}@./main.go

Gin框架

package main

import "github.com/gin-gonic/gin"

func main() {
    r := gin.Default()
    
    r.GET("/health", healthHandler)
    
    api := r.Group("/api")
    {
        api.GET("/characters", listCharacters)
        api.POST("/characters", createCharacter)
        api.GET("/characters/:id", getCharacter)  // Gin param: :id
        api.PUT("/characters/:id", updateCharacter)
        api.DELETE("/characters/:id", deleteCharacter)
    }
    
    r.Run(":8080")
}

架构ID格式: go-http:GET:/api/characters/:id@./main.go

检测到的元素:

  • 带有JSON标签的结构定义
  • 嵌入式结构
  • 接口定义
  • http.HandleFunc() 模式
  • Chi路由器: r.Get(), r.Post(), r.Route(), {param} 语法
  • 杜松子酒框架: r.GET(), r.POST(), r.Group(), :param 语法

使用示例:

const result = await client.callTool("extract_schemas", {
  rootDir: "./backend",
  include: ["**/*.go"],
});
// Returns structs, interfaces, and endpoints

gRPC/Protobuf

解析协议缓冲区定义(proto3)以提取消息类型、枚举、服务和RPC方法。

基本消息

syntax = "proto3";

package character;

message Character {
    string id = 1;
    string name = 2;
    CharacterClass character_class = 3;
    int32 level = 4;
    Stats stats = 5;
    repeated string skills = 6;
}

message Stats {
    int32 strength = 1;
    int32 dexterity = 2;
    int32 constitution = 3;
}

架构ID格式: proto-message:character.Character@./character.proto

枚举

enum CharacterClass {
    CHARACTER_CLASS_UNSPECIFIED = 0;
    CHARACTER_CLASS_FIGHTER = 1;
    CHARACTER_CLASS_WIZARD = 2;
    CHARACTER_CLASS_ROGUE = 3;
}

enum DamageType {
    DAMAGE_TYPE_UNSPECIFIED = 0;
    DAMAGE_TYPE_SLASHING = 1;
    DAMAGE_TYPE_PIERCING = 2;
    DAMAGE_TYPE_FIRE = 3;
}

架构ID格式: proto-enum:character.CharacterClass@./character.proto

一个和地图字段

message Equipment {
    string id = 1;
    string name = 2;
    
    oneof item_type {
        Weapon weapon = 10;
        Armor armor = 11;
        Consumable consumable = 12;
    }
}

message Inventory {
    string character_id = 1;
    map<string, int32> item_counts = 2;
    map<string, Equipment> equipped = 3;
}

架构ID格式: proto-message:character.Equipment@./equipment.proto

服务和RPC

service CharacterService {
    // Unary RPC
    rpc GetCharacter(GetCharacterRequest) returns (Character);
    
    // Server streaming
    rpc ListCharacters(ListRequest) returns (stream Character);
    
    // Client streaming
    rpc UploadInventory(stream Item) returns (UploadResponse);
    
    // Bidirectional streaming
    rpc Chat(stream ChatMessage) returns (stream ChatMessage);
}

message GetCharacterRequest {
    string id = 1;
}

message ListRequest {
    int32 page_size = 1;
    string page_token = 2;
}

架构ID格式: proto-service:character.CharacterService@./character.proto RPC格式: proto-rpc:CharacterService.GetCharacter@./character.proto

知名类型

import "google/protobuf/timestamp.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/any.proto";
import "google/protobuf/struct.proto";

message CharacterEvent {
    string character_id = 1;
    string event_type = 2;
    google.protobuf.Timestamp created_at = 3;
    google.protobuf.Duration duration = 4;
    google.protobuf.Any payload = 5;
    google.protobuf.Struct metadata = 6;
}

检测到的元素:

  • 具有所有字段类型(标量、消息、枚举、重复)的消息
  • 带数值的枚举
  • oneof 字段组
  • map<K, V> 领域
  • 嵌套消息定义
  • 所有流媒体模式的服务定义:
    • Unary: rpc Method(Request) returns (Response)
    • 服务器流媒体: rpc Method(Request) returns (stream Response)
    • 客户端流媒体: rpc Method(stream Request) returns (Response)
    • 双向: rpc Method(stream Request) returns (stream Response)
  • 众所周知的类型: Timestamp, Duration, Any, Struct

使用示例:

const result = await client.callTool("extract_schemas", {
  rootDir: "./proto",
  include: ["**/*.proto"],
});
// Returns messages, enums, and services

Python HTTP客户端(请求、httpx、aiohttp)

在Python代码中跟踪HTTP客户端调用,以检测消费者的期望。

请求库

import requests

# Basic GET
response = requests.get("https://api.example.com/characters")
characters = response.json()

# GET with path parameter
character = requests.get(f"https://api.example.com/characters/{char_id}").json()

# POST with JSON body
new_char = requests.post(
    "https://api.example.com/characters",
    json={"name": "Hero", "class": "Fighter"}
).json()

# Session with base URL
session = requests.Session()
session.headers.update({"Authorization": "Bearer token"})
user = session.get("https://api.example.com/me").json()

# Property access tracking
print(character["name"], character["stats"]["strength"])

架构ID格式: python-http:GET:/characters@./client.py

httpx库

import httpx

# Sync client
response = httpx.get("https://api.example.com/characters")
data = response.json()

# Async client
async with httpx.AsyncClient(base_url="https://api.example.com") as client:
    response = await client.get("/characters")
    characters = response.json()
    
    response = await client.post("/characters", json={"name": "Hero"})
    new_char = response.json()

架构ID格式: python-http:GET:/characters@./client.py

aiohttp库

import aiohttp

async with aiohttp.ClientSession() as session:
    # GET request
    async with session.get("https://api.example.com/characters") as response:
        characters = await response.json()
    
    # POST request
    async with session.post(
        "https://api.example.com/characters",
        json={"name": "Hero", "class": "Fighter"}
    ) as response:
        new_char = await response.json()
    
    # Property access
    print(new_char["id"], new_char["name"])

架构ID格式: python-http:POST:/characters@./client.py

检测到的元素:

  • requests.get(), requests.post()等等。
  • httpx.get(), httpx.post(), AsyncClient 方法
  • aiohttp.ClientSession 方法
  • URL提取(静态字符串、f字符串)
  • HTTP方法检测
  • 响应属性访问(字典键访问)

使用示例:

const result = await client.callTool("trace_usage", {
  rootDir: "./python-client",
  include: ["**/*.py"],
});
// Returns HTTP client calls with property access patterns

建筑

模式匹配器框架

模式匹配器提供了一个可扩展的系统,用于检测跨不同框架的代码模式。位于 src/patterns/:

src/patterns/
├── base.ts          # BasePattern abstract class
├── types.ts         # PatternMatch, PatternContext interfaces
├── registry.ts      # PatternRegistry for plugin management
├── extractors.ts    # Node extractors for AST traversal
├── errors.ts        # Pattern-specific error types
├── rest/            # Express, Fastify patterns
├── http-clients/    # fetch, axios patterns
└── graphql/         # Apollo patterns

支持的图案类型:

  • 通话模式:函数/方法调用(app.get(), fetch())
  • 装饰图案:Types/Python装饰器(@Controller())
  • 房地产模式:对象属性分配
  • 出口模式:模块导出(export const router = ...)
  • 链式图案:方法链(router.get().post())

导入分辨率

跨文件类型解析与导入图形构建。位于 src/languages/import-resolver.ts:

  • 解决 import { Type } from "./types"
  • 处理桶出口(export * from)
  • 通过tsconfig.json支持路径别名
  • 检测和处理循环依赖关系
  • 缓存解析类型以提高性能

工具参考

Trace MCP提供11种工具,分为三类:

岩心分析工具

工具 说明
extract_schemas 从服务器源代码中提取MCP工具定义
extract_file 从单个文件中提取模式
trace_usage 跟踪客户端代码如何使用MCP工具
trace_file 在单个文件中跟踪工具使用情况
compare 完整管道:提取→ 痕迹→ 比较→ 报告

代码生成工具

工具 说明
scaffold_consumer 从生产者模式生成客户端代码
scaffold_producer 根据客户端使用情况生成服务器存根
comment_contract 为已验证的配对添加交叉引用注释

项目管理工具

工具 说明
init_project 使用初始化跟踪项目 .trace-mcp config
watch 监视文件的更改并自动重新验证
get_project_status 获取项目配置、缓存状态和验证结果

工具详细信息

extract_schemas

从服务器源代码中提取MCP工具定义(ProducerSchemas)。扫描 server.tool() 调用并解析它们的Zod模式。还支持OpenAPI、TypeScript接口、tRPC路由器、REST端点和GraphQL模式。

参数:

  • rootDir (必填):服务器源代码根目录
  • include:要包含的球形图案(默认值: **/*.ts)
  • exclude:要排除的球形图案(默认值: node_modules, dist)

例子:

const result = await client.callTool("extract_schemas", {
  rootDir: "./backend/src",
});
// Returns: { success: true, count: 12, schemas: [...] }

extract_file

从单个TypeScript文件中提取MCP工具定义。

参数:

  • filePath (必填):TypeScript文件的路径

trace_usage

跟踪客户端代码如何使用MCP工具。查找 callTool() 调用、HTTP客户端调用和GraphQL挂钩,跟踪在结果上访问哪些属性。

参数:

  • rootDir (必填):消费者源代码的根目录
  • include:球状图案包括
  • exclude:要排除的球形图案

trace_file

在单个TypeScript文件中跟踪MCP工具的使用情况。

参数:

  • filePath (必填):TypeScript文件的路径

compare

完整的分析管道:提取生产者模式,跟踪消费者使用情况,并对其进行比较以发现不匹配。

参数:

  • producerDir (必需):MCP服务器源目录的路径
  • consumerDir (必需):消费者/客户端源目录的路径
  • format:输出格式(json, markdown, summary)
  • strict:严格模式-将缺少的可选属性视为警告
  • direction:数据流向(producer_to_consumer, consumer_to_producer, bidirectional)

示例输出(Markdown):

# mnehmos.trace.mcp Analysis Report

**Generated**: 2025-12-11T02:11:48.624Z

## Summary

| Metric      | Count |
| ----------- | ----- |
| Total Tools | 12    |
| Total Calls | 34    |
| Matches     | 31    |
| Mismatches  | 3     |

## Mismatches

### get_character

- **Type**: MISSING_PROPERTY
- **Description**: Consumer expects "characterClass" but producer has "class"
- **Consumer**: ./components/CharacterSheet.tsx:45
- **Producer**: ./tools/character.ts:23

scaffold_consumer

从生产者模式生成消费者代码。创建正确调用MCP工具的TypeScript函数、React钩子或Zustand操作。

参数:

  • producerDir (必需):MCP服务器源目录的路径
  • toolName (必填):脚手架工具名称
  • target:输出格式(typescript, javascript, react-hook, zustand-action)
  • includeErrorHandling:包括try/catch错误处理(默认值:true)
  • includeTypes:包括TypeScript类型定义(默认值:true)

输出示例:

/**
 * Get character data
 * @trace-contract CONSUMER
 * Producer: ./server/character-tools.ts:23
 */
export async function getCharacter(
  client: McpClient,
  args: GetCharacterArgs
): Promise<GetCharacterResult> {
  try {
    const result = await client.callTool("get_character", args);
    return JSON.parse(result.content[0].text);
  } catch (error) {
    console.error("Error calling get_character:", error);
    throw error;
  }
}

scaffold_producer

根据消费者使用情况生成生产者模式存根。根据客户端代码调用MCP工具的方式创建MCP工具定义。

参数:

  • consumerDir (必填):消费者源目录的路径
  • toolName (必填):脚手架工具名称
  • includeHandler:包含处理程序存根(默认值:true)

输出示例:

import { z } from "zod";

// Tool: get_character
// Scaffolded from consumer at ./components/CharacterSheet.tsx:14
// @trace-contract PRODUCER (scaffolded)

server.tool(
  "get_character",
  "TODO: Add description",
  {
    characterId: z.string(),
  },
  async (args) => {
    // TODO: Implement handler
    // Consumer expects: name, race, level, stats, characterClass
    return {
      content: [
        {
          type: "text",
          text: JSON.stringify({
            name: null, // TODO
            race: null, // TODO
            level: null, // TODO
          }),
        },
      ],
    };
  }
);

comment_contract

为已验证的生产者/消费者对添加交叉引用注释。在两个文件中记录合同关系。

参数:

  • producerDir (必需):MCP服务器源目录的路径
  • consumerDir (必填):消费者源目录的路径
  • toolName (必填):已验证工具的名称
  • dryRun:不写预览(默认值:true)
  • style:评论风格(jsdoc, inline, block)

示例预览:

// Producer comment:
/*
 * @trace-contract PRODUCER
 * Tool: get_character
 * Consumer: ./components/CharacterSheet.tsx:14
 * Args: characterId
 * Validated: 2025-12-11
 */

// Consumer comment:
/*
 * @trace-contract CONSUMER
 * Tool: get_character
 * Producer: ./server/character-tools.ts:23
 * Required Args: characterId
 * Validated: 2025-12-11
 */

init_project

使用初始化跟踪项目 .trace-mcp 用于监视模式和缓存的配置目录。

参数:

  • projectDir (必需):跟踪项目的根目录
  • producerPath (必填):生产者/服务器代码的相对路径
  • consumerPath (必填):消费者/客户代码的相对路径
  • producerLanguage:语言(typescript, python, go, rust, json_schema)
  • consumerLanguage:语言(typescript, python, go, rust, json_schema)

例子:

const result = await client.callTool("init_project", {
  projectDir: "./my-app",
  producerPath: "./backend/src",
  consumerPath: "./frontend/src",
});
// Creates: ./my-app/.trace-mcp/config.json

watch

监视项目文件的更改并自动重新验证合同。

参数:

  • projectDir (必填):根目录 .trace-mcp 配置
  • action: start, stop, status,或 poll

行动:

  • start:开始监视文件更改
  • stop:停止观看
  • status:检查当前观察者状态
  • poll:获取待处理事件和上次验证结果

get_project_status

获取跟踪项目的状态,包括配置、缓存状态和上次验证结果。

参数:

  • projectDir (必填):根目录 .trace-mcp 配置

输出示例:

{
  "success": true,
  "exists": true,
  "projectDir": "/path/to/project",
  "config": {
    "producer": { "path": "./server", "language": "typescript" },
    "consumer": { "path": "./client", "language": "typescript" }
  },
  "isWatching": true,
  "watcherStatus": { "running": true, "pendingChanges": 0 }
}

典型工作流程

1.快速一次性分析

// Compare backend vs frontend, get markdown report
const result = await client.callTool("compare", {
  producerDir: "./backend/src",
  consumerDir: "./frontend/src",
  format: "markdown",
});

2.连续验证(监视模式)

// Initialize project
await client.callTool("init_project", {
  projectDir: ".",
  producerPath: "./server",
  consumerPath: "./client",
});

// Start watching
await client.callTool("watch", {
  projectDir: ".",
  action: "start",
});

// Later: poll for results
const status = await client.callTool("watch", {
  projectDir: ".",
  action: "poll",
});

3.生成缺失代码

// Generate client code from server schema
const consumer = await client.callTool("scaffold_consumer", {
  producerDir: "./server",
  toolName: "get_character",
  target: "react-hook",
});

// Or generate server stub from client usage
const producer = await client.callTool("scaffold_producer", {
  consumerDir: "./client",
  toolName: "save_settings",
});

4.提取多种格式

// Extract from MCP server
const mcpSchemas = await client.callTool("extract_schemas", {
  rootDir: "./backend/mcp",
  include: ["**/*.ts"],
});

// Extract from OpenAPI specification
const openApiSchemas = await client.callTool("extract_schemas", {
  rootDir: "./backend",
  include: ["**/*.openapi.yaml"],
});

// Extract from tRPC router
const trpcSchemas = await client.callTool("extract_schemas", {
  rootDir: "./backend/trpc",
  include: ["**/*.router.ts"],
});

// Extract TypeScript interfaces
const interfaceSchemas = await client.callTool("extract_schemas", {
  rootDir: "./shared",
  include: ["**/*.types.ts"],
});

// Extract REST endpoints (Express/Fastify)
const restSchemas = await client.callTool("extract_schemas", {
  rootDir: "./backend/routes",
  include: ["**/*.ts"],
});

// Extract GraphQL schemas
const graphqlSchemas = await client.callTool("extract_schemas", {
  rootDir: "./backend/graphql",
  include: ["**/*.graphql", "**/resolvers.ts"],
});

5.全栈GraphQL验证

// Extract GraphQL schema and resolvers
const producer = await client.callTool("extract_schemas", {
  rootDir: "./backend",
  include: ["**/*.graphql", "**/resolvers/**/*.ts"],
});

// Trace Apollo Client hooks
const consumer = await client.callTool("trace_usage", {
  rootDir: "./frontend/src",
  include: ["**/*.tsx"],
});

// Compare for schema drift
const report = await client.callTool("compare", {
  producerDir: "./backend",
  consumerDir: "./frontend/src",
  format: "markdown",
});

路线图

完成

  • [x] MCP工具模式提取
  • [x] 消费者使用追踪
  • [x] 基本不匹配检测
  • [x] 代码脚手架(消费者和生产者)
  • [x] 合同意见
  • [x] 具有自动重新验证功能的监视模式
  • [x] OpenAPI/Swagger适配器支持
  • [x] TypeScript接口提取
  • [x] tRPC路由器支持
  • [x] 可插拔适配器注册表
  • [x] 模式匹配器抽象(第2阶段)
  • [x] 跨文件导入解析(第2阶段)
  • [x] REST端点检测-快速和快速(第2阶段)
  • [x] HTTP客户端跟踪-获取和axios(第2阶段)
  • [x] GraphQL支持-SDL、Apollo服务器、Apollo客户端(第2阶段)
  • [x] Python语言支持-FastAPI、Flask、MCP工具、Pydantic(第3阶段)
  • [x] Go语言支持-Chi、Gin、stdlib处理程序、结构(第3阶段)
  • [x] gRPC/Protobuf支持-proto3、消息、服务、流媒体(第3阶段)
  • [x] Python HTTP客户端跟踪-请求、httpx、aiohttp(第3阶段)

计划的

  • []JSON模式适配器
  • []WebSocket消息跟踪
  • []OpenTetry集成
  • []Rust语言支持
  • []Java/Kotlin语言支持

许可证

麻省理工学院