Skip to main content
mcp-watchtower exports six TypeScript interfaces and type shapes. You can import them alongside StaticAnalyzer and SemanticAnalyzer. This page documents every field, its type, and its meaning.

ToolSchema

ToolSchema represents a single tool as declared in an MCP server manifest. You construct an array of these and pass it to analyzer.analyze().
name
string
required
The tool’s unique identifier within the server. This is the value the LLM uses when selecting a tool to invoke.
description
string
required
A human- and model-readable description of what the tool does. The static analyzer scans this field for shadow patterns.
inputSchema
object
JSON Schema–style definition of the tool’s accepted parameters. Optional — tools with no parameters may omit this field.
Example:

Finding

Finding represents a single issue produced by the analyzer. The findings array on StaticReport is a list of these.
severity
'critical' | 'warning' | 'info'
required
How serious the issue is. critical findings cause the CLI to exit with code 1. Use this field to gate CI pipelines programmatically.
code
string
required
Machine-readable identifier for the type of issue. See the finding codes section below for all possible values.
message
string
required
Human-readable explanation of the finding, including the tool name and relevant context.
tool
string
Name of the tool that triggered the finding. Present for all findings except TOOL_COUNT_WARNING, which is not scoped to a single tool.
Name of the second tool involved in a conflict finding. Only present on PARAMETER_CONFLICT findings.

Finding codes

Default severity: criticalTwo or more tools in the same server share the same name. LLMs treat tool names as unique identifiers — duplicate names produce unpredictable routing behavior.The tool field is set to the duplicated name. The relatedTool field is not set.
Default severity: warningA tool’s name uses a different naming convention (snake_case, camelCase, or kebab-case) from the majority of other tools in the server. Inconsistent conventions make the tool manifest harder for models to reason about.The tool field is set to the outlier tool name.
Default severity: warningTwo tools use different parameter names for the same semantic concept — for example, ticker in one tool and symbol in another. The analyzer uses deterministic normalization plus a built-in synonym seed set covering common patterns like identifiers, pagination, and date fields.Both the tool and relatedTool fields are set.
Default severity: warning or critical (depends on the matched pattern)A tool’s description contains language that can hijack LLM tool routing — for example, phrases that instruct the model to always prefer this tool or to ignore other tools. Severity is set by the matched pattern definition.The tool field is set to the affected tool name.
Default severity: warningThe server exposes more tools than the configured maxTools threshold (default: 20). Research shows LLM routing accuracy degrades above roughly 20 tools per server. Consider splitting a large server into smaller, focused sub-servers.Neither tool nor relatedTool is set — this finding applies to the server as a whole.

StaticReport

StaticReport is the object returned by analyzer.analyze(). It contains the full results of the analysis run.
server
string
required
The serverName argument you passed to analyze().
toolCount
number
required
The number of tools that were analyzed.
findings
Finding[]
required
All findings produced across the five checks. An empty array means the server passed cleanly.
passedAt
string
required
ISO 8601 timestamp of when the analysis completed, e.g. "2024-11-15T09:32:00.123Z".

StaticAnalyzerConfig

StaticAnalyzerConfig is the optional configuration object accepted by the StaticAnalyzer constructor.
platform
boolean
default:"false"
When true, elevates DUPLICATE_TOOL_NAME severity to critical. Use this when loading multiple MCP servers simultaneously into a shared context, where name collisions are dangerous rather than just inconvenient.
maxTools
number
default:"20"
Tool count threshold for TOOL_COUNT_WARNING. A finding is emitted when tools.length exceeds this value.

SemanticFinding

SemanticFinding represents a single result produced by SemanticAnalyzer. Semantic findings are separate from static Finding objects because they carry corpus match metadata.
severity
'warning' | 'info'
required
Semantic findings are never critical. SEMANTIC_OVERLAP and SEMANTIC_PARAMETER_CONFLICT are warning findings, while ALREADY_IN_CORPUS is typically info.
code
'SEMANTIC_OVERLAP' | 'ALREADY_IN_CORPUS' | 'SEMANTIC_PARAMETER_CONFLICT'
required
Machine-readable identifier for the semantic match type.
tool
string
required
Name of the tool in the server you analyzed.
matchedTool
string
required
Name of the matching tool in the semantic corpus.
matchedServer
string
required
Qualified server identifier from the corpus, such as owner/server-name.
matchedDisplayName
string
required
Human-readable display name for the matched corpus server.
matchedParameter
string
Parameter name involved in a SEMANTIC_PARAMETER_CONFLICT finding. Omitted for corpus-overlap findings.
similarity
number
required
Cosine similarity score rounded to two decimals. Higher values indicate a closer semantic match.
message
string
required
Human-readable explanation of the overlap and suggested action.

Semantic finding codes

Default severity: infoThe analyzed tool has the same name as a corpus tool and a very high description similarity (>= 0.95). This usually means the tool already exists in the corpus. If the corpus entry is your own server, no action is needed.
Default severity: warningThe analyzed tool is semantically similar to a tool in the corpus from another server. This is a signal to make your description more specific so LLMs can distinguish the tools more reliably.
Default severity: warningTwo parameters in the same scanned server look semantically equivalent even though they use different names. This finding comes from the deeper semantic parameter pass, which compares parameter names and descriptions in the context of their surrounding tools.The tool, matchedTool, and matchedParameter fields are set. matchedServer and matchedDisplayName are set to the scanned server name because the comparison is within one server, not against the external corpus.

SemanticReport

SemanticReport is the object returned by await new SemanticAnalyzer().analyze(...).
server
string
required
The serverName argument you passed to analyze().
toolCount
number
required
The number of tools that were analyzed.
findings
SemanticFinding[]
required
All semantic findings that met the configured similarity threshold. An empty array means no strong overlaps were detected.
scannedAt
string
required
ISO 8601 timestamp of when the semantic analysis completed.