Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions fern/apis/mcp-tools/generators.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
api:
specs:
- openapi: openapi.json
209 changes: 209 additions & 0 deletions fern/apis/mcp-tools/openapi.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
{
"openapi": "3.1.0",
"info": {
"title": "Fern Docs MCP API",
"version": "1.0.0",
"description": "API endpoints for MCP agents to authenticate and search Fern documentation sites."
},
"servers": [
{
"url": "https://docs.example.com",
"description": "Your documentation domain"
}
],
"components": {
"securitySchemes": {
"FernApiKey": {
"type": "apiKey",
"in": "header",
"name": "FERN_API_KEY",
"description": "Fern API key, from `fern generate token`."
},
"FernToken": {
"type": "apiKey",
"in": "header",
"name": "FERN_TOKEN",
"description": "JWT token for this user."
}
}
},
"paths": {
"/api/fern-docs/get-jwt": {
"get": {
"summary": "JWT from Fern API key",
"description": "Get a JWT to access protected documentation endpoints, optionally scoped to specific roles.",
"operationId": "getJwt",
"security": [
{
"FernApiKey": []
}
],
"parameters": [
{
"name": "ROLES",
"in": "header",
"required": false,
"schema": {
"type": "string"
},
"description": "Comma-separated list of roles (e.g., \"botanist,seedling\"). Sets roles for returned JWT if provided, otherwise, roles are empty."
},
{
"name": "x-fern-host",
"in": "header",
"required": false,
"schema": {
"type": "string"
},
"description": "Domain (required on preview URLs)"
}
],
"responses": {
"200": {
"description": "Successfully generated JWT",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"fern_token": {
"type": "string",
"description": "JWT token for authenticating subsequent requests"
},
"roles": {
"type": "array",
"items": {
"type": "string"
},
"description": "Roles included in the JWT"
}
},
"required": ["fern_token", "roles"]
}
}
}
},
"400": {
"description": "Bad request (local preview, self-hosted, or SSO environment)",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {
"type": "string"
}
}
}
}
}
},
"401": {
"description": "Unauthorized (missing or invalid API key)",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {
"type": "string"
}
}
}
}
}
},
"403": {
"description": "Forbidden (API key does not belong to this domain's Fern organization)",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {
"type": "string"
}
}
}
}
}
}
}
}
},
"/api/fern-docs/search/v2/key": {
"get": {
"summary": "Algolia search credentials",
"description": "Get Algolia search credentials for querying documentation.",
"operationId": "getSearchKey",
"security": [
{
"FernApiKey": []
},
{
"FernToken": []
}
],
"parameters": [
{
"name": "ROLES",
"in": "header",
"required": false,
"schema": {
"type": "string"
},
"description": "Comma-separated list of roles (only with FERN_API_KEY). Sets roles for returned search key if provided, otherwise, roles are empty."
},
{
"name": "x-fern-host",
"in": "header",
"required": false,
"schema": {
"type": "string"
},
"description": "Documentation domain (required on preview URLs)"
}
],
"responses": {
"200": {
"description": "Successfully retrieved search credentials",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"appId": {
"type": "string",
"description": "Algolia application ID"
},
"apiKey": {
"type": "string",
"description": "Short-lived Algolia search API key"
},
"roles": {
"type": "array",
"items": {
"type": "string"
},
"description": "Roles included in the search key (only with FERN_API_KEY auth)"
}
},
"required": ["appId", "apiKey"]
}
}
}
},
"400": {
"description": "Bad request (local preview or unsupported preview URL)"
},
"401": {
"description": "Unauthorized (invalid Fern API key)"
},
"403": {
"description": "Forbidden (API key does not belong to this domain's Fern organization)"
}
}
}
}
}
}
9 changes: 7 additions & 2 deletions fern/products/docs/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,13 @@ navigation:
contents:
- link: Ask Fern
href: /learn/ask-fern/getting-started/what-is-ask-fern
- page: MCP server for your site
path: ./pages/ai/mcp-server.mdx
- section: MCP server for your site
contents:
- page: Overview
path: ./pages/ai/mcp-server.mdx
- api: API Reference
paginated: false
api-name: mcp-tools
slug: mcp-server
- page: Fern Scribe (coming soon)
path: ./pages/ai/scribe.mdx
Expand Down
15 changes: 14 additions & 1 deletion fern/products/docs/pages/ai/mcp-server.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,17 @@ Developers can access your MCP server by visiting `your-documentation-site.com/m

<Tip>
**Looking for Fern's own MCP server?** If you want to connect your AI client to Fern's MCP server for help with Ask Fern, Docs, and SDKs, see the [fern-mcp-server repository](https://github.com/fern-api/fern-mcp-server).
</Tip>
</Tip>

## Additional AI Tooling
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [vale] reported by reviewdog 🐶
[FernStyles.Headings] 'Additional AI Tooling' should use sentence-style capitalization.


LLMs can access your documentation programmatically, even for authenticated sites. When content is fetched this way, it's served as clean markdown without HTML markup, making it token efficient for LLMs to process.

```bash
curl -X GET https://docs.example.com/platform/overview \
-H 'Accept: text/plain' \
-H 'x-fern-host: docs.example.com' \
-H "FERN_TOKEN:${JWT}"
```

For sites with authentication, LLMs can obtain a JWT by calling the [`/api/fern-docs/get-jwt`](/learn/docs/ai-features/mcp-server/api-reference/get-jwt) endpoint with a Fern API key. This JWT can then be used to access protected documentation content and search functionality.