MCP servers
Nearly every agent ecosystem stores MCP servers in the same JSON shape, so one normaliser covers all of them.
The shape Gate reads
.mcp.json
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github@2025.4.8"],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "${env:GITHUB_TOKEN}"
}
},
"vendor": {
"type": "http",
"url": "https://mcp.vendor.example/v1",
"headers": { "Authorization": "Bearer ${env:VENDOR_TOKEN}" }
}
}
}
VS Code uses servers instead of mcpServers; Codex uses
[mcp_servers.name] in TOML. Gate reads all three.
Transports
- Name
stdio- Type
- local process
- Description
A
commandandargs. The agent starts the server as a child process. Gate reads the command line but never runs it. See deep inspection.
- Name
sse- Type
- remote, legacy
- Description
Server-sent events. Treated the same as
httpfor analysis.
What Gate extracts
From each server definition:
- Credentials: in
env, inargs, inheaders, and in the URL itself. Detected, classified by type, and redacted at the boundary. A value like${env:TOKEN}is recorded as a credential the agent holds, but not as a leak: referencing a secret is the fix, not the problem. - Filesystem grants: any argument or environment value that looks like a path, classified by scope and checked against known credential directories.
- Production indicators:
prod,production,prd,live, or a live-mode payment key, matched on word boundaries soproduct_catalogdoes not trip it. - Tools: for recognised packages, the real tool list.
Known servers
Gate recognises 52 server classes, covering 194 individually mapped tools. The table is split into two kinds of match:
Exact match: a specific package whose tool list Gate knows. Tools are enumerated as fact:
2 MCP servers
14 exposed tools
Category match: Gate recognises the kind of server but not the exact package. It records a capability posture instead of inventing tools:
GATE005 db
db: PostgreSQL server; tool set not enumerated, capabilities
inferred from the server type
This distinction is why Gate's counts can be trusted. Enumerating tools a server might not have would inflate every headline number, and a security tool with inflated numbers is a security tool nobody believes.
Contributing a mapping
The known-server table is Gate's accumulating asset: every entry turns a guess into a fact, for everyone. Adding one is the highest-value contribution to Gate.
Several of the original @modelcontextprotocol/server-* packages were archived
in 2025, with vendors taking over the important ones. GitHub now maintains
github/github-mcp-server. Gate still matches the archived names: they are
still pinned in configuration files, and a scanner has to find what is running.
packages/core/src/capabilities.ts
{
id: 'linear',
label: 'Linear',
match: ['mcp.linear.app'],
fuzzyMatch: ['linear-mcp'],
tools: {
create_issue: ['write', 'communicate'],
update_issue: ['write'],
search_issues: ['search', 'read'],
delete_issue: ['delete'],
},
defaultCapabilities: ['read', 'search', 'write'],
}
Only put a package in match if you have read that server and the tool list is
right. Everything else goes in fuzzyMatch.