{operation.deprecated &&
Deprecated
}
{operation['x-stability'] && (
)}
+ {operation['x-gitbook-mcp'] && (
+
+ )}
)}
{!context.headless && title
diff --git a/packages/react-openapi/src/context.ts b/packages/react-openapi/src/context.ts
index 5933f6b46..cfb07eadc 100644
--- a/packages/react-openapi/src/context.ts
+++ b/packages/react-openapi/src/context.ts
@@ -16,6 +16,7 @@ export interface OpenAPIClientContext {
copy: React.ReactNode;
check: React.ReactNode;
lock: React.ReactNode;
+ mcp: React.ReactNode;
};
/**
diff --git a/packages/react-openapi/src/resolveOpenAPIOperation.ts b/packages/react-openapi/src/resolveOpenAPIOperation.ts
index ebb7ab5f9..5c4ba647b 100644
--- a/packages/react-openapi/src/resolveOpenAPIOperation.ts
+++ b/packages/react-openapi/src/resolveOpenAPIOperation.ts
@@ -6,7 +6,7 @@ import type {
} from '@gitbook/openapi-parser';
import { dereferenceFilesystem } from './dereference';
import type { OpenAPIOperationData, OpenAPISecurityScope } from './types';
-import { checkIsReference } from './utils';
+import { checkIsReference, readMcpUrl } from './utils';
export { fromJSON, toJSON } from 'flatted';
@@ -71,7 +71,11 @@ export async function resolveOpenAPIOperation(
return {
servers,
- operation: { ...operation, security },
+ operation: {
+ ...operation,
+ security,
+ 'x-gitbook-mcp-url': getMcpUrl(schema, path, operation),
+ },
method,
path,
securities: Array.from(securitiesMap.entries()),
@@ -148,6 +152,18 @@ function getServers(
return 'servers' in schema ? (schema.servers ?? []) : [];
}
+/**
+ * Resolve the MCP server URL for an operation, following the same precedence as servers:
+ * operation > path > root.
+ */
+function getMcpUrl(
+ schema: OpenAPIV3.Document | OpenAPIV3_1.Document,
+ path: string,
+ operation: OpenAPIV3.OperationObject
+): string | undefined {
+ return readMcpUrl(operation) ?? readMcpUrl(getPathObject(schema, path)) ?? readMcpUrl(schema);
+}
+
/**
* Get an operation by its path and method.
*/
diff --git a/packages/react-openapi/src/resolveOpenAPIWebhook.ts b/packages/react-openapi/src/resolveOpenAPIWebhook.ts
index ed799ac9a..0825b45a2 100644
--- a/packages/react-openapi/src/resolveOpenAPIWebhook.ts
+++ b/packages/react-openapi/src/resolveOpenAPIWebhook.ts
@@ -6,6 +6,7 @@ import type {
} from '@gitbook/openapi-parser';
import { dereferenceFilesystem } from './dereference';
import type { OpenAPIWebhookData } from './types';
+import { readMcpUrl } from './utils';
export { fromJSON, toJSON } from 'flatted';
@@ -40,7 +41,13 @@ export async function resolveOpenAPIWebhook(
return {
servers,
- operation,
+ operation: {
+ ...operation,
+ 'x-gitbook-mcp-url':
+ readMcpUrl(operation) ??
+ readMcpUrl(getPathObject(schema, name)) ??
+ readMcpUrl(schema),
+ },
method,
name,
'x-expandAllResponses':
diff --git a/packages/react-openapi/src/translations/de.ts b/packages/react-openapi/src/translations/de.ts
index 043d06640..a4238288d 100644
--- a/packages/react-openapi/src/translations/de.ts
+++ b/packages/react-openapi/src/translations/de.ts
@@ -5,6 +5,8 @@ export const de = {
stability_experimental: 'Experimentell',
stability_alpha: 'Alpha',
stability_beta: 'Beta',
+ available_in_mcp: 'Im MCP verfügbar',
+ copy_url: 'URL kopieren',
discriminator: 'Diskriminator',
copy_to_clipboard: 'In die Zwischenablage kopieren',
copied: 'Kopiert',
diff --git a/packages/react-openapi/src/translations/en.ts b/packages/react-openapi/src/translations/en.ts
index c6079979e..e50d7cdaa 100644
--- a/packages/react-openapi/src/translations/en.ts
+++ b/packages/react-openapi/src/translations/en.ts
@@ -5,6 +5,8 @@ export const en = {
stability_experimental: 'Experimental',
stability_alpha: 'Alpha',
stability_beta: 'Beta',
+ available_in_mcp: 'Available in MCP',
+ copy_url: 'Copy URL',
discriminator: 'Discriminator',
copy_to_clipboard: 'Copy to clipboard',
copied: 'Copied',
diff --git a/packages/react-openapi/src/translations/es.ts b/packages/react-openapi/src/translations/es.ts
index 6f572b1f6..21f61d010 100644
--- a/packages/react-openapi/src/translations/es.ts
+++ b/packages/react-openapi/src/translations/es.ts
@@ -5,6 +5,8 @@ export const es = {
stability_experimental: 'Experimental',
stability_alpha: 'Alfa',
stability_beta: 'Beta',
+ available_in_mcp: 'Disponible en el MCP',
+ copy_url: 'Copiar URL',
discriminator: 'Discriminador',
copy_to_clipboard: 'Copiar al portapapeles',
copied: 'Copiado',
diff --git a/packages/react-openapi/src/translations/fr.ts b/packages/react-openapi/src/translations/fr.ts
index f7971d9b0..aa2078905 100644
--- a/packages/react-openapi/src/translations/fr.ts
+++ b/packages/react-openapi/src/translations/fr.ts
@@ -5,6 +5,8 @@ export const fr = {
stability_experimental: 'Expérimental',
stability_alpha: 'Alpha',
stability_beta: 'Bêta',
+ available_in_mcp: 'Disponible dans le MCP',
+ copy_url: "Copier l'URL",
discriminator: 'Discriminateur',
copy_to_clipboard: 'Copier dans le presse-papiers',
copied: 'Copié',
diff --git a/packages/react-openapi/src/translations/ja.ts b/packages/react-openapi/src/translations/ja.ts
index e71b71dac..4806663e6 100644
--- a/packages/react-openapi/src/translations/ja.ts
+++ b/packages/react-openapi/src/translations/ja.ts
@@ -5,6 +5,8 @@ export const ja = {
stability_experimental: '実験的',
stability_alpha: 'アルファ',
stability_beta: 'ベータ',
+ available_in_mcp: 'MCPで利用可能',
+ copy_url: 'URLをコピー',
discriminator: 'ディスクリミネーター',
copy_to_clipboard: 'クリップボードにコピー',
copied: 'コピー済み',
diff --git a/packages/react-openapi/src/translations/nl.ts b/packages/react-openapi/src/translations/nl.ts
index 748be822d..3c58e1313 100644
--- a/packages/react-openapi/src/translations/nl.ts
+++ b/packages/react-openapi/src/translations/nl.ts
@@ -5,6 +5,8 @@ export const nl = {
stability_experimental: 'Experimenteel',
stability_alpha: 'Alfa',
stability_beta: 'Bèta',
+ available_in_mcp: 'Beschikbaar in MCP',
+ copy_url: 'URL kopiëren',
discriminator: 'Discriminator',
copy_to_clipboard: 'Kopiëren naar klembord',
copied: 'Gekopieerd',
diff --git a/packages/react-openapi/src/translations/no.ts b/packages/react-openapi/src/translations/no.ts
index f5b580b1b..ed6c096e2 100644
--- a/packages/react-openapi/src/translations/no.ts
+++ b/packages/react-openapi/src/translations/no.ts
@@ -5,6 +5,8 @@ export const no = {
stability_experimental: 'Eksperimentell',
stability_alpha: 'Alfa',
stability_beta: 'Beta',
+ available_in_mcp: 'Tilgjengelig i MCP',
+ copy_url: 'Kopier URL',
discriminator: 'Diskriminator',
copy_to_clipboard: 'Kopier til utklippstavle',
copied: 'Kopiert',
diff --git a/packages/react-openapi/src/translations/pt-br.ts b/packages/react-openapi/src/translations/pt-br.ts
index a727d9673..58cc8bf37 100644
--- a/packages/react-openapi/src/translations/pt-br.ts
+++ b/packages/react-openapi/src/translations/pt-br.ts
@@ -5,6 +5,8 @@ export const pt_br = {
stability_experimental: 'Experimental',
stability_alpha: 'Alfa',
stability_beta: 'Beta',
+ available_in_mcp: 'Disponível no MCP',
+ copy_url: 'Copiar URL',
discriminator: 'Discriminador',
copy_to_clipboard: 'Copiar para a área de transferência',
copied: 'Copiado',
diff --git a/packages/react-openapi/src/translations/zh.ts b/packages/react-openapi/src/translations/zh.ts
index 9a34ccb55..4fb1bc88b 100644
--- a/packages/react-openapi/src/translations/zh.ts
+++ b/packages/react-openapi/src/translations/zh.ts
@@ -5,6 +5,8 @@ export const zh = {
stability_experimental: '实验性',
stability_alpha: 'Alpha',
stability_beta: 'Beta',
+ available_in_mcp: '可在 MCP 中使用',
+ copy_url: '复制 URL',
discriminator: '判别器',
copy_to_clipboard: '复制到剪贴板',
copied: '已复制',
diff --git a/packages/react-openapi/src/utils.ts b/packages/react-openapi/src/utils.ts
index f0523766b..1c6ef6a88 100644
--- a/packages/react-openapi/src/utils.ts
+++ b/packages/react-openapi/src/utils.ts
@@ -16,6 +16,18 @@ export function createStateKey(key: string, scope?: string) {
return scope ? `${scope}_${key}` : key;
}
+/**
+ * Read the `x-gitbook-mcp-url` extension from any spec object, treating an empty string as unset
+ * so it falls through to the next level when resolving the operation > path > root cascade.
+ */
+export function readMcpUrl(obj: unknown): string | undefined {
+ if (obj && typeof obj === 'object' && 'x-gitbook-mcp-url' in obj) {
+ const value = obj['x-gitbook-mcp-url'];
+ return typeof value === 'string' && value ? value : undefined;
+ }
+ return undefined;
+}
+
/**
* Check if an object has a description. Either at the root level or in items.
*/