diff --git a/.github/workflows/docs-preview.yml b/.github/workflows/docs-preview.yml new file mode 100644 index 00000000..3a170cdc --- /dev/null +++ b/.github/workflows/docs-preview.yml @@ -0,0 +1,65 @@ +name: Docs Preview + +on: + pull_request: + types: [opened, synchronize, reopened, closed] + paths: + - "docs/**" + - "src/**" + - "README.md" + - "typedoc.config.mjs" + - "scripts/typedoc-*.mjs" + - ".github/workflows/docs-preview.yml" + +permissions: + contents: read + pull-requests: write + +concurrency: + group: docs-preview-${{ github.event.pull_request.number }} + cancel-in-progress: true + +jobs: + build-and-deploy: + # Refuse to run for fork PRs — forks do not have access to the Cloudflare + # secrets, so deploys would fail anyway. + if: >- + github.event.action != 'closed' && + github.event.pull_request.head.repo.full_name == github.repository + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + + - uses: actions/setup-node@v6 + with: + node-version: "22" + cache: npm + + - run: npm ci + + - run: npm run build + + - run: npm run docs + + - name: Deploy preview + uses: modelcontextprotocol/actions/cloudflare-pages-preview/deploy@main + with: + directory: docs + project-name: mcp-ext-apps-docs-preview + api-token: ${{ secrets.CF_PAGES_PREVIEW_API_TOKEN }} + account-id: ${{ secrets.CF_PAGES_PREVIEW_ACCOUNT_ID }} + comment-title: "📖 Docs Preview Deployed" + comment-marker: "" + + cleanup: + if: >- + github.event.action == 'closed' && + github.event.pull_request.head.repo.full_name == github.repository + runs-on: ubuntu-latest + steps: + - uses: modelcontextprotocol/actions/cloudflare-pages-preview/cleanup@main + with: + project-name: mcp-ext-apps-docs-preview + api-token: ${{ secrets.CF_PAGES_PREVIEW_API_TOKEN }} + account-id: ${{ secrets.CF_PAGES_PREVIEW_ACCOUNT_ID }} + comment-marker: "" diff --git a/README.md b/README.md index 73125c41..7348e154 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,10 @@
Build interactive UIs for MCP tools — charts, forms, dashboards — that render inline in Claude, ChatGPT and any other compliant chat client.
diff --git a/docs/mcp-theme.css b/docs/mcp-theme.css
index 8dd20410..d786e55f 100644
--- a/docs/mcp-theme.css
+++ b/docs/mcp-theme.css
@@ -2,21 +2,23 @@
* MCP Apps custom theme — aligns TypeDoc styling with modelcontextprotocol.io
*/
-@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap');
+@import url("https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap");
/* ------------------------------------------------------------------ */
/* Fonts */
/* ------------------------------------------------------------------ */
:root {
- --font-family-text: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
- --font-family-code: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
+ --font-family-text:
+ "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
+ --font-family-code:
+ "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
body {
- font-family: var(--font-family-text);
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
+ font-family: var(--font-family-text);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
}
/* ------------------------------------------------------------------ */
@@ -24,12 +26,12 @@ body {
/* ------------------------------------------------------------------ */
:root {
- --light-color-background: #ffffff;
- --light-color-background-secondary: #f9fafb;
- --light-color-background-navbar: #ffffff;
- --light-color-accent: #e5e7eb;
- --light-color-text: #111827;
- --light-color-text-aside: #6b7280;
+ --light-color-background: #ffffff;
+ --light-color-background-secondary: #f9fafb;
+ --light-color-background-navbar: #ffffff;
+ --light-color-accent: #e5e7eb;
+ --light-color-text: #111827;
+ --light-color-text-aside: #6b7280;
}
/* ------------------------------------------------------------------ */
@@ -37,12 +39,12 @@ body {
/* ------------------------------------------------------------------ */
:root {
- --dark-color-background: #0f1117;
- --dark-color-background-secondary: #161b22;
- --dark-color-background-navbar: #0f1117;
- --dark-color-accent: #30363d;
- --dark-color-text: #f0f6fc;
- --dark-color-text-aside: #8b949e;
+ --dark-color-background: #0f1117;
+ --dark-color-background-secondary: #161b22;
+ --dark-color-background-navbar: #0f1117;
+ --dark-color-accent: #30363d;
+ --dark-color-text: #f0f6fc;
+ --dark-color-text-aside: #8b949e;
}
/* ------------------------------------------------------------------ */
@@ -50,32 +52,55 @@ body {
/* ------------------------------------------------------------------ */
:root {
- --dim-toolbar-contents-height: 3.5rem;
+ --dim-toolbar-contents-height: 3.5rem;
}
.tsd-page-toolbar {
- backdrop-filter: blur(12px);
- -webkit-backdrop-filter: blur(12px);
+ backdrop-filter: blur(12px);
+ -webkit-backdrop-filter: blur(12px);
}
@media (prefers-color-scheme: light) {
- .tsd-page-toolbar {
- background-color: rgba(255, 255, 255, 0.85);
- }
+ .tsd-page-toolbar {
+ background-color: rgba(255, 255, 255, 0.85);
+ }
}
@media (prefers-color-scheme: dark) {
- .tsd-page-toolbar {
- background-color: rgba(15, 17, 23, 0.75);
- }
+ .tsd-page-toolbar {
+ background-color: rgba(15, 17, 23, 0.75);
+ }
}
-:root[data-theme='light'] .tsd-page-toolbar {
- background-color: rgba(255, 255, 255, 0.85);
+:root[data-theme="light"] .tsd-page-toolbar {
+ background-color: rgba(255, 255, 255, 0.85);
}
-:root[data-theme='dark'] .tsd-page-toolbar {
- background-color: rgba(15, 17, 23, 0.75);
+:root[data-theme="dark"] .tsd-page-toolbar {
+ background-color: rgba(15, 17, 23, 0.75);
+}
+
+/* ------------------------------------------------------------------ */
+/* Theme-aware logo (rewritten from README s so
+ * the logo follows the TypeDoc theme switcher (data-theme), not just the
+ * OS prefers-color-scheme media query
*/
import { Renderer } from "typedoc";
@@ -38,6 +41,17 @@ export function load(app) {
);
}
+ // The README logo uses
tags — CSS in mcp-theme.css picks the correct
+ // one based on both data-theme and prefers-color-scheme (for "OS" mode).
+ page.contents = page.contents.replace(
+ /
]*)>\s*<\/picture>/,
+ (_, darkSrc, lightSrc, imgAttrs) =>
+ `
` +
+ `
`,
+ );
+
// Inject script to mark the current sidebar nav link with a "current" class.
// TypeDoc does not natively add this class for document pages.
// The sidebar is populated asynchronously from compressed navigation data,