Document MCP server generator - #6778
Conversation
| </Indent> | ||
|
|
||
| <ParamField path="include" type="array of objects" required={false} toc={true}> | ||
| Endpoints to expose as tools. Entries are OR'd together; fields within a single entry are AND'd. Omit `include` to start from every endpoint the spec exposes. |
There was a problem hiding this comment.
📝 [vale] <FernStyles.Acronyms> reported by reviewdog 🐶
'AND' has no definition.
| - An `include`/`exclude` selector that matches nothing. | ||
| - A destructive endpoint with no `destructive` annotation override. | ||
| - A new spec endpoint matching no configured group. | ||
| - An **orphaned override** — an `overrides` entry keyed to an endpoint no longer in the spec, so a hand-written description doesn't just silently stop applying. |
There was a problem hiding this comment.
📝 [vale] <FernStyles.Hedges> reported by reviewdog 🐶
Avoid hedge words and filler like 'just'. Prefer direct statements.
| - An `include`/`exclude` selector that matches nothing. | ||
| - A destructive endpoint with no `destructive` annotation override. | ||
| - A new spec endpoint matching no configured group. | ||
| - An **orphaned override** — an `overrides` entry keyed to an endpoint no longer in the spec, so a hand-written description doesn't just silently stop applying. |
There was a problem hiding this comment.
📝 [vale] <FernStyles.Adverbs> reported by reviewdog 🐶
Remove 'silently' if it's not important to the meaning of the statement.
| - An **orphaned override** — an `overrides` entry keyed to an endpoint no longer in the spec, so a hand-written description doesn't just silently stop applying. | |
| - An **orphaned override** — an `overrides` entry keyed to an endpoint no longer in the spec, so a hand-written description doesn't just stop applying. |
| - A `server-name` or package rename on an already-published group, which `tools --diff` can't see on its own since it compares tools, not identity. | ||
| - A `response-fields` projection set under a generator version that doesn't support it. | ||
|
|
||
| All of these print as warnings, not blockers, in CI and `--json` output. |
There was a problem hiding this comment.
📝 [vale] <Microsoft.Wordiness> reported by reviewdog 🐶
Consider using 'these' instead of 'All of these'.
| All of these print as warnings, not blockers, in CI and `--json` output. | |
| these print as warnings, not blockers, in CI and `--json` output. |
|
|
||
| `fern mcp init` always adds a new group; it never mutates an existing one. `fern mcp tools --refine --group <name>` is the mutation path for a group already written. | ||
|
|
||
| Two endpoints can appear in more than one group's toolset — `fern mcp list` reports the overlap as information, not a warning. When a spec grows a new endpoint, it lands in whichever group's rules match; `fern check` warns if a new endpoint matches none of them, so nothing silently falls through the cracks. |
There was a problem hiding this comment.
📝 [vale] <FernStyles.Adverbs> reported by reviewdog 🐶
Remove 'silently' if it's not important to the meaning of the statement.
| Two endpoints can appear in more than one group's toolset — `fern mcp list` reports the overlap as information, not a warning. When a spec grows a new endpoint, it lands in whichever group's rules match; `fern check` warns if a new endpoint matches none of them, so nothing silently falls through the cracks. | |
| Two endpoints can appear in more than one group's toolset — `fern mcp list` reports the overlap as information, not a warning. When a spec grows a new endpoint, it lands in whichever group's rules match; `fern check` warns if a new endpoint matches none of them, so nothing falls through the cracks. |
| - A **group** is a separately generated and published server — its own npm package, its own GitHub repo, its own version. | ||
| - A **preset** is a named subset of one group's toolset that a client can connect to directly — one deploy, several audiences. | ||
|
|
||
| Reach for multiple groups when the audiences need different deployments (an internal admin server your public one shouldn't ship). Reach for presets when one deployment is enough and you just want to hand different clients a narrower slice of it. Small APIs typically need neither; large ones mostly need presets before they need multiple groups. |
There was a problem hiding this comment.
📝 [vale] <FernStyles.Hedges> reported by reviewdog 🐶
Avoid hedge words and filler like 'just'. Prefer direct statements.
| The MCP generator is in early access. [Reach out](https://buildwithfern.com/book-demo?type=mcp) to get started. | ||
| </Note> | ||
|
|
||
| Fern's MCP generator turns your API definition into a [Model Context Protocol](https://modelcontextprotocol.io) server: a project where every endpoint becomes a typed tool that Claude, Cursor, and other MCP clients can call directly. It shares the same spec, `generators.yml`, and generation pipeline as your SDKs and CLI — an MCP server is just another generator output, configured as a [group](/learn/mcp-generator/get-started/quickstart) like any other. |
There was a problem hiding this comment.
📝 [vale] <FernStyles.Hedges> reported by reviewdog 🐶
Avoid hedge words and filler like 'just'. Prefer direct statements.
| availability: beta | ||
| --- | ||
|
|
||
| An MCP server that exposes 300 tools is worse than one that exposes 30: agents spend context distinguishing similar-sounding tools, take more turns to find the right one, and are more likely to call something destructive by accident. Curating the toolset — not just generating one — is the part of setting up an MCP server that an SDK never needed. |
There was a problem hiding this comment.
📝 [vale] <FernStyles.Hedges> reported by reviewdog 🐶
Avoid hedge words and filler like 'just'. Prefer direct statements.
|
|
||
| Narrowing writes compound selectors where they express the intent — `{ tag: reports, method: GET }` for "read-only reports" — rather than an enumerated endpoint list. Response-field projection keeps a tool but restricts its response to the fields you name, via `overrides.<endpoint>.response-fields` in the [configuration reference](/learn/mcp-generator/get-started/configuration#overrides). "Switch to dynamic mode" writes `tools.mode: dynamic` as a stated trade-off, not a silent one. | ||
|
|
||
| `--refine` mutates an existing group's config in place. `fern mcp init` always adds a new group and never mutates one — the two commands are deliberately disjoint. |
There was a problem hiding this comment.
📝 [vale] <FernStyles.Adverbs> reported by reviewdog 🐶
Remove 'deliberately' if it's not important to the meaning of the statement.
| `--refine` mutates an existing group's config in place. `fern mcp init` always adds a new group and never mutates one — the two commands are deliberately disjoint. | |
| `--refine` mutates an existing group's config in place. `fern mcp init` always adds a new group and never mutates one — the two commands are disjoint. |
| ◆ Accept / Adjust (describe the change) / Start over / Switch to manual | ||
| ``` | ||
|
|
||
| The proposal leads with what it excluded, since a 20-tool include list is hard to eyeball but an exclusion list is easy to verify against what you asked for. Anything the model can't express as a selector — a spending limit, an escalation rule — is written into the server's `instructions` field or a per-tool `overrides` description instead of silently dropped. The output is always the same declarative rules any other preset writes: reviewable, diffable, and safe to hand-edit afterward. Run it non-interactively with `fern mcp init --preset ai --intent "support agents, refunds under $100, no admin"`. |
There was a problem hiding this comment.
📝 [vale] <FernStyles.Adverbs> reported by reviewdog 🐶
Remove 'silently' if it's not important to the meaning of the statement.
| The proposal leads with what it excluded, since a 20-tool include list is hard to eyeball but an exclusion list is easy to verify against what you asked for. Anything the model can't express as a selector — a spending limit, an escalation rule — is written into the server's `instructions` field or a per-tool `overrides` description instead of silently dropped. The output is always the same declarative rules any other preset writes: reviewable, diffable, and safe to hand-edit afterward. Run it non-interactively with `fern mcp init --preset ai --intent "support agents, refunds under $100, no admin"`. | |
| The proposal leads with what it excluded, since a 20-tool include list is hard to eyeball but an exclusion list is easy to verify against what you asked for. Anything the model can't express as a selector — a spending limit, an escalation rule — is written into the server's `instructions` field or a per-tool `overrides` description instead of dropped. The output is always the same declarative rules any other preset writes: reviewable, diffable, and safe to hand-edit afterward. Run it non-interactively with `fern mcp init --preset ai --intent "support agents, refunds under $100, no admin"`. |
No description provided.