sourcey 3.3.10 → 3.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/README.md +19 -3
  2. package/dist/client/scroll-tracker.js +8 -1
  3. package/dist/components/layout/Head.d.ts.map +1 -1
  4. package/dist/components/layout/Head.js +1 -1
  5. package/dist/components/layout/Page.d.ts.map +1 -1
  6. package/dist/components/layout/Page.js +2 -1
  7. package/dist/components/layout/Sidebar.d.ts.map +1 -1
  8. package/dist/components/layout/Sidebar.js +6 -1
  9. package/dist/components/layout/TableOfContents.js +1 -1
  10. package/dist/components/mcp/AnnotationBadges.d.ts +15 -0
  11. package/dist/components/mcp/AnnotationBadges.d.ts.map +1 -0
  12. package/dist/components/mcp/AnnotationBadges.js +10 -0
  13. package/dist/components/mcp/McpConnection.d.ts +10 -0
  14. package/dist/components/mcp/McpConnection.d.ts.map +1 -0
  15. package/dist/components/mcp/McpConnection.js +32 -0
  16. package/dist/components/mcp/McpEndpointBar.d.ts +8 -0
  17. package/dist/components/mcp/McpEndpointBar.d.ts.map +1 -0
  18. package/dist/components/mcp/McpEndpointBar.js +16 -0
  19. package/dist/components/mcp/McpReturns.d.ts +18 -0
  20. package/dist/components/mcp/McpReturns.d.ts.map +1 -0
  21. package/dist/components/mcp/McpReturns.js +33 -0
  22. package/dist/components/openapi/Operation.d.ts.map +1 -1
  23. package/dist/components/openapi/Operation.js +5 -1
  24. package/dist/config.d.ts +3 -0
  25. package/dist/config.d.ts.map +1 -1
  26. package/dist/config.js +8 -3
  27. package/dist/core/mcp-normalizer.d.ts +11 -0
  28. package/dist/core/mcp-normalizer.d.ts.map +1 -0
  29. package/dist/core/mcp-normalizer.js +382 -0
  30. package/dist/core/types.d.ts +26 -2
  31. package/dist/core/types.d.ts.map +1 -1
  32. package/dist/dev-server.d.ts.map +1 -1
  33. package/dist/dev-server.js +46 -8
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js +16 -9
  36. package/dist/renderer/html-builder.d.ts.map +1 -1
  37. package/dist/renderer/html-builder.js +9 -0
  38. package/dist/themes/default/sourcey.css +36 -8
  39. package/dist/utils/markdown.d.ts.map +1 -1
  40. package/dist/utils/markdown.js +50 -1
  41. package/package.json +6 -2
package/README.md CHANGED
@@ -5,7 +5,7 @@
5
5
  Sourcey is an open source documentation platform. Point it at an OpenAPI spec, add markdown guides, get a complete docs site. Static HTML you own; no dashboard, no monthly bill, no API calls to render your own documentation. Deploy anywhere.
6
6
 
7
7
  [![npm](https://img.shields.io/npm/v/sourcey)](https://www.npmjs.com/package/sourcey)
8
- [![build](https://img.shields.io/github/actions/workflow/status/nilstate/sourcey/ci.yml?branch=master)](https://github.com/nilstate/sourcey/actions)
8
+ [![build](https://img.shields.io/github/actions/workflow/status/sourcey/sourcey/ci.yml?branch=master)](https://github.com/sourcey/sourcey/actions)
9
9
  [![node](https://img.shields.io/node/v/sourcey)](https://nodejs.org)
10
10
 
11
11
  ```bash
@@ -14,7 +14,7 @@ npx sourcey init
14
14
 
15
15
  ![Sourcey](assets/screenshot.jpg)
16
16
 
17
- **[Live demo](https://cheesestore.github.io/)** · [Documentation](https://sourcey.com/docs) · [GitHub](https://github.com/nilstate/sourcey)
17
+ **[Live demo](https://cheesestore.github.io/)** · [Documentation](https://sourcey.com/docs) · [GitHub](https://github.com/sourcey/sourcey)
18
18
 
19
19
  ## Features
20
20
 
@@ -43,6 +43,22 @@ npx sourcey init
43
43
  | Self-hosted | Yes | No | No | No | Yes | Yes |
44
44
  | Pricing | Free / AGPL | $150+/mo | Free / paid | Paid | Free / paid | Free |
45
45
 
46
+ ## Install
47
+
48
+ ```bash
49
+ # npm (recommended)
50
+ npx sourcey init
51
+
52
+ # Homebrew
53
+ brew tap sourcey/sourcey && brew install sourcey
54
+
55
+ # Docker
56
+ docker run -v $(pwd):/docs sourcey/sourcey build
57
+
58
+ # Nix
59
+ nix run github:sourcey/sourcey
60
+ ```
61
+
46
62
  ## Quick start
47
63
 
48
64
  ```bash
@@ -159,7 +175,7 @@ sourcey validate api.yaml Validate a spec file
159
175
  ## Development
160
176
 
161
177
  ```bash
162
- git clone https://github.com/nilstate/sourcey.git
178
+ git clone https://github.com/sourcey/sourcey.git
163
179
  cd sourcey && npm install
164
180
  npm run build && npm test
165
181
 
@@ -74,10 +74,17 @@
74
74
  }
75
75
  }
76
76
 
77
- // Scroll to element with header offset
77
+ // Scroll to element with header offset.
78
+ // For the first traverse target, scroll to the very top of the page
79
+ // so the title and all top padding are visible.
78
80
  function scrollToId(id, behavior) {
79
81
  var el = document.getElementById(id);
80
82
  if (!el) return;
83
+ var firstTarget = targets.length ? targets[0].getAttribute('data-traverse-target') : null;
84
+ if (id === firstTarget) {
85
+ window.scrollTo({ top: 0, behavior: behavior });
86
+ return;
87
+ }
81
88
  var offset = (navbar ? navbar.offsetHeight : 0) - 1;
82
89
  window.scrollTo({ top: el.getBoundingClientRect().top + window.scrollY - offset, behavior: behavior });
83
90
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Head.d.ts","sourceRoot":"","sources":["../../../src/components/layout/Head.tsx"],"names":[],"mappings":"AAKA,wBAAgB,IAAI,iCA8EnB"}
1
+ {"version":3,"file":"Head.d.ts","sourceRoot":"","sources":["../../../src/components/layout/Head.tsx"],"names":[],"mappings":"AAKA,wBAAgB,IAAI,iCAqFnB"}
@@ -52,5 +52,5 @@ export function Head() {
52
52
  body { margin: 0; background: rgb(var(--color-background-light)); }
53
53
  .dark body { background: rgb(var(--color-background-dark)); }
54
54
  `;
55
- return (_jsxs("head", { children: [_jsx("meta", { charset: "utf-8" }), _jsx("meta", { name: "viewport", content: "width=device-width, initial-scale=1" }), _jsx("title", { children: pageTitle }), _jsx("meta", { name: "description", content: pageDescription }), _jsx("meta", { name: "generator", content: `Sourcey ${pkg.version}` }), _jsx("meta", { name: "sourcey-search", content: `${options.assetBase}search-index.json` }), _jsx("style", { dangerouslySetInnerHTML: { __html: themeCSS } }), _jsx("style", { dangerouslySetInnerHTML: { __html: langIconCSS() } }), site.customCSS && _jsx("style", { dangerouslySetInnerHTML: { __html: site.customCSS } }), _jsx("script", { dangerouslySetInnerHTML: { __html: `(function(){var t=localStorage.getItem('sourcey-theme');if(t==='dark')document.documentElement.classList.add('dark')})()` } }), googleFontsUrl && (_jsxs(_Fragment, { children: [_jsx("link", { rel: "preconnect", href: "https://fonts.googleapis.com" }), _jsx("link", { rel: "preconnect", href: "https://fonts.gstatic.com", crossOrigin: "anonymous" }), _jsx("link", { rel: "stylesheet", href: googleFontsUrl })] })), _jsx("link", { rel: "stylesheet", href: `${options.assetBase}sourcey.css` }), site.favicon && _jsx("link", { rel: "icon", href: site.favicon })] }));
55
+ return (_jsxs("head", { children: [_jsx("meta", { charset: "utf-8" }), _jsx("meta", { name: "viewport", content: "width=device-width, initial-scale=1" }), _jsx("title", { children: pageTitle }), _jsx("meta", { name: "description", content: pageDescription }), _jsx("meta", { name: "generator", content: `Sourcey ${pkg.version}` }), _jsx("meta", { property: "og:title", content: pageTitle }), _jsx("meta", { property: "og:description", content: pageDescription }), _jsx("meta", { property: "og:type", content: "website" }), siteName && _jsx("meta", { property: "og:site_name", content: siteName }), _jsx("meta", { name: "twitter:card", content: "summary" }), _jsx("meta", { name: "twitter:title", content: pageTitle }), _jsx("meta", { name: "twitter:description", content: pageDescription }), _jsx("meta", { name: "sourcey-search", content: `${options.assetBase}search-index.json` }), _jsx("style", { dangerouslySetInnerHTML: { __html: themeCSS } }), _jsx("style", { dangerouslySetInnerHTML: { __html: langIconCSS() } }), site.customCSS && _jsx("style", { dangerouslySetInnerHTML: { __html: site.customCSS } }), _jsx("script", { dangerouslySetInnerHTML: { __html: `(function(){var t=localStorage.getItem('sourcey-theme');if(t==='dark')document.documentElement.classList.add('dark')})()` } }), googleFontsUrl && (_jsxs(_Fragment, { children: [_jsx("link", { rel: "preconnect", href: "https://fonts.googleapis.com" }), _jsx("link", { rel: "preconnect", href: "https://fonts.gstatic.com", crossOrigin: "anonymous" }), _jsx("link", { rel: "stylesheet", href: googleFontsUrl })] })), _jsx("link", { rel: "stylesheet", href: `${options.assetBase}sourcey.css` }), site.favicon && _jsx("link", { rel: "icon", href: site.favicon })] }));
56
56
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Page.d.ts","sourceRoot":"","sources":["../../../src/components/layout/Page.tsx"],"names":[],"mappings":"AA8OA,wBAAgB,IAAI,iCAqCnB"}
1
+ {"version":3,"file":"Page.d.ts","sourceRoot":"","sources":["../../../src/components/layout/Page.tsx"],"names":[],"mappings":"AAkPA,wBAAgB,IAAI,iCAqCnB"}
@@ -10,6 +10,7 @@ import { SecurityDefinitions } from "../openapi/Security.js";
10
10
  import { Tags } from "../openapi/Tags.js";
11
11
  import { Definition } from "../openapi/Definition.js";
12
12
  import { SocialIcon } from "../ui/SocialIcon.js";
13
+ import { McpConnection } from "../mcp/McpConnection.js";
13
14
  /**
14
15
  * Markdown page content with prose typography.
15
16
  */
@@ -27,7 +28,7 @@ function MarkdownPageContent({ page, className = "" }) {
27
28
  function SpecPageContent({ className = "" }) {
28
29
  const spec = useContext(SpecContext);
29
30
  const serverUrl = spec.servers[0]?.url ?? "/";
30
- return (_jsxs("div", { class: `relative grow box-border flex-col w-full mx-auto px-1 min-w-0 ${className}`, id: "content-area", children: [_jsxs("article", { children: [_jsx("header", { class: "mb-8", children: _jsxs("div", { class: "flex items-baseline gap-3", children: [_jsx("h1", { class: "text-2xl sm:text-3xl font-bold text-[rgb(var(--color-gray-900))] dark:text-[rgb(var(--color-gray-200))] tracking-tight", children: spec.info.title }), _jsxs("span", { class: "text-sm text-[rgb(var(--color-gray-400))]", children: ["v", spec.info.version] })] }) }), _jsx(Introduction, {}), _jsx(SecurityDefinitions, {}), _jsx(Tags, { tags: spec.tags, serverUrl: serverUrl }), Object.keys(spec.schemas).length > 0 && (_jsxs("div", { class: "mt-12", children: [_jsx("div", { class: "mb-6", children: _jsx("h1", { class: "text-xl font-bold text-[rgb(var(--color-gray-900))] dark:text-[rgb(var(--color-gray-200))]", children: "Models" }) }), Object.entries(spec.schemas).map(([name, schema]) => (_jsx(Definition, { name: name, schema: schema }, name)))] }))] }), _jsx(ContentFooter, {})] }));
31
+ return (_jsxs("div", { class: `relative grow box-border flex-col w-full mx-auto px-1 min-w-0 ${className}`, id: "content-area", children: [_jsxs("article", { children: [_jsx("header", { class: "mb-8", children: _jsxs("div", { class: "flex items-baseline gap-3", children: [_jsx("h1", { class: "text-2xl sm:text-3xl font-bold text-[rgb(var(--color-gray-900))] dark:text-[rgb(var(--color-gray-200))] tracking-tight", children: spec.info.title }), _jsxs("span", { class: "text-sm text-[rgb(var(--color-gray-400))]", children: ["v", spec.info.version] })] }) }), _jsx(Introduction, {}), spec.operations[0]?.mcpExtras?.connection && (_jsx(McpConnection, { connection: spec.operations[0].mcpExtras.connection })), _jsx(SecurityDefinitions, {}), _jsx(Tags, { tags: spec.tags, serverUrl: serverUrl }), Object.keys(spec.schemas).length > 0 && (_jsxs("div", { class: "mt-12", children: [_jsx("div", { class: "mb-6", children: _jsx("h1", { class: "text-xl font-bold text-[rgb(var(--color-gray-900))] dark:text-[rgb(var(--color-gray-200))]", children: "Models" }) }), Object.entries(spec.schemas).map(([name, schema]) => (_jsx(Definition, { name: name, schema: schema }, name)))] }))] }), _jsx(ContentFooter, {})] }));
31
32
  }
32
33
  function PageNavigation() {
33
34
  const nav = useContext(NavigationContext);
@@ -1 +1 @@
1
- {"version":3,"file":"Sidebar.d.ts","sourceRoot":"","sources":["../../../src/components/layout/Sidebar.tsx"],"names":[],"mappings":"AA+EA;;GAEG;AACH,wBAAgB,OAAO,wCAuGtB"}
1
+ {"version":3,"file":"Sidebar.d.ts","sourceRoot":"","sources":["../../../src/components/layout/Sidebar.tsx"],"names":[],"mappings":"AAoFA;;GAEG;AACH,wBAAgB,OAAO,wCAuGtB"}
@@ -8,7 +8,7 @@ import { Logo } from "../ui/Logo.js";
8
8
  */
9
9
  function MethodPill({ method }) {
10
10
  const m = method.toUpperCase();
11
- const label = m === "DELETE" ? "DEL" : m;
11
+ const label = m === "DELETE" ? "DEL" : m === "RESOURCE" ? "RES" : m === "PROMPT" ? "PRMT" : m;
12
12
  const colors = {
13
13
  GET: "bg-green-400/20 dark:bg-green-400/20 text-green-700 dark:text-green-400",
14
14
  POST: "bg-blue-400/20 dark:bg-blue-400/20 text-blue-700 dark:text-blue-400",
@@ -16,6 +16,11 @@ function MethodPill({ method }) {
16
16
  DELETE: "bg-red-400/20 dark:bg-red-400/20 text-red-700 dark:text-red-400",
17
17
  DEL: "bg-red-400/20 dark:bg-red-400/20 text-red-700 dark:text-red-400",
18
18
  PATCH: "bg-orange-400/20 dark:bg-orange-400/20 text-orange-700 dark:text-orange-400",
19
+ TOOL: "bg-purple-400/20 dark:bg-purple-400/20 text-purple-700 dark:text-purple-400",
20
+ RESOURCE: "bg-green-400/20 dark:bg-green-400/20 text-green-700 dark:text-green-400",
21
+ RES: "bg-green-400/20 dark:bg-green-400/20 text-green-700 dark:text-green-400",
22
+ PROMPT: "bg-blue-400/20 dark:bg-blue-400/20 text-blue-700 dark:text-blue-400",
23
+ PRMT: "bg-blue-400/20 dark:bg-blue-400/20 text-blue-700 dark:text-blue-400",
19
24
  };
20
25
  return (_jsx("span", { class: "flex items-center w-8 h-[1lh] shrink-0", children: _jsx("span", { class: `px-1 py-0.5 rounded-md text-[0.55rem] leading-tight font-bold ${colors[m] ?? "bg-gray-400/20 text-gray-700"}`, children: label }) }));
21
26
  }
@@ -16,7 +16,7 @@ function TocList({ headings }) {
16
16
  groups[groups.length - 1].children.push(h);
17
17
  }
18
18
  }
19
- return (_jsx("ul", { class: "space-y-0.5", children: groups.map((g) => (_jsxs("li", { children: [_jsx("a", { href: `#${g.root.id}`, class: `${tocLink} py-1`, children: g.root.text }), g.children.length > 0 && (_jsx("ul", { class: "mb-1.5", children: g.children.map((c) => (_jsx("li", { children: _jsx("a", { href: `#${c.id}`, class: `${tocLink} pl-3 text-[13px] py-0.5`, children: c.text }) }, c.id))) }))] }, g.root.id))) }));
19
+ return (_jsx("ul", { children: groups.map((g) => (_jsxs("li", { children: [_jsx("a", { href: `#${g.root.id}`, class: `${tocLink} py-1`, children: g.root.text }), g.children.length > 0 && (_jsx("ul", { children: g.children.map((c) => (_jsx("li", { children: _jsx("a", { href: `#${c.id}`, class: `${tocLink} pl-3 text-[13px] py-0.5`, children: c.text }) }, c.id))) }))] }, g.root.id))) }));
20
20
  }
21
21
  export function TableOfContents({ headings }) {
22
22
  if (headings.length === 0)
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Renders MCP tool annotation badges inline with the operation title.
3
+ * Same visual pattern as DeprecatedBadge / RequiredBadge / ReadOnlyBadge.
4
+ */
5
+ interface Annotations {
6
+ readOnlyHint?: boolean;
7
+ destructiveHint?: boolean;
8
+ idempotentHint?: boolean;
9
+ openWorldHint?: boolean;
10
+ }
11
+ export declare function AnnotationBadges({ annotations }: {
12
+ annotations: Annotations;
13
+ }): import("preact").JSX.Element;
14
+ export {};
15
+ //# sourceMappingURL=AnnotationBadges.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AnnotationBadges.d.ts","sourceRoot":"","sources":["../../../src/components/mcp/AnnotationBadges.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,UAAU,WAAW;IACnB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AASD,wBAAgB,gBAAgB,CAAC,EAAE,WAAW,EAAE,EAAE;IAAE,WAAW,EAAE,WAAW,CAAA;CAAE,gCAa7E"}
@@ -0,0 +1,10 @@
1
+ import { jsx as _jsx, Fragment as _Fragment } from "preact/jsx-runtime";
2
+ const badges = [
3
+ { key: "readOnlyHint", label: "read-only", className: "bg-green-100/50 text-green-600 dark:bg-green-400/10 dark:text-green-300" },
4
+ { key: "destructiveHint", label: "destructive", className: "bg-red-100/50 text-red-600 dark:bg-red-400/10 dark:text-red-300" },
5
+ { key: "idempotentHint", label: "idempotent", className: "bg-blue-100/50 text-blue-600 dark:bg-blue-400/10 dark:text-blue-300" },
6
+ { key: "openWorldHint", label: "open-world", className: "bg-amber-100/50 text-amber-600 dark:bg-amber-400/10 dark:text-amber-300" },
7
+ ];
8
+ export function AnnotationBadges({ annotations }) {
9
+ return (_jsx(_Fragment, { children: badges.map(({ key, label, className }) => annotations[key] && (_jsx("span", { class: `whitespace-nowrap rounded-md px-2 py-0.5 text-xs font-medium ${className}`, children: label }, key))) }));
10
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Connection config card for MCP docs.
3
+ * Rendered below Introduction in SpecPageContent.
4
+ * Uses the same bordered card pattern as Introduction's Base URLs table.
5
+ */
6
+ import type { McpConnectionInfo } from "../../core/types.js";
7
+ export declare function McpConnection({ connection }: {
8
+ connection: McpConnectionInfo;
9
+ }): import("preact").JSX.Element | null;
10
+ //# sourceMappingURL=McpConnection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"McpConnection.d.ts","sourceRoot":"","sources":["../../../src/components/mcp/McpConnection.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE7D,wBAAgB,aAAa,CAAC,EAAE,UAAU,EAAE,EAAE;IAAE,UAAU,EAAE,iBAAiB,CAAA;CAAE,uCAwD9E"}
@@ -0,0 +1,32 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "preact/jsx-runtime";
2
+ export function McpConnection({ connection }) {
3
+ const transport = connection.transport;
4
+ if (!transport)
5
+ return null;
6
+ // Build the config JSON snippet
7
+ const serverEntry = {};
8
+ if (transport.type === "stdio") {
9
+ if (transport.command)
10
+ serverEntry.command = transport.command;
11
+ if (transport.args?.length)
12
+ serverEntry.args = transport.args;
13
+ }
14
+ else {
15
+ if (transport.url)
16
+ serverEntry.url = transport.url;
17
+ }
18
+ const configJson = JSON.stringify({ mcpServers: { [connection.serverName]: serverEntry } }, null, 2);
19
+ // Capabilities summary
20
+ const caps = [];
21
+ if (connection.capabilities) {
22
+ if (connection.capabilities.tools)
23
+ caps.push("tools");
24
+ if (connection.capabilities.resources)
25
+ caps.push("resources");
26
+ if (connection.capabilities.prompts)
27
+ caps.push("prompts");
28
+ if (connection.capabilities.logging)
29
+ caps.push("logging");
30
+ }
31
+ return (_jsxs("div", { class: "mb-8 rounded-[var(--radius)] border border-[rgb(var(--color-gray-200)/0.7)] dark:border-[rgb(var(--color-border-dark-subtle)/0.1)] overflow-hidden", children: [_jsx("div", { class: "px-4 py-2.5 text-xs font-semibold text-[rgb(var(--color-gray-600))] dark:text-[rgb(var(--color-gray-300))] border-b border-[rgb(var(--color-gray-200)/0.7)] dark:border-[rgb(var(--color-border-dark-subtle)/0.1)]", children: "Connect" }), _jsxs("div", { class: "px-4 py-3", children: [_jsx("p", { class: "text-sm text-[rgb(var(--color-gray-500))] mb-3", children: "Add to your MCP client configuration:" }), _jsx("div", { class: "code-group not-prose", children: _jsx("div", { class: "relative w-full px-4 py-3.5 text-sm leading-6 bg-[rgb(var(--color-code-block-light))] dark:bg-[rgb(var(--color-code-block-dark))] overflow-x-auto rounded-[var(--radius)]", style: "font-variant-ligatures: none", children: _jsx("div", { class: "font-mono whitespace-pre text-xs leading-[1.35rem] text-[rgb(var(--color-gray-800))] dark:text-[rgb(var(--color-gray-200))]", children: configJson }) }) }), _jsxs("div", { class: "mt-3 flex flex-wrap gap-x-6 gap-y-1 text-xs text-[rgb(var(--color-gray-500))]", children: [connection.mcpVersion && (_jsxs("span", { children: ["Protocol ", _jsxs("span", { class: "font-medium text-[rgb(var(--color-gray-700))] dark:text-[rgb(var(--color-gray-300))]", children: ["MCP ", connection.mcpVersion] })] })), _jsxs("span", { children: ["Transport ", _jsx("span", { class: "font-medium text-[rgb(var(--color-gray-700))] dark:text-[rgb(var(--color-gray-300))]", children: transport.type })] }), caps.length > 0 && (_jsxs("span", { children: ["Capabilities ", _jsx("span", { class: "font-medium text-[rgb(var(--color-gray-700))] dark:text-[rgb(var(--color-gray-300))]", children: caps.join(", ") })] }))] })] })] }));
32
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * MCP equivalent of EndpointBar. Shows method pill + tool name or resource URI.
3
+ */
4
+ export declare function McpEndpointBar({ method, path }: {
5
+ method: string;
6
+ path: string;
7
+ }): import("preact").JSX.Element;
8
+ //# sourceMappingURL=McpEndpointBar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"McpEndpointBar.d.ts","sourceRoot":"","sources":["../../../src/components/mcp/McpEndpointBar.tsx"],"names":[],"mappings":"AAAA;;GAEG;AAQH,wBAAgB,cAAc,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,gCAuBhF"}
@@ -0,0 +1,16 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "preact/jsx-runtime";
2
+ /**
3
+ * MCP equivalent of EndpointBar. Shows method pill + tool name or resource URI.
4
+ */
5
+ const methodColors = {
6
+ tool: "bg-purple-400/20 dark:bg-purple-400/20 text-purple-700 dark:text-purple-400",
7
+ resource: "bg-green-400/20 dark:bg-green-400/20 text-green-700 dark:text-green-400",
8
+ prompt: "bg-blue-400/20 dark:bg-blue-400/20 text-blue-700 dark:text-blue-400",
9
+ };
10
+ export function McpEndpointBar({ method, path }) {
11
+ const colorClass = methodColors[method] ?? "bg-gray-400/20 text-gray-700";
12
+ const label = method.toUpperCase();
13
+ // Split path on {param} segments for dimmed rendering
14
+ const segments = path.split(/(\{[^}]+\})/);
15
+ return (_jsxs("div", { class: "flex items-center gap-2 rounded-[var(--radius)] border border-[rgb(var(--color-gray-200)/0.7)] dark:border-[rgb(var(--color-border-dark-subtle)/0.1)] px-3 py-2.5 mb-6 overflow-hidden", children: [_jsx("span", { class: `rounded-lg font-bold px-1.5 py-0.5 text-sm leading-5 shrink-0 ${colorClass}`, children: label }), _jsx("span", { class: "flex items-center overflow-x-auto flex-1 no-scrollbar font-mono text-sm text-[rgb(var(--color-gray-800))] dark:text-[rgb(var(--color-gray-200))]", children: segments.map((seg, i) => seg.startsWith("{") ? (_jsx("span", { class: "text-[rgb(var(--color-gray-400))] dark:text-[rgb(var(--color-gray-500))]", children: seg }, i)) : (_jsx("span", { children: seg }, i))) })] }));
16
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * MCP Returns section — replaces Responses for MCP operations.
3
+ * Renders output schema as a schema view instead of status code tables.
4
+ */
5
+ import type { NormalizedSchema } from "../../core/types.js";
6
+ /**
7
+ * Left column: "Returns" section label + schema view or fallback text.
8
+ */
9
+ export declare function McpReturnsCopy({ schema }: {
10
+ schema?: NormalizedSchema;
11
+ }): import("preact").JSX.Element;
12
+ /**
13
+ * Right column (sticky panel): example JSON for the output schema.
14
+ */
15
+ export declare function McpReturnsExample({ schema }: {
16
+ schema?: NormalizedSchema;
17
+ }): import("preact").JSX.Element;
18
+ //# sourceMappingURL=McpReturns.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"McpReturns.d.ts","sourceRoot":"","sources":["../../../src/components/mcp/McpReturns.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAK5D;;GAEG;AACH,wBAAgB,cAAc,CAAC,EAAE,MAAM,EAAE,EAAE;IAAE,MAAM,CAAC,EAAE,gBAAgB,CAAA;CAAE,gCAavE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,MAAM,EAAE,EAAE;IAAE,MAAM,CAAC,EAAE,gBAAgB,CAAA;CAAE,gCAyB1E"}
@@ -0,0 +1,33 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "preact/jsx-runtime";
2
+ import { SchemaView } from "../schema/SchemaView.js";
3
+ import { ExampleView } from "../schema/ExampleView.js";
4
+ import { SectionLabel } from "../ui/SectionLabel.js";
5
+ /**
6
+ * Left column: "Returns" section label + schema view or fallback text.
7
+ */
8
+ export function McpReturnsCopy({ schema }) {
9
+ return (_jsxs("div", { class: "mt-6", children: [_jsx(SectionLabel, { children: "Returns" }), schema ? (_jsx(SchemaView, { schema: schema })) : (_jsx("p", { class: "text-sm text-[rgb(var(--color-gray-500))]", children: "Returns MCP content array (text, image, or embedded resource)." }))] }));
10
+ }
11
+ /**
12
+ * Right column (sticky panel): example JSON for the output schema.
13
+ */
14
+ export function McpReturnsExample({ schema }) {
15
+ if (!schema) {
16
+ return (_jsx(ExampleView, { schema: {
17
+ type: "object",
18
+ properties: {
19
+ content: {
20
+ type: "array",
21
+ items: {
22
+ type: "object",
23
+ properties: {
24
+ type: { type: "string", enum: ["text", "image", "resource"] },
25
+ text: { type: "string", example: "..." },
26
+ },
27
+ },
28
+ },
29
+ },
30
+ }, title: "Response" }));
31
+ }
32
+ return _jsx(ExampleView, { schema: schema, title: "Response" });
33
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"Operation.d.ts","sourceRoot":"","sources":["../../../src/components/openapi/Operation.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAyB,MAAM,qBAAqB,CAAC;AAatF,UAAU,cAAc;IACtB,SAAS,EAAE,mBAAmB,CAAC;IAC/B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,cAAc,gCAsErE"}
1
+ {"version":3,"file":"Operation.d.ts","sourceRoot":"","sources":["../../../src/components/openapi/Operation.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAyB,MAAM,qBAAqB,CAAC;AAgBtF,UAAU,cAAc;IACtB,SAAS,EAAE,mBAAmB,CAAC;IAC/B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,cAAc,gCA0FrE"}
@@ -11,6 +11,9 @@ import { ResponsesCopy, ResponsesExamples } from "./Responses.js";
11
11
  import { SecurityCopy } from "./Security.js";
12
12
  import { CodeSamplesExamples } from "./CodeSamples.js";
13
13
  import { EndpointBar } from "./EndpointBar.js";
14
+ import { McpEndpointBar } from "../mcp/McpEndpointBar.js";
15
+ import { AnnotationBadges } from "../mcp/AnnotationBadges.js";
16
+ import { McpReturnsCopy, McpReturnsExample } from "../mcp/McpReturns.js";
14
17
  /**
15
18
  * Single operation with sticky code panel:
16
19
  * - Endpoint bar at top
@@ -22,7 +25,8 @@ export function Operation({ operation: op, serverUrl }) {
22
25
  const id = `operation-${htmlId(op.path)}-${htmlId(op.method)}`;
23
26
  const hasParams = op.parameters.length > 0;
24
27
  const hasBody = !!op.requestBody;
25
- return (_jsxs("div", { id: id, class: "py-8 border-t border-[rgb(var(--color-gray-100))] dark:border-[rgb(var(--color-gray-800))]", "data-traverse-target": id, children: [_jsxs("header", { class: "mb-6", children: [op.summary && (_jsx("h2", { class: "text-2xl sm:text-3xl text-[rgb(var(--color-gray-900))] dark:text-[rgb(var(--color-gray-200))] tracking-tight font-bold mb-2", children: _jsx(Markdown, { content: op.summary, inline: true }) })), op.deprecated && _jsx(DeprecatedBadge, {})] }), _jsx(EndpointBar, { method: op.method, path: op.path, serverUrl: serverUrl }), _jsxs("div", { class: `flex flex-col ${apiFirst ? "lg:flex-row" : "xl:flex-row"} gap-8`, children: [_jsxs("div", { class: "flex-1 min-w-0", children: [op.description && (_jsx(Markdown, { content: op.description, class: "mb-6" })), hasBody && (_jsxs("div", { class: "mt-6", children: [_jsx(SectionLabel, { meta: bodyMediaType(op.requestBody), children: "Body" }), _jsx(RequestBody, { body: op.requestBody })] })), hasParams && (_jsxs("div", { class: "mt-6", children: [_jsx(SectionLabel, { children: "Parameters" }), _jsx(Parameters, { parameters: op.parameters })] })), op.responses.length > 0 && (_jsxs("div", { class: "mt-6", children: [_jsx(SectionLabel, { children: "Response" }), _jsx(ResponsesCopy, { responses: op.responses })] })), _jsx(SecurityCopy, { security: op.security })] }), _jsxs("aside", { class: `hidden ${apiFirst ? "lg:block" : "xl:block"} w-[28rem] shrink-0 sticky self-start overflow-y-auto space-y-4`, style: "top: calc(var(--header-height) + 2.5rem); max-height: calc(100vh - var(--header-height) - 5rem)", children: [_jsx(CodeSamplesExamples, { operation: op, serverUrl: serverUrl, codeSampleLangs: site.codeSamples }), hasBody && _jsx(RequestBodyExample, { body: op.requestBody }), _jsx(ResponsesExamples, { responses: op.responses })] })] }), _jsxs("div", { class: `${apiFirst ? "lg:hidden" : "xl:hidden"} mt-8 space-y-4`, children: [_jsx(CodeSamplesExamples, { operation: op, serverUrl: serverUrl, codeSampleLangs: site.codeSamples }), hasBody && _jsx(RequestBodyExample, { body: op.requestBody }), _jsx(ResponsesExamples, { responses: op.responses })] })] }));
28
+ const mcp = op.mcpExtras;
29
+ return (_jsxs("div", { id: id, class: "py-8 border-t border-[rgb(var(--color-gray-100))] dark:border-[rgb(var(--color-gray-800))]", "data-traverse-target": id, children: [_jsx("header", { class: "mb-6", children: op.summary && (_jsxs("div", { class: "flex items-baseline gap-2 flex-wrap", children: [_jsx("h2", { class: "text-2xl sm:text-3xl text-[rgb(var(--color-gray-900))] dark:text-[rgb(var(--color-gray-200))] tracking-tight font-bold mb-2", children: _jsx(Markdown, { content: op.summary, inline: true }) }), op.deprecated && _jsx(DeprecatedBadge, {}), mcp?.annotations && _jsx(AnnotationBadges, { annotations: mcp.annotations })] })) }), mcp ? (_jsx(McpEndpointBar, { method: op.method, path: op.path })) : (_jsx(EndpointBar, { method: op.method, path: op.path, serverUrl: serverUrl })), _jsxs("div", { class: `flex flex-col ${apiFirst ? "lg:flex-row" : "xl:flex-row"} gap-8`, children: [_jsxs("div", { class: "flex-1 min-w-0", children: [op.description && (_jsx(Markdown, { content: op.description, class: "mb-6" })), hasBody && (_jsxs("div", { class: "mt-6", children: [_jsx(SectionLabel, { meta: bodyMediaType(op.requestBody), children: "Body" }), _jsx(RequestBody, { body: op.requestBody })] })), hasParams && (_jsxs("div", { class: "mt-6", children: [_jsx(SectionLabel, { children: "Parameters" }), _jsx(Parameters, { parameters: op.parameters })] })), mcp ? (_jsx(McpReturnsCopy, { schema: mcp.outputSchema })) : (op.responses.length > 0 && (_jsxs("div", { class: "mt-6", children: [_jsx(SectionLabel, { children: "Response" }), _jsx(ResponsesCopy, { responses: op.responses })] }))), !mcp && _jsx(SecurityCopy, { security: op.security })] }), _jsxs("aside", { class: `hidden ${apiFirst ? "lg:block" : "xl:block"} w-[28rem] shrink-0 sticky self-start overflow-y-auto space-y-4`, style: "top: calc(var(--header-height) + 2.5rem); max-height: calc(100vh - var(--header-height) - 5rem)", children: [_jsx(CodeSamplesExamples, { operation: op, serverUrl: serverUrl, codeSampleLangs: site.codeSamples }), hasBody && _jsx(RequestBodyExample, { body: op.requestBody }), mcp ? (_jsx(McpReturnsExample, { schema: mcp.outputSchema })) : (_jsx(ResponsesExamples, { responses: op.responses }))] })] }), _jsxs("div", { class: `${apiFirst ? "lg:hidden" : "xl:hidden"} mt-8 space-y-4`, children: [_jsx(CodeSamplesExamples, { operation: op, serverUrl: serverUrl, codeSampleLangs: site.codeSamples }), hasBody && _jsx(RequestBodyExample, { body: op.requestBody }), mcp ? (_jsx(McpReturnsExample, { schema: mcp.outputSchema })) : (_jsx(ResponsesExamples, { responses: op.responses }))] })] }));
26
30
  }
27
31
  function bodyMediaType(body) {
28
32
  const types = Object.keys(body.content);
package/dist/config.d.ts CHANGED
@@ -78,6 +78,8 @@ export interface TabConfig {
78
78
  openapi?: string;
79
79
  groups?: GroupConfig[];
80
80
  doxygen?: DoxygenConfig;
81
+ /** Path to an mcp.json file (MCP server snapshot). */
82
+ mcp?: string;
81
83
  }
82
84
  export interface GroupConfig {
83
85
  group: string;
@@ -146,6 +148,7 @@ export interface ResolvedTab {
146
148
  openapi?: string;
147
149
  groups?: ResolvedGroup[];
148
150
  doxygen?: ResolvedDoxygenConfig;
151
+ mcp?: string;
149
152
  }
150
153
  export interface ResolvedPage {
151
154
  /** Original config slug (e.g. "run/index") */
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
package/dist/config.js CHANGED
@@ -137,18 +137,23 @@ async function resolveTabs(tabs, configDir) {
137
137
  if (slugs.has(slug))
138
138
  throw new Error(`Duplicate tab slug "${slug}" (from "${tab.tab}")`);
139
139
  slugs.add(slug);
140
- const sources = [tab.openapi, tab.groups, tab.doxygen].filter(Boolean).length;
140
+ const sources = [tab.openapi, tab.groups, tab.doxygen, tab.mcp].filter(Boolean).length;
141
141
  if (sources > 1) {
142
- throw new Error(`Tab "${tab.tab}" has multiple sources; use only one of "openapi", "groups", or "doxygen"`);
142
+ throw new Error(`Tab "${tab.tab}" has multiple sources; use only one of "openapi", "groups", "doxygen", or "mcp"`);
143
143
  }
144
144
  if (sources === 0) {
145
- throw new Error(`Tab "${tab.tab}" needs one of "openapi", "groups", or "doxygen"`);
145
+ throw new Error(`Tab "${tab.tab}" needs one of "openapi", "groups", "doxygen", or "mcp"`);
146
146
  }
147
147
  if (tab.openapi) {
148
148
  const absPath = resolve(configDir, tab.openapi);
149
149
  await assertExists(absPath, `OpenAPI spec "${tab.openapi}" in tab "${tab.tab}"`);
150
150
  resolved.push({ label: tab.tab, slug, openapi: absPath });
151
151
  }
152
+ else if (tab.mcp) {
153
+ const absPath = resolve(configDir, tab.mcp);
154
+ await assertExists(absPath, `MCP spec "${tab.mcp}" in tab "${tab.tab}"`);
155
+ resolved.push({ label: tab.tab, slug, mcp: absPath });
156
+ }
152
157
  else if (tab.doxygen) {
153
158
  const absXml = resolve(configDir, tab.doxygen.xml);
154
159
  await assertExists(absXml, `Doxygen XML directory "${tab.doxygen.xml}" in tab "${tab.tab}"`);
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Convert an McpSpec (from mcp-parser) into a NormalizedSpec for rendering.
3
+ *
4
+ * This is the bridge between the MCP snapshot format and sourcey's
5
+ * format-agnostic rendering pipeline. Everything downstream (components,
6
+ * search, navigation, themes) works unchanged.
7
+ */
8
+ import type { McpSpec } from "mcp-parser";
9
+ import type { NormalizedSpec } from "./types.js";
10
+ export declare function normalizeMcpSpec(spec: McpSpec): NormalizedSpec;
11
+ //# sourceMappingURL=mcp-normalizer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-normalizer.d.ts","sourceRoot":"","sources":["../../src/core/mcp-normalizer.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAoE,MAAM,YAAY,CAAC;AAC5G,OAAO,KAAK,EACV,cAAc,EAUf,MAAM,YAAY,CAAC;AAKpB,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,OAAO,GAAG,cAAc,CA+C9D"}