Skip to main content
Glama

MCP-Server-Reference

未受治理的MCP是一种未登记入目的API,位于高一层。

一个小型 Model Context Protocol 服务器,它发布一份静态的 OpenAPI 目录、一份书面契约和一份明确的拒绝清单。它是一个参照接口暴露面——不是平台,也不是 SaaS。

Bruno Carvalho de Aquino,解决方案架构师。

MCP host (Cursor, Claude, …)
        |
        | stdio
        v
+---------------------------+
|  mcp-server-reference     |
|                           |
|  tools  = catalog lookup  |
|  resources = contract     |
|  deny-list = interface    |
+---------------------------+
        |
        | imported modules only
        v
   orders | identity | billing
   (OpenAPI snippets, no fetch)

问题

团队正在以当年接入影子 API 的方式接入 MCP 服务器:一个进程、几个功能强大的工具、没有清单、没有负责人、也没有关于该进程不应做什么的任何书面说明。

一个接受 URL 的工具就是 HTTP 代理。一个接受 shell 字符串的工具就是远程代码执行。一个转储 process.env 的工具就是凭据外泄。协议本身并不会让这些形态变得安全。把它们称为“工具”,只会让它们掩在 API 评审者的视线之外。

Related MCP server: enterprise-mcp

这个仓库是什么

组成

作用

TypeScript MCP 服务器(@modelcontextprotocol/server v2)

宿主可生成的 stdio 进程

五个工具

list / lookup / describe。不做执行。

四个资源

契约、拒绝清单、目录索引、各API 规范

CONTRACT.md

接口的人工清单

DENY.md

明确不会加入的能力封闭清单

ADR-0006

拒绝清单为什么是接口的一部分

目录是编译进进程的三个实验室 OpenAPI 文档(orders、identity、billing)。规范的 servers[] 使用 .invalid 顶级域。进程从不去获取它们。

这个仓库不是什么

  • 不是。Apidex 是产品形态的答案(清单、生命周期、MCP 治理)。本仓库是公开的楔子:一台诚实的服务器,以及一个书面的“不”。

  • 不是 MCP 安全网关。 没有 OAuth、没有按主体区分的允许名单、不推发审计日志。那是后续的另一个盒子。

  • 不是客户成功案例。 没有编造的服务器数量、令牌数,以及所谓“影子 MCP 降低 N%”。

约束

  • Node 20+。 TypeScript 严格模式。没有运行时文件系统遍历。没有 fetch。没有 child_process。

  • 工具的输入是封闭的:slugs、HTC 方法、路径模板、拒绝清单枚举。

  • billing 是有意弃用的。目录若隐藏离场 API,集成就会随之腐烂。

  • Identity 发布的部分不包含密码或令牌端点。受限状态是元数据,不是做样子。

风险说明

风险

Irruption in any MCP,如何manifest

这里的应对

SSRF

若 fetch(userUrl),`swagger BSL,“就现在"

无 URL 参数。规范是导入的。

RCE

run_command,shell -c

未实现。explain_deny("raw_hell")。

机密外泄

debug_env,“home-directory read_file"

没有环境或路径工具。仓库中无机密。

通过 specs 进行提示内嵌

载有指令的远程 OpenAPI

目录是评审过的 git 内容。

混淆的 deputy

宿主把权限授给服务器;模型选工具

一小组暴露面。contract 可列出。

影子执行

查找工具偷偷调用真实 API

get_operation 返回 invoked: false。

这是一张威胁便签,并不是生产环境知产的完整 STRIDE 模型。若把本服务器挂到宿主上,你仍然要信任宿主进程和模型。淡薄化这种信任是网关的活。

本地运行方式

npm install
npm test
npm run typecheck
npm run inspect    # prints the contract JSON
npm run build

stdiio 服务器(宿主拉起的那个):

npm start
# or, without a prior build:
npm run dev

不要往那个进程里输入内容。MCP 使用 JSON-RPC 在 stdin/stdout 上传。在不同的地方,和宿主聊天。

Cursor / Claude Desktop

{
  "mcpServers": {
    "catalog": {
      "command": "node",
      "args": ["/absolute/path/to/mcp-server-reference/dist/index.js"]
    }
  }
}

先 build。宿主必须能启动 Node。连接后调用 inspect_contract 或读取 mcp://contract。

冒烟测试,无宿主

npm run inspect

你应当能看到五个工具、四个资源和七条拒绝清单 id。

与 API 治理的关系

OpenAPI 治理早已有词汇表:owner 所有权、生命周期、破坏性变更、deprecation 弃用、“这个操作不公开”。MCP 来了,却把这套词汇忘了。

API 实践

本仓库的作风对应

实际上发布的 OpenAPI

CONTRACT.md + inspect_contract

路径白名单

画像 ①② 精确操作匹配

“不要暴露 /admin”

DENY.md

已弃用 API 仍列在这里

billing 生活周期 = 已弃用

CI 里的契约测试

npm test + npm run typecheck

如果你看到“加不明 CI 的 REST 端点”的 PR 会被拒,那么它也不该让“不加文档 API 的 MCP 工具”的 PR 通过。

这个问题的产品形态——API 和 MCP 服务器的清单、生命周期、审查——is Apidex。本仓库并不实现这些。它演示的是一个目录可以摄取的 factor:一个能描述自己,并解自己拒绝什么的服务器。

我接受的选择

一堆厨房齐全的 demo 只要写入截屏很好看,它也可能教出下一位工程师“就这一次”地加 fetch。我选了一副普通目录,让拒绝清单自己成为焦点。

代价是:你不能用这个服务器去“做X”。这是故意的。执行是另一张契约,与身份有关。

写道

MIT。Copyright (c) 2026 Bruno Carvalho de Aquino。

Available Tools

5 tools
explain_denyExplain a denied capabilityA

Explain why a named capability is refused. Use this instead of asking the server to grow a shell, HTTP client, or secret reader.

NameRequiredDescriptionDefault
capabilityYesA capability from the published deny-list

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations present, the description carries the full burden of behavioral disclosure. It clearly states the tool's purpose but does not mention side effects, permissions, or that it is a read-only operation. The phrase 'refused' implies it is explanatory, but the description does not explicitly say whether it executes anything or how it behaves beyond returning an explanation. This is adequate but not rich; a 3 reflects the absence of contradictions balanced against incomplete behavioral detail.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with zero redundancy. The primary purpose is front-loaded, and the usage guidance follows immediately. Every word earns its place without padding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple tool with one enum-constrained parameter and no output schema, the description provides sufficient context: it explains what it does and when to prefer it over requesting capabilities. It does not describe the return format or potential errors, but given the simplicity and the absence of an output schema, this is a minor gap. Completeness is high for the tool's complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema provides 100% coverage: the single parameter 'capability' has an enum list and a description that fully defines it as 'A capability from the published deny-list.' The description adds no extra semantics beyond referring to a 'named capability,' which is already covered by the schema. Given high schema coverage, the baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a clear verb-resource purpose: 'Explain why a named capability is refused.' It also distinguishes itself from asking the server to grow a shell, HTTP client, or secret reader, which positions it as a diagnostic tool rather than a capability-granting one. However, it does not explicitly name the sibling tools (list_catalog, lookup_api, etc.) or contrast with them, so some differentiation is left implicit.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It provides explicit guidance on when to use this tool: 'Use this instead of asking the server to grow a shell, HTTP client, or secret reader.' This tells the agent that whenever it would consider requesting such capabilities, it should instead call explain_deny. It does not mention the sibling tools or give extensive exclusion criteria, but the core use case is clearly stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_operationGet cataloged operationA

Return one operation from a cataloged API. Method and path must match the published spec exactly. This describes the operation; it does not invoke it.

NameRequiredDescriptionDefault
pathYesExact OpenAPI path template, for example /orders/{orderId}
apiIdYes
methodYes

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden. It discloses an important trait: the operation is not invoked, indicating a read-only, side-effect-free behavior. However, it does not mention error behavior (e.g., what happens on no match) or return format details, so transparency is partial. The explicit 'does not invoke' is valuable 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.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences deliver the core purpose, a constraint, and a crucial non-invocation note — no filler. The main action is front-loaded, and every clause earns its place. It is efficiently structured for quick comprehension.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

As a retrieval tool with no output schema, the description should at least indicate what structure the 'operation' takes or what happens when no match is found. It says it 'returns one operation' but does not describe the return object or error cases. Given the sibling tools and the absence of an output schema, the description is under-specified for an agent to know exactly what to expect or how to handle failures.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is only 33% (only 'path' has a description). The description adds meaning for 'method' and 'path' by stating they must match the published spec exactly, but it never explains 'apiId' — what it represents or how to obtain it. Thus, two of three parameters get some semantics, but the most opaque one remains undocumented, and the tool text does not fully compensate for the low schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a clear action ('Return one operation') and resource ('from a cataloged API'), and distinguishes itself by explicitly noting it 'describes the operation; it does not invoke it.' This sets it apart from tools that might execute API calls and makes its purpose unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It conveys a prerequisite ('Method and path must match the published spec exactly') and a key differentiator ('does not invoke it'), but it does not explicitly compare with sibling tools like list_catalog or inspect_contract. The context of when to choose this over alternatives is implied rather than stated, so some guidance exists but lacks explicit routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

inspect_contractInspect published contractA

Return the tool manifest, resource manifest, deny-list ids, and a statement of what this server is not.

NameRequiredDescriptionDefault

No parameters

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description must carry the full behavioral burden. It discloses that the tool returns manifests, deny-list ids, and a statement of what the server is not, indicating a read-only inspection. However, it doesn't mention any potential side effects, resource costs, or error behavior. For a simple read-only tool this is adequate but not rich.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence that directly states what is returned. No filler, every word earns its place, and the key outputs are front-loaded. This is appropriately concise for the tool's simplicity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a parameterless inspection tool with no output schema, the description covers the essential return values. It doesn't explain what 'tool manifest' or 'resource manifest' mean, but that may be domain-specific. It also doesn't clarify when to choose this over siblings, but given the tool's narrow scope, it's relatively complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so there is nothing for the description to explain. The baseline for 0 parameters is 4, and the description doesn't need to compensate for any schema gaps. The tool is straightforward in that regard.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a clear verb ('Return') and specifies the resource (contract information: tool manifest, resource manifest, deny-list ids). It is specific about what is returned, but it doesn't explicitly contrast with sibling tools like list_catalog or explain_deny, leaving some ambiguity about what makes this unique.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies when to use it (for inspecting the server's contract) but doesn't state explicit conditions or exclusions relative to the siblings. It doesn't say 'use this when you need an overview' or 'don't use this for looking up specific operations'. Context is somewhat clear but not fully articulated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_catalogList API catalogA

List the static OpenAPI catalog entries published with this server. Returns id, owner, lifecycle, classification, and operation count. No network.

NameRequiredDescriptionDefault

No parameters

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It discloses the return fields (id, owner, lifecycle, classification, operation count) and the 'No network' behavior, which is valuable context. It does not mention potential staleness or failure modes, but for a simple list these are minor omissions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with zero waste. The verb and resource are front-loaded, followed by return fields and a key behavioral note. Every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is simple (no params, no output schema), and the description fully explains what it does and what it returns. Sibling tools exist but differentiation is handled by purpose clarity. Nothing essential is missing for an agent to invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so schema coverage is trivially 100%. Per calibration, a baseline of 4 applies. The description adds nothing parameter-related because none exist, which is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'List' and the resource 'static OpenAPI catalog entries published with this server', distinguishing it from siblings like lookup_api (single lookup) and get_operation (specific operation). The scope is explicit and unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description notes 'No network' implying a fast, static listing, but does not explicitly say when to use this vs alternatives such as lookup_api. It offers no explicit exclusions or conditions, but the purpose is self-evident enough that an agent can infer suitability for overview retrieval.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

lookup_apiLookup cataloged APIA

Return one imported OpenAPI document by catalog id (orders, identity, billing). Rejects unknown ids. Does not fetch URLs from the spec.

NameRequiredDescriptionDefault
apiIdYesCatalog id, for example orders

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It reveals two important traits: it rejects unknown ids (error behavior) and does not fetch URLs from the spec (avoiding network side-effects). Even without a return format specification, these disclosures cover the key operational concerns an agent would have.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two short sentences, front-loaded with the core action and resource. The second sentence delivers two high-value constraints efficiently. There is zero filler; every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple single-parameter lookup with no output schema and no annotations, the description covers the essential purpose, error handling, and a limitation. It does not describe the return structure (e.g., raw JSON vs. parsed object), but that is a minor gap given the simplicity and the explicit scope of the tool. Overall, an agent can confidently invoke it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already documents apiId with a pattern and example, achieving 100% coverage. The description adds concrete catalog id examples (orders, identity, billing) that go beyond the schema's single example, enriching the parameter's semantic meaning and helping the agent select valid values. This justifies a score above the baseline 3.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'Return' and the resource 'imported OpenAPI document' with a specific identifier (catalog id). It also gives concrete examples (orders, identity, billing) and implicitly differentiates from siblings like list_catalog (which lists) and get_operation (which fetches a specific operation). The purpose is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It provides practical usage guidance by stating that unknown ids are rejected (so the agent knows to validate against the catalog) and that it does not fetch URLs from the spec (clarifying a limitation). It does not explicitly name alternatives, but the examples and behavior imply it is for looking up a single document by id, which is sufficient for most agents to route correctly.

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.

  1. 5 tool updatesv1.0.0
    • First observedexplain_deny
    • First observedget_operation
    • First observedinspect_contract
    • First observedlist_catalog
    • First observedlookup_api

TDQS

A4.1/5.0

Scored across 5 tools

Disambiguation5/5

Each tool has a completely distinct purpose: listing catalogs, fetching a specific API document, retrieving a single operation, inspecting the server contract, and explaining deny behavior. No overlap or ambiguity exists.

Naming Consistency5/5

All tool names follow a consistent lowercase verb_noun pattern (list_catalog, lookup_api, get_operation, inspect_contract, explain_deny), making the surface predictable and easy to navigate.

Tool Count5/5

Five tools is precisely scoped for a read-only reference server. Each tool fills a necessary role without redundancy, and the count is neither too sparse nor overloaded for the stated purpose.

Completeness5/5

The tool set covers the full lifecycle for exploring static OpenAPI catalogs: listing, retrieving documents, drilling into operations, inspecting the server contract, and understanding denied capabilities. No apparent dead ends or missing operations for its domain.

Maintenance

ActivityStale
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    A read-only MCP server for navigating OpenAPI / Swagger specifications, enabling agents to search endpoints, retrieve parameters and schemas, and inspect authentication without loading the full spec into context.
    9
    15 npm
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    An MCP server exposing scoped, read-only enterprise operations tools with fail-closed credential handling. It returns opaque approval IDs for mutations and requires a separate operator approval command to release one-time capabilities.
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables MCP clients to resolve, inspect, acquire, verify, and query routes, capabilities, schema, and health for public and authorized web resources, with fail-closed statuses and artifact production.
    MIT