Skip to content
Merged
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
65 changes: 65 additions & 0 deletions .github/workflows/docs-preview.yml
Original file line number Diff line number Diff line change
@@ -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: "<!-- docs-preview-comment -->"

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: "<!-- docs-preview-comment -->"
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
<!-- LOGO -->
<div align="center">
<img src="media/mcp.svg#gh-light-mode-only" alt="MCP Apps" width="128">
<img src="media/mcp-white.svg#gh-dark-mode-only" alt="MCP Apps" width="128">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="media/mcp-white.svg">
<source media="(prefers-color-scheme: light)" srcset="media/mcp.svg">
<img src="media/mcp.svg" alt="MCP Apps" width="128">
</picture>
<h1>MCP Apps</h1>
<p>
Build interactive UIs for MCP tools — charts, forms, dashboards — that render inline in Claude, ChatGPT and any other compliant chat client.
Expand Down
185 changes: 106 additions & 79 deletions docs/mcp-theme.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,169 +2,196 @@
* 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;
}

/* ------------------------------------------------------------------ */
/* Light mode colors */
/* ------------------------------------------------------------------ */

: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;
}

/* ------------------------------------------------------------------ */
/* Dark mode colors */
/* ------------------------------------------------------------------ */

: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;
}

/* ------------------------------------------------------------------ */
/* Header — taller, frosted glass */
/* ------------------------------------------------------------------ */

: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 <picture> by mcpstyle plugin) */
/* ------------------------------------------------------------------ */

/* Explicit theme selection via TypeDoc switcher — takes precedence */
:root[data-theme="light"] .mcp-logo-dark,
:root[data-theme="dark"] .mcp-logo-light {
display: none;
}

/* "OS" mode (data-theme='os') follows prefers-color-scheme */
@media (prefers-color-scheme: light) {
:root[data-theme="os"] .mcp-logo-dark {
display: none;
}
}

@media (prefers-color-scheme: dark) {
:root[data-theme="os"] .mcp-logo-light {
display: none;
}
}

/* ------------------------------------------------------------------ */
/* Sidebar navigation (matches modelcontextprotocol.io sidebar) */
/* ------------------------------------------------------------------ */

.tsd-navigation a {
padding: 0.375rem 0.75rem;
font-size: 0.875rem;
line-height: 1.5;
border-radius: 0.75rem;
color: var(--color-text-aside);
transition: background-color 0.15s ease, color 0.15s ease;
padding: 0.375rem 0.75rem;
font-size: 0.875rem;
line-height: 1.5;
border-radius: 0.75rem;
color: var(--color-text-aside);
transition:
background-color 0.15s ease,
color 0.15s ease;
}

.tsd-navigation a:hover:not(.current) {
background-color: rgba(107, 114, 128, 0.05);
color: var(--color-text);
background-color: rgba(107, 114, 128, 0.05);
color: var(--color-text);
}

.tsd-navigation a.current {
background-color: rgba(107, 114, 128, 0.15);
color: var(--color-text);
font-weight: 700;
background-color: rgba(107, 114, 128, 0.15);
color: var(--color-text);
font-weight: 700;
}

/* Group headers (Documents, Security, API Documentation) */
.tsd-accordion-summary > h3 {
font-weight: 600;
font-size: 0.875rem;
letter-spacing: 0.01em;
font-weight: 600;
font-size: 0.875rem;
letter-spacing: 0.01em;
}

.site-menu {
padding: 1.25rem 0;
padding: 1.25rem 0;
}

@media (prefers-color-scheme: dark) {
.tsd-navigation a {
color: var(--color-text-aside);
}
.tsd-navigation a {
color: var(--color-text-aside);
}

.tsd-navigation a:hover:not(.current) {
background-color: rgba(229, 231, 235, 0.05);
color: var(--color-text);
}
.tsd-navigation a:hover:not(.current) {
background-color: rgba(229, 231, 235, 0.05);
color: var(--color-text);
}

.tsd-navigation a.current {
background-color: rgba(229, 231, 235, 0.15);
color: var(--color-text);
font-weight: 700;
}
.tsd-navigation a.current {
background-color: rgba(229, 231, 235, 0.15);
color: var(--color-text);
font-weight: 700;
}
}

:root[data-theme='dark'] .tsd-navigation a {
color: var(--color-text-aside);
:root[data-theme="dark"] .tsd-navigation a {
color: var(--color-text-aside);
}

:root[data-theme='dark'] .tsd-navigation a:hover:not(.current) {
background-color: rgba(229, 231, 235, 0.05);
color: var(--color-text);
:root[data-theme="dark"] .tsd-navigation a:hover:not(.current) {
background-color: rgba(229, 231, 235, 0.05);
color: var(--color-text);
}

:root[data-theme='dark'] .tsd-navigation a.current {
background-color: rgba(229, 231, 235, 0.15);
color: var(--color-text);
font-weight: 700;
:root[data-theme="dark"] .tsd-navigation a.current {
background-color: rgba(229, 231, 235, 0.15);
color: var(--color-text);
font-weight: 700;
}

/* ------------------------------------------------------------------ */
/* Content area */
/* ------------------------------------------------------------------ */

.tsd-typography {
line-height: 1.6;
line-height: 1.6;
}

.tsd-panel.tsd-typography h1 {
margin-top: 0;
padding-bottom: 0.4em;
margin-top: 0;
padding-bottom: 0.4em;
}

.tsd-panel.tsd-typography h2 {
margin-top: 2rem;
padding-bottom: 0.3em;
margin-top: 2rem;
padding-bottom: 0.3em;
}

.tsd-panel.tsd-typography h3 {
margin-top: 1.75rem;
margin-top: 1.75rem;
}

/* ------------------------------------------------------------------ */
Expand All @@ -173,17 +200,17 @@ body {

code,
pre {
font-family: var(--font-family-code);
font-size: 1em;
font-family: var(--font-family-code);
font-size: 1em;
}

.tsd-typography pre {
padding: 1rem 1.25rem;
border: 1px solid var(--color-accent);
padding: 1rem 1.25rem;
border: 1px solid var(--color-accent);
}

/* Inline code */
.tsd-typography code:not(pre code) {
padding: 0.15em 0.35em;
font-size: 1em;
padding: 0.15em 0.35em;
font-size: 1em;
}
Loading
Loading