Trace MCP
Trace MCP is a static analysis engine that detects schema mismatches between data producers (APIs, backends) and consumers (frontends, clients) across multiple languages and frameworks before runtime.
Core Capabilities:
Schema Extraction: Extract producer schemas from MCP tools (Zod), OpenAPI/Swagger specs, TypeScript interfaces, tRPC routers, REST endpoints (Express, Fastify, FastAPI, Flask, Chi, Gin), GraphQL SDL/Apollo resolvers, Go structs/interfaces, and gRPC/Protobuf definitions. Extract from entire directories with glob patterns or single files.
Consumer Usage Tracing: Analyze how client code consumes schemas by tracking property access patterns,
callTool()invocations, HTTP client calls (fetch, axios, requests, httpx, aiohttp), and GraphQL client hooks (Apollo Client).Mismatch Detection: Compare producer schemas against consumer expectations with a full analysis pipeline. Generate detailed reports in JSON, Markdown, or summary formats with bidirectional validation (producer→consumer, consumer→producer, or both) and optional strict mode.
Code Generation: Scaffold type-safe consumer code (TypeScript functions, React hooks, Zustand actions) from producer schemas, or generate producer stubs from consumer usage patterns. Automatically includes error handling and TypeScript types.
Project Management: Initialize trace projects with persistent configuration, enable watch mode for continuous validation with auto-revalidation on file changes, monitor project status (config, cache, validation results), and add cross-reference comments to document validated contracts.
Supported Languages & Frameworks: TypeScript, Python, Go, and Protobuf with MCP, OpenAPI, tRPC, gRPC, Express, Fastify, FastAPI, Flask, Chi, Gin, GraphQL (SDL/Apollo), and various HTTP client libraries.
Reliability: 1047 tests across 16 suites with an extensible pattern matcher framework supporting call, decorator, property, export, and chain patterns with cross-file import resolution.
Planned adapter support for GraphQL schema validation and mismatch detection between producers and consumers.
Supports JavaScript code analysis for tracing MCP tool usage and generating scaffolded consumer code from producer schemas.
Generates formatted analysis reports showing schema mismatches, tool statistics, and validation results in markdown format.
Provides partial support for Python language analysis in producer and consumer schema extraction and validation workflows.
Generates React hooks from MCP tool schemas, enabling type-safe integration of producer schemas into React applications.
Provides partial support for Rust language analysis in producer and consumer schema extraction and validation workflows.
Analyzes TypeScript code to extract MCP tool definitions, trace usage patterns, detect schema mismatches between producers and consumers, and generate scaffolded code with type definitions.
Extracts and analyzes Zod schema definitions from MCP server tool declarations to validate data contracts between producers and consumers.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Trace MCPcompare my backend and frontend for mismatches"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
mnehmos.trace.mcp
Static analysis engine for detecting schema mismatches between data producers and consumers.
What It Does
Trace MCP finds mismatches between:
Backend API responses and frontend expectations
MCP tool outputs and client code that uses them
Service A's events and Service B's handlers
REST endpoints and HTTP client calls
GraphQL schemas and Apollo Client hooks
Producer returns: { characterClass: "Fighter", hitPoints: 45 }
Consumer expects: { class: "Fighter", hp: 45 }
Result: ❌ Mismatch detected before runtimeRelated MCP server: Trace MCP
Features
Core Capabilities
Feature | Description |
Schema Extraction | Extract schemas from MCP tools, OpenAPI, TypeScript, tRPC, REST endpoints, GraphQL |
Usage Tracing | Track how client code consumes schemas via property access patterns |
Mismatch Detection | Compare producer schemas against consumer expectations |
Code Generation | Scaffold consumer code from producer schemas (and vice versa) |
Watch Mode | Continuous validation on file changes |
Phase 2 Capabilities
Feature | Description |
Pattern Matcher | Extensible pattern detection supporting call, decorator, property, export, and chain patterns |
Import Resolution | Cross-file type resolution with import graph building and circular dependency handling |
REST Detection | Express and Fastify endpoint extraction with validation middleware support |
HTTP Client Tracing | fetch() and axios call detection with URL extraction and type inference |
GraphQL Support | SDL schema parsing, Apollo Server resolvers, and Apollo Client hook tracing |
Phase 3 Capabilities
Feature | Description |
Python AST Parser | FastAPI, Flask, and MCP tool extraction with Pydantic model support |
Go Language Parser | Struct/interface extraction with Chi, Gin, and stdlib HTTP handler detection |
gRPC/Protobuf Support | Proto3 parsing with message, enum, service, and streaming RPC extraction |
Python HTTP Clients | requests, httpx, and aiohttp library detection with response property tracing |
Test Coverage
1047 tests passing across 16 test suites:
Test Suite | Tests |
Pattern Matcher | 85 |
REST Detection | 87 |
HTTP Client Tracing | 90 |
GraphQL Support | 109 |
Import Resolution | 56 |
Core (adapters, OpenAPI, tRPC) | 234 |
Python AST | 121 |
gRPC/Protobuf | 124 |
Go Parser | 106 |
Python HTTP Clients | 35 |
Installation
# 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 buildConfiguration
Add to your MCP client configuration (e.g., claude_desktop_config.json or Roo-Code settings):
{
"mcpServers": {
"trace-mcp": {
"command": "node",
"args": ["/path/to/trace-mcp/dist/index.js"],
"env": {}
}
}
}Supported Formats
Trace MCP supports schema extraction and comparison across multiple specification formats through a pluggable adapter registry.
Summary of Supported Frameworks
Category | Frameworks |
API Specs | OpenAPI 3.0+, Swagger |
RPC | MCP (Zod), tRPC, gRPC/Protobuf |
REST Servers | Express, Fastify, FastAPI, Flask, Chi, Gin, Go stdlib |
HTTP Clients | fetch(), axios, requests, httpx, aiohttp |
GraphQL | SDL schemas, Apollo Server, Apollo Client |
Type Systems | TypeScript interfaces, Zod schemas, Pydantic models, Go structs |
Supported Languages
Language | Producer Detection | Consumer Tracing |
TypeScript | MCP tools, tRPC, Express, Fastify, GraphQL resolvers | callTool(), fetch, axios, Apollo Client |
Python | FastAPI, Flask, MCP tools, Pydantic models | requests, httpx, aiohttp |
Go | Chi, Gin, stdlib handlers, structs, interfaces | — |
Protobuf | Messages, enums, services, streaming RPCs | — |
MCP Server Schemas (Zod)
Extract MCP tool definitions from server source code using Zod schemas.
server.tool(
"get_character",
"Fetch character data",
{
characterId: z.string().describe("Character ID"),
},
async (args) => {
// implementation
}
);Schema ID Format: endpoint:GET:/tools/get_character@./server.ts
OpenAPI / Swagger Specifications
Extract schemas from OpenAPI 3.0+ specifications, supporting endpoints, request bodies, responses, and component schemas.
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
- classSchema ID Format: endpoint:GET:/characters/{id}@./api.yaml
Usage Example:
const result = await client.callTool("extract_schemas", {
rootDir: "./backend",
include: ["**/*.openapi.yaml", "**/*.swagger.json"],
});TypeScript Interfaces & Types
Extract exported interfaces, type aliases, and enums from TypeScript source files. Supports utility types including Pick, Omit, Partial, Required, and 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",
}Schema ID Format: interface:Character@./types.ts
Supported Utility Types:
Pick<T, K>- Select properties from interfaceOmit<T, K>- Exclude properties from interfacePartial<T>- Make all properties optionalRequired<T>- Make all properties requiredRecord<K, T>- Object with specific keys and value type
Usage Example:
const result = await client.callTool("extract_schemas", {
rootDir: "./shared",
include: ["**/*.ts", "**/*.tsx"],
});
// Returns interfaces with ID format: interface:CharacterClass@./types.tstRPC Routers
Extract procedure schemas from tRPC routers, including input/output types, query, mutation, and subscription handlers. Handles nested routers and middleware.
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
}),
}),
});Schema ID Format: trpc:users.getById@./router.ts
Detected Elements:
Router definitions (
router({ ... }))Nested routers (
users: router({ ... }))Procedures (
.query(),.mutation(),.subscription())Input schemas (
.input(zod_schema))Output schemas (
.output(zod_schema))
Usage Example:
const result = await client.callTool("extract_schemas", {
rootDir: "./backend/trpc",
include: ["**/*.router.ts"],
});
// Returns procedures with ID format: trpc:users.getById@./router.tsREST Endpoints (Express & Fastify)
Extract endpoint schemas from Express and Fastify applications, including route parameters, request bodies, response types, and validation middleware.
Express
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);Schema ID Format: rest:GET:/users/:id@./app.ts
Fastify
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" }));Schema ID Format: rest:POST:/users@./server.ts
Detected Elements:
HTTP methods: GET, POST, PUT, PATCH, DELETE
Path parameters (
:id,:userId)Request body schemas (Zod, Joi, celebrate, JSON Schema)
Response type inference
Router prefixes and mounting
Usage Example:
const result = await client.callTool("extract_schemas", {
rootDir: "./backend",
include: ["**/*.ts"],
});
// Returns endpoints with ID format: rest:GET:/users/:id@./routes.tsHTTP Clients (fetch & axios)
Trace HTTP client calls to detect consumer expectations for API responses.
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);Detected Elements:
URL extraction (static strings, template literals, variables)
HTTP method detection
Type assertions and generics
Property access patterns on response data
axios
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;Schema ID Format: http-client:GET:/api/users@./client.ts
Detected Elements:
axios methods:
.get(),.post(),.put(),.patch(),.delete()Generic type parameters (
axios.get<User>)Instance creation with
axios.create()Base URL resolution
Response data property access
Usage Example:
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.tsGraphQL (SDL & Apollo)
Extract schemas from GraphQL SDL files and trace Apollo Server resolvers and Apollo Client hooks.
SDL Schema Files
# 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!
}Schema ID Format: graphql:Query.user@./schema.graphql
Apollo Server Resolvers
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 });Schema ID Format: graphql-resolver:Query.user@./resolvers.ts
Apollo Client Hooks
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>;
}Schema ID Format: graphql-client:GetUser@./UserProfile.tsx
Detected Elements:
SDL types: scalar, object, input, enum, interface, union
Query and Mutation definitions
Field arguments and return types
Apollo Client hooks:
useQuery,useMutation,useLazyQuery,useSubscriptionOperation names and variables
Selected fields in queries
Usage Example:
// 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 Tools)
Extract endpoint schemas from Python web frameworks and MCP tool definitions with full Pydantic model support.
FastAPI
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)Schema ID Format: python:GET:/characters/{character_id}@./main.py
Flask
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)Schema ID Format: python:GET:/api/users/<user_id>@./app.py
MCP Tools (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}Schema ID Format: python-mcp:get_character@./tools.py
Pydantic Models
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]] = NoneDetected Elements:
Decorators:
@app.get(),@app.post(),@router.*,@app.route(),@blueprint.route()MCP decorators:
@mcp.tool(),@server.tool()Pydantic
BaseModelclasses with field extractionType annotations:
Optional,Union,List,Dict,LiteralEnum types
Usage Example:
const result = await client.callTool("extract_schemas", {
rootDir: "./backend",
include: ["**/*.py"],
});
// Returns endpoints with ID format: python:GET:/characters/{id}@./main.pyGo Language (Chi, Gin, stdlib)
Extract struct definitions, interfaces, and HTTP endpoint schemas from Go source files.
Structs with JSON Tags
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"`
}Schema ID Format: go-struct:Character@./models/character.go
Interfaces
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
}Schema ID Format: go-interface:CharacterService@./services/character.go
stdlib HTTP Handlers
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
}
}Schema ID Format: go-http:GET:/health@./main.go
Chi Router
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)
}Schema ID Format: go-http:GET:/api/characters/{id}@./main.go
Gin Framework
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")
}Schema ID Format: go-http:GET:/api/characters/:id@./main.go
Detected Elements:
Struct definitions with JSON tags
Embedded structs
Interface definitions
http.HandleFunc()patternsChi router:
r.Get(),r.Post(),r.Route(),{param}syntaxGin framework:
r.GET(),r.POST(),r.Group(),:paramsyntax
Usage Example:
const result = await client.callTool("extract_schemas", {
rootDir: "./backend",
include: ["**/*.go"],
});
// Returns structs, interfaces, and endpointsgRPC / Protobuf
Parse Protocol Buffer definitions (proto3) to extract message types, enums, services, and RPC methods.
Basic Messages
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;
}Schema ID Format: proto-message:character.Character@./character.proto
Enums
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;
}Schema ID Format: proto-enum:character.CharacterClass@./character.proto
Oneof and Map Fields
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;
}Schema ID Format: proto-message:character.Equipment@./equipment.proto
Services and RPCs
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;
}Schema ID Format: proto-service:character.CharacterService@./character.proto
RPC Format: proto-rpc:CharacterService.GetCharacter@./character.proto
Well-Known Types
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;
}Detected Elements:
Messages with all field types (scalar, message, enum, repeated)
Enums with numeric values
oneoffield groupsmap<K, V>fieldsNested message definitions
Service definitions with all streaming modes:
Unary:
rpc Method(Request) returns (Response)Server streaming:
rpc Method(Request) returns (stream Response)Client streaming:
rpc Method(stream Request) returns (Response)Bidirectional:
rpc Method(stream Request) returns (stream Response)
Well-known types:
Timestamp,Duration,Any,Struct
Usage Example:
const result = await client.callTool("extract_schemas", {
rootDir: "./proto",
include: ["**/*.proto"],
});
// Returns messages, enums, and servicesPython HTTP Clients (requests, httpx, aiohttp)
Trace HTTP client calls in Python code to detect consumer expectations.
requests Library
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"])Schema ID Format: python-http:GET:/characters@./client.py
httpx Library
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()Schema ID Format: python-http:GET:/characters@./client.py
aiohttp Library
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"])Schema ID Format: python-http:POST:/characters@./client.py
Detected Elements:
requests.get(),requests.post(), etc.httpx.get(),httpx.post(),AsyncClientmethodsaiohttp.ClientSessionmethodsURL extraction (static strings, f-strings)
HTTP method detection
Response property access (dictionary key access)
Usage Example:
const result = await client.callTool("trace_usage", {
rootDir: "./python-client",
include: ["**/*.py"],
});
// Returns HTTP client calls with property access patternsArchitecture
Pattern Matcher Framework
The pattern matcher provides an extensible system for detecting code patterns across different frameworks. Located in 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 patternsSupported Pattern Types:
Call patterns: Function/method calls (
app.get(),fetch())Decorator patterns: TypeScript/Python decorators (
@Controller())Property patterns: Object property assignments
Export patterns: Module exports (
export const router = ...)Chain patterns: Method chaining (
router.get().post())
Import Resolution
Cross-file type resolution with import graph building. Located in src/languages/import-resolver.ts:
Resolves
import { Type } from "./types"Handles barrel exports (
export * from)Supports path aliases via tsconfig.json
Detects and handles circular dependencies
Caches resolved types for performance
Tools Reference
Trace MCP provides 11 tools organized into three categories:
Core Analysis Tools
Tool | Description |
| Extract MCP tool definitions from server source code |
| Extract schemas from a single file |
| Trace how client code uses MCP tools |
| Trace tool usage in a single file |
| Full pipeline: extract → trace → compare → report |
Code Generation Tools
Tool | Description |
| Generate client code from producer schema |
| Generate server stub from client usage |
| Add cross-reference comments to validated pairs |
Project Management Tools
Tool | Description |
| Initialize a trace project with |
| Watch files for changes and auto-revalidate |
| Get project config, cache state, and validation results |
Tool Details
extract_schemas
Extract MCP tool definitions (ProducerSchemas) from server source code. Scans for server.tool() calls and parses their Zod schemas. Also supports OpenAPI, TypeScript interfaces, tRPC routers, REST endpoints, and GraphQL schemas.
Parameters:
rootDir(required): Root directory of server source codeinclude: Glob patterns to include (default:**/*.ts)exclude: Glob patterns to exclude (default:node_modules,dist)
Example:
const result = await client.callTool("extract_schemas", {
rootDir: "./backend/src",
});
// Returns: { success: true, count: 12, schemas: [...] }extract_file
Extract MCP tool definitions from a single TypeScript file.
Parameters:
filePath(required): Path to a TypeScript file
trace_usage
Trace how client code uses MCP tools. Finds callTool() invocations, HTTP client calls, and GraphQL hooks, tracking which properties are accessed on results.
Parameters:
rootDir(required): Root directory of consumer source codeinclude: Glob patterns to includeexclude: Glob patterns to exclude
trace_file
Trace MCP tool usage in a single TypeScript file.
Parameters:
filePath(required): Path to a TypeScript file
compare
Full analysis pipeline: extract producer schemas, trace consumer usage, and compare them to find mismatches.
Parameters:
producerDir(required): Path to MCP server source directoryconsumerDir(required): Path to consumer/client source directoryformat: Output format (json,markdown,summary)strict: Strict mode - treat missing optional properties as warningsdirection: Data flow direction (producer_to_consumer,consumer_to_producer,bidirectional)
Example Output (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:23scaffold_consumer
Generate consumer code from a producer schema. Creates TypeScript functions, React hooks, or Zustand actions that correctly call MCP tools.
Parameters:
producerDir(required): Path to MCP server source directorytoolName(required): Name of the tool to scaffoldtarget: Output format (typescript,javascript,react-hook,zustand-action)includeErrorHandling: Include try/catch error handling (default: true)includeTypes: Include TypeScript type definitions (default: true)
Example Output:
/**
* 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
Generate producer schema stub from consumer usage. Creates MCP tool definition based on how client code calls it.
Parameters:
consumerDir(required): Path to consumer source directorytoolName(required): Name of the tool to scaffoldincludeHandler: Include handler stub (default: true)
Example Output:
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
Add cross-reference comments to validated producer/consumer pairs. Documents the contract relationship in both files.
Parameters:
producerDir(required): Path to MCP server source directoryconsumerDir(required): Path to consumer source directorytoolName(required): Name of the validated tooldryRun: Preview without writing (default: true)style: Comment style (jsdoc,inline,block)
Example Preview:
// 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
Initialize a trace project with .trace-mcp config directory for watch mode and caching.
Parameters:
projectDir(required): Root directory for the trace projectproducerPath(required): Relative path to producer/server codeconsumerPath(required): Relative path to consumer/client codeproducerLanguage: Language (typescript,python,go,rust,json_schema)consumerLanguage: Language (typescript,python,go,rust,json_schema)
Example:
const result = await client.callTool("init_project", {
projectDir: "./my-app",
producerPath: "./backend/src",
consumerPath: "./frontend/src",
});
// Creates: ./my-app/.trace-mcp/config.jsonwatch
Watch project files for changes and auto-revalidate contracts.
Parameters:
projectDir(required): Root directory with.trace-mcpconfigaction:start,stop,status, orpoll
Actions:
start: Begin watching for file changesstop: Stop watchingstatus: Check current watcher statepoll: Get pending events and last validation result
get_project_status
Get the status of a trace project including config, cache state, and last validation result.
Parameters:
projectDir(required): Root directory with.trace-mcpconfig
Example Output:
{
"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 }
}Typical Workflow
1. Quick One-Off Analysis
// Compare backend vs frontend, get markdown report
const result = await client.callTool("compare", {
producerDir: "./backend/src",
consumerDir: "./frontend/src",
format: "markdown",
});2. Continuous Validation (Watch Mode)
// 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 Missing Code
// 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 Multiple Formats
// 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. Full-Stack GraphQL Validation
// 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",
});Roadmap
Completed
MCP tool schema extraction
Consumer usage tracing
Basic mismatch detection
Code scaffolding (consumer & producer)
Contract comments
Watch mode with auto-revalidation
OpenAPI/Swagger adapter support
TypeScript interface extraction
tRPC router support
Pluggable adapter registry
Pattern Matcher abstraction (Phase 2)
Cross-file import resolution (Phase 2)
REST endpoint detection - Express & Fastify (Phase 2)
HTTP client tracing - fetch & axios (Phase 2)
GraphQL support - SDL, Apollo Server, Apollo Client (Phase 2)
Python language support - FastAPI, Flask, MCP tools, Pydantic (Phase 3)
Go language support - Chi, Gin, stdlib handlers, structs (Phase 3)
gRPC/Protobuf support - proto3, messages, services, streaming (Phase 3)
Python HTTP client tracing - requests, httpx, aiohttp (Phase 3)
Planned
JSON Schema adapter
WebSocket message tracing
OpenTelemetry integration
Rust language support
Java/Kotlin language support
License
MIT
Available Tools
11 toolscomment_contractC
Add cross-reference comments to validated producer/consumer pairs. Documents the contract relationship in both files.
| Name | Required | Description | Default |
|---|---|---|---|
| producerDir | Yes | Path to MCP server source directory | |
| consumerDir | Yes | Path to consumer source directory | |
| toolName | Yes | Name of the validated tool | |
| dryRun | No | Preview comments without writing to files (default: true) | |
| style | No | Comment style |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description must fully disclose behavioral traits. It states it adds comments to files, implying writes, but does not specify if it is destructive, whether it requires prior validation, or what happens on dryRun=false. Important behavioral details are missing.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences that front-load the core purpose. Every sentence adds value with no redundant information. Ideal structure for quick comprehension.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite good schema coverage, the description lacks context about the validation prerequisite, the commenting process, dryRun behavior, and file modification implications. For a tool with no output schema and annotations, more complete context is needed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% description coverage, so the schema already explains each parameter. The description adds context about 'validated pairs,' but does not provide significant additional meaning beyond the schema. Baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool adds cross-reference comments to producer/consumer pairs and documents the contract relationship. The verb 'add' and resource 'comments' are specific, and it distinguishes from sibling tools like compare or extract_file. However, it does not clarify what 'validated' means, slightly reducing clarity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit guidance on when to use this tool versus alternatives. The description implies it is for documenting contract relationships after validation, but it does not mention prerequisites, when not to use it, or compare to sibling tools. Usage context is left implicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
compareB
Full contract validation: extract producer schemas, trace consumer usage, compare for mismatches. Works across languages (TS↔Python, Go↔TS, etc.) and protocols (REST, GraphQL, gRPC, MCP).
| Name | Required | Description | Default |
|---|---|---|---|
| producerDir | Yes | Path to API/server source directory | |
| consumerDir | Yes | Path to client source directory | |
| format | No | Output format | |
| strict | No | Strict mode for comparison | |
| direction | No | Data flow direction (default: producer_to_consumer) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description must cover behavioral traits. It mentions the what (extract, trace, compare) but not side effects, permissions, or output behavior. Critical details like whether it modifies files or requires network access are missing.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is highly concise: two sentences, each serving a distinct purpose. The first sentence states the core function, the second broadens scope. No unnecessary words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema and 5 parameters, the description should provide more context about the result format or behavior. It omits any hint of what the comparison outputs (e.g., mismatches report), leaving a significant gap for a complex tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with clear descriptions for all 5 parameters. The tool description adds no additional parameter semantics beyond what the schema already provides, meeting the baseline expectation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description provides a specific verb ('validate') and resource ('contract'), and explicitly distinguishes from siblings by stating it performs three actions (extract, trace, compare) in one tool. It covers multiple languages and protocols, making its scope clear.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description does not explain when to use this tool versus the many sibling tools like 'extract_schemas' or 'trace_usage'. There is no guidance on prerequisites, when to avoid, or typical scenarios, leaving the agent to guess.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
extract_fileA
Extract API schemas from a single file. Supports TypeScript, Python, Go, Protobuf, GraphQL SDL, OpenAPI JSON/YAML, and SQL DDL.
| Name | Required | Description | Default |
|---|---|---|---|
| filePath | Yes | Path to source file (any supported language) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries full burden for behavioral disclosure. It only states the function (extracting schemas) without mentioning if the operation is read-only, if it requires any permissions, or what happens on failure. The supported formats are listed, but key behavioral traits are missing.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is composed of two short, information-dense sentences. Every word contributes: the first sentence states the action and scope, the second lists supported languages. No wasted text, and the critical info is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has one parameter and no output schema. The description explains what the tool does and supported inputs, but does not mention the output format or behavior in edge cases (e.g., unsupported file type). For a simple extraction tool, it is minimally viable but leaves gaps in expected return value and error handling.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% (one parameter with description 'Path to source file (any supported language)'). The description adds value beyond the schema by listing the specific supported languages (TypeScript, Python, etc.), which clarifies the acceptable input and adds context to the parameter's scope.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Extract API schemas from a single file', which is a specific verb+resource combination. It lists supported languages, making the tool distinct from siblings like extract_schemas (which likely handles multiple files). The purpose is precise and unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description does not provide guidance on when to use this tool versus alternatives. No explicit 'when-to-use' or 'when-not-to-use' instructions are given. The user must infer from the tool name that it is for single files, but no contrast with sibling tools is provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
extract_schemasA
Extract API schemas from source code. Supports: MCP tools (Zod), OpenAPI/Swagger specs, GraphQL SDL, tRPC routers, REST endpoints (Express/Fastify), gRPC/Protobuf services, Python (FastAPI/Flask decorators), Go (Gin/Chi handlers), and SQL DDL (CREATE TABLE, CREATE TYPE). Auto-detects format from file contents.
| Name | Required | Description | Default |
|---|---|---|---|
| rootDir | Yes | Root directory of server/API source code | |
| include | No | Glob patterns to include (e.g., **/*.ts, **/*.py, **/*.go, **/*.proto, **/*.sql) | |
| exclude | No | Glob patterns to exclude |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full burden. It mentions auto-detection of format, which is helpful, but does not disclose limitations (e.g., behavior on large directories, handling of unsupported formats, or whether schemas are validated). This level of transparency is adequate but not comprehensive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise (one paragraph) and front-loaded with the main purpose. However, the list of supported formats could be better structured (e.g., bullet points) for readability. It is still efficient with no wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity (many formats, no output schema), the description lacks explanation of the output format or sample usage. It does not clarify what the extracted schema looks like (e.g., JSON, YAML, or structured data). This leaves some gaps for an agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% for 3 parameters, each with descriptions. The description adds context about supported formats but does not enhance parameter semantics beyond what the schema provides. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'Extract API schemas from source code.' It lists numerous supported formats (MCP tools, OpenAPI, GraphQL, tRPC, REST, gRPC, Python, Go, SQL DDL), making it distinct from sibling tools like extract_file (which extracts files) and compare (which compares schemas).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage when source code contains API schemas but lacks explicit guidance on when to use this tool versus alternatives. It does not provide when-not-to-use conditions or mention sibling tools as alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_project_statusB
Get the status of a trace project including config, cache state, and last validation result.
| Name | Required | Description | Default |
|---|---|---|---|
| projectDir | Yes | Root directory with .trace-mcp config |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so the description must disclose behavioral traits. It states the output conceptually but does not mention side effects, permissions, or whether it is read-only. The agent cannot infer safety or side effects without more detail.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, well-structured sentence that front-loads the action and resource. It is concise with no extraneous words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (one parameter, no output schema), the description provides sufficient context about what is returned. It could optionally mention that no validation or mutation occurs, but overall it is adequate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the description adds little beyond the schema's 'Root directory with .trace-mcp config'. The description of the parameter is clear but not enriched by the tool description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the purpose: 'Get the status of a trace project' and specifies what is included (config, cache state, last validation result). It effectively distinguishes from sibling tools like init_project or trace_file, which are more about creation or extraction.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit guidance on when to use this tool versus alternatives. The description lacks prerequisites or context for appropriate usage, leaving the agent to infer from the tool name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
init_projectA
Initialize a trace project with .trace-mcp config directory. Creates project structure for watch mode and caching.
| Name | Required | Description | Default |
|---|---|---|---|
| projectDir | Yes | Root directory for the trace project | |
| producerPath | Yes | Relative path to producer/server code | |
| consumerPath | Yes | Relative path to consumer/client code | |
| producerLanguage | No | Producer language (default: typescript) | |
| consumerLanguage | No | Consumer language (default: typescript) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided. Description says it creates project structure, but doesn't disclose idempotency, overwrite behavior, or side effects. Adequate but could be more transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences with no wasted words. Action verb front-loaded. Every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a setup tool with 5 parameters and no output schema, description is too minimal. Does not explain return value, what files are created, or what happens if project already exists. Incomplete for effective agent usage.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%; each parameter is documented in schema. Description adds no additional parameter context beyond schema. Baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states verb (initialize) and resource (trace project), and specifies what it creates (.trace-mcp config directory, project structure for watch mode and caching). Distinguishes from siblings like scaffold_consumer which focus on code scaffolding.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Implies use when starting a trace project, but no explicit guidance on when to use vs alternatives like scaffold_consumer or get_project_status. No exclusions or prerequisites mentioned.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
scaffold_consumerB
Generate type-safe client code from API schemas. Creates TypeScript functions, React hooks, or Zustand actions with full type inference.
| Name | Required | Description | Default |
|---|---|---|---|
| producerDir | Yes | Path to API source directory | |
| toolName | Yes | Name of the endpoint/tool to scaffold | |
| target | No | Output target format | |
| includeErrorHandling | No | Include try/catch error handling | |
| includeTypes | No | Include TypeScript type definitions |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are present, so the description must carry the transparency burden. It fails to disclose side effects (e.g., file overwriting), permissions, or whether the generated code is saved somewhere. Only the basic output types are mentioned.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two concise sentences with the core action front-loaded. Every word adds value; no redundancy or filler. It is efficiently structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite having 5 parameters and no output schema or annotations, the description omits important details like return values, file system effects, required directory structure, or error handling behavior. It is insufficient for a code generation tool of this complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the input schema already documents all parameters. The description adds minimal extra meaning by explaining the output formats (TypeScript, React hooks, Zustand), which aligns with the 'target' enum. Baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: generating type-safe client code from API schemas, and lists concrete outputs (TypeScript functions, React hooks, Zustand actions). This differentiates it from the sibling 'scaffold_producer' which presumably generates server-side code.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for generating client code after having API schemas, but does not explicitly state when to use this over alternatives like scaffold_producer or other tools. No exclusion criteria or prerequisite conditions are provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
scaffold_producerC
Generate API stubs from client usage patterns. Infers schema from how client code calls the API.
| Name | Required | Description | Default |
|---|---|---|---|
| consumerDir | Yes | Path to client source directory | |
| toolName | Yes | Name of the endpoint/tool to scaffold | |
| includeHandler | No | Include handler stub |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must disclose all behavioral traits. It only says 'infers schema' but doesn't mention whether it writes files, requires permissions, or has side effects. Critical behavior like overwriting existing stubs is not disclosed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no redundancy. Every word is functional and front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema or annotations exist. The description does not mention output format (e.g., file paths, generated code language) or prerequisites. For a code generation tool, this is insufficient for an agent to use correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema covers 100% of parameters with descriptions. The description adds context that the stubs are generated from client usage patterns, but does not elaborate on how consumerDir influences inference or how includeHandler affects output.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool generates API stubs and infers schema from client usage. However, it does not explicitly differentiate from its sibling scaffold_consumer, which likely does the opposite (generate client stubs from API schema).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided on when to use this tool versus alternatives like scaffold_consumer or other code generation tools. Context like prerequisites (e.g., consumerDir must exist) is missing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
trace_fileA
Trace API usage in a single file. Detects HTTP calls, GraphQL queries, MCP tool calls, and response property access.
| Name | Required | Description | Default |
|---|---|---|---|
| filePath | Yes | Path to client source file |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. It discloses detection capabilities (HTTP calls, GraphQL queries, etc.), but does not mention side effects, output format, or any limitations. Adequate but not comprehensive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, efficient and front-loaded with core purpose. No redundancy, but could include a brief example or usage hint without bloating.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple tool with one parameter and no output schema, the description covers the essential behavior. However, lacking differentiation from sibling trace_usage reduces completeness slightly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% for the single parameter filePath, which already includes a description. The tool description adds no additional semantic value beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'trace' and the resource 'file', and enumerates specific API types detected (HTTP, GraphQL, MCP, response property). This distinguishes it from sibling tools like trace_usage which may have broader scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool vs alternatives (e.g., trace_usage). No prerequisites, context, or when-not-to-use information provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
trace_usageA
Trace how client code calls APIs. Detects: MCP callTool(), fetch/axios HTTP calls, Apollo Client hooks (useQuery/useMutation), Python requests/aiohttp/httpx, and tracks property access patterns on responses.
| Name | Required | Description | Default |
|---|---|---|---|
| rootDir | Yes | Root directory of client/consumer source code | |
| include | No | Glob patterns to include | |
| exclude | No | Glob patterns to exclude |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. It discloses detection capabilities clearly, but doesn't mention whether it modifies anything, requires network access, or handles errors. Still fairly transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two efficient sentences, front-loaded with key action and specific examples. Every sentence earns its place with zero waste.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Adequately covers the tool's capability for its complexity. No output schema, but description doesn't need to explain return values. Could mention output format or limitations, but still complete enough.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with clear parameter descriptions. The description adds no extra meaning beyond what schema provides, achieving baseline 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states the tool's purpose: tracing how client code calls APIs. It lists specific types of API calls detected (MCP, HTTP, Apollo, Python libraries), making it specific and distinguishing it from siblings like trace_file.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit guidance on when to use this tool vs alternatives like trace_file or compare. The description implies usage for tracing API usage but lacks when-not-to or alternative recommendations.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
watchA
Watch project files for changes and auto-revalidate contracts. Actions: start (begin watching), stop (end watching), status (check state), poll (get pending events).
| Name | Required | Description | Default |
|---|---|---|---|
| projectDir | Yes | Root directory with .trace-mcp config | |
| action | No | Watch action (default: start) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must fully disclose behavioral traits. It explains the four actions and their purposes, but lacks details on side effects, permissions, error handling, or whether the tool is safe/destructive. The behavior is partially transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence followed by a bullet-like list of the four actions. It is concise, front-loaded, and contains no extraneous information. Every part earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has four distinct actions and no output schema. The description does not explain what each action returns (e.g., status output, poll format) or elaborate on 'auto-revalidate contracts'. This leaves gaps for an AI agent to infer behavior. It is complete enough for a simple understanding but lacks depth for robust usage.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% description coverage, so the schema already documents both parameters (projectDir and action with enum). The description adds minimal extra meaning beyond restating the actions, which are already in the enum descriptions. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool watches project files for changes and auto-revalidates contracts, listing four specific actions (start, stop, status, poll). This distinguishes it from all sibling tools, which do not offer file watching.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for file monitoring but does not explicitly state when to use it versus alternatives, nor does it provide when-not or prerequisites. Among siblings, no tool duplicates this functionality, so guidelines are adequate but not explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
7 tool updates
- Changed
compare2 fields changed- changed
Input schema / properties / consumerDir / descriptionPrevious value: -"Path to consumer/client source directory"New value: +"Path to client source directory" - changed
Input schema / properties / producerDir / descriptionPrevious value: -"Path to MCP server source directory"New value: +"Path to API/server source directory"
- Changed
extract_file1 field changed- changed
Input schema / properties / filePath / descriptionPrevious value: -"Path to a TypeScript file"New value: +"Path to source file (any supported language)"
- Changed
extract_schemas2 fields changed- changed
Input schema / properties / include / descriptionPrevious value: -"Glob patterns to include"New value: +"Glob patterns to include (e.g., **/*.ts, **/*.py, **/*.go, **/*.proto, **/*.sql)" - changed
Input schema / properties / rootDir / descriptionPrevious value: -"Root directory of MCP server source code"New value: +"Root directory of server/API source code"
- Changed
scaffold_consumer2 fields changed- changed
Input schema / properties / producerDir / descriptionPrevious value: -"Path to MCP server source directory"New value: +"Path to API source directory" - changed
Input schema / properties / toolName / descriptionPrevious value: -"Name of the tool to scaffold consumer for"New value: +"Name of the endpoint/tool to scaffold"
- Changed
scaffold_producer2 fields changed- changed
Input schema / properties / consumerDir / descriptionPrevious value: -"Path to consumer source directory"New value: +"Path to client source directory" - changed
Input schema / properties / toolName / descriptionPrevious value: -"Name of the tool to scaffold producer for"New value: +"Name of the endpoint/tool to scaffold"
- Changed
trace_file1 field changed- changed
Input schema / properties / filePath / descriptionPrevious value: -"Path to a TypeScript file"New value: +"Path to client source file"
- Changed
trace_usage1 field changed- changed
Input schema / properties / rootDir / descriptionPrevious value: -"Root directory of consumer source code"New value: +"Root directory of client/consumer source code"
11 tool updates
- First observed
comment_contract - First observed
compare - First observed
extract_file - First observed
extract_schemas - First observed
get_project_status - First observed
init_project - First observed
scaffold_consumer - First observed
scaffold_producer - First observed
trace_file - First observed
trace_usage - First observed
watch
TDQS
Scored across 11 tools
Tools are mostly distinct, but pairs like trace_file/trace_usage and extract_file/extract_schemas have overlapping purposes. Descriptions clarify the scope difference (single file vs. general), so ambiguity is low.
All tool names follow a consistent verb_noun snake_case pattern (e.g., extract_file, trace_usage, init_project), making it easy to infer functionality.
With 11 tools, the server covers extraction, tracing, validation, scaffolding, and project management without being bloated. The scope is well-defined.
The tool surface covers the full workflow: project init, schema extraction, usage tracing, contract comparison, cross-referencing comments, scaffolding, and watching. No obvious gaps for the intended domain.
Maintenance
Related MCP Connectors
Monitor MCP servers, API contracts and AI outputs for schema drift. Alerts on breaking changes.
Statically audits MCP tool surfaces for token cost, schema quality, and design issues.
MCP Spec Compliance MCP — audits any MCP server.json against the official Model Context Protocol
Detect breaking changes, generate changelogs, diff, and validate OpenAPI specs.
Related MCP Servers
- -licenseNot gradedqualityNot gradedmaintenanceEnables validation, diff generation, and backend population for Synesthetic assets using schema-compliant resources and tools. Serves as an MCP adapter that enforces schema compliance and integrates with the Synesthetic asset generation pipeline.-
- FlicenseAqualityNot gradedmaintenanceStatic analysis engine that detects schema mismatches between data producers (like MCP servers) and consumers (like client code), preventing runtime errors by validating contracts at development time.11-
- AlicenseAqualityBmaintenanceProvides safe, deterministic inspection, transformation, validation, and diffing of structured data (JSON, CSV, YAML, Parquet) via schema-aware MCP tools.4Apache 2.0
- AlicenseAqualityDmaintenanceEnables generating JSON Schema from sample data, generating TypeScript types, validating data against schemas, creating mock data from schemas, and comparing schemas for differences.528 npmMIT