Skip to content

Commit 242ec23

Browse files
authored
Merge pull request #159 from modelcontextprotocol/martinalong/mcp-apps/custom-fonts
[MCP Apps] Add way to pass custom fonts
2 parents c3e9d4d + 6397ec1 commit 242ec23

File tree

12 files changed

+323
-4
lines changed

12 files changed

+323
-4
lines changed

examples/customer-segmentation-server/src/mcp-app.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
:root {
33
color-scheme: light dark;
44

5+
/* Font families */
6+
--font-sans: system-ui, -apple-system, sans-serif;
7+
58
/* Background colors */
69
--color-background-primary: light-dark(#ffffff, #111827);
710
--color-background-secondary: light-dark(#f9fafb, #1f2937);
@@ -33,6 +36,7 @@
3336
html, body {
3437
margin: 0;
3538
padding: 0;
39+
font-family: var(--font-sans);
3640
color: var(--color-text-primary);
3741
overflow: hidden;
3842
}

examples/customer-segmentation-server/src/mcp-app.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
App,
66
PostMessageTransport,
77
applyHostStyleVariables,
8+
applyHostFonts,
89
applyDocumentTheme,
910
} from "@modelcontextprotocol/ext-apps";
1011
import { Chart, registerables } from "chart.js";
@@ -448,14 +449,17 @@ applyDocumentTheme(systemDark ? "dark" : "light");
448449
// Register handlers and connect
449450
app.onerror = log.error;
450451

451-
// Handle host context changes (theme and styles from host)
452+
// Handle host context changes (theme, styles, and fonts from host)
452453
app.onhostcontextchanged = (params) => {
453454
if (params.theme) {
454455
applyDocumentTheme(params.theme);
455456
}
456457
if (params.styles?.variables) {
457458
applyHostStyleVariables(params.styles.variables);
458459
}
460+
if (params.styles?.css?.fonts) {
461+
applyHostFonts(params.styles.css.fonts);
462+
}
459463
// Recreate chart to pick up new colors
460464
if (state.chart && (params.theme || params.styles?.variables)) {
461465
state.chart.destroy();
@@ -472,6 +476,9 @@ app.connect().then(() => {
472476
if (ctx?.styles?.variables) {
473477
applyHostStyleVariables(ctx.styles.variables);
474478
}
479+
if (ctx?.styles?.css?.fonts) {
480+
applyHostFonts(ctx.styles.css.fonts);
481+
}
475482
});
476483

477484
// Fetch data after connection

specification/draft/apps.mdx

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,11 @@ interface HostContext {
451451
styles?: {
452452
/** CSS variables for theming */
453453
variables?: Record<McpUiStyleVariableKey, string | undefined>;
454+
/** CSS blocks that apps can inject */
455+
css?: {
456+
/** CSS for font loading (@font-face rules or @import statements) */
457+
fonts?: string;
458+
};
454459
};
455460
/** How the UI is currently displayed */
456461
displayMode?: "inline" | "fullscreen" | "pip";
@@ -503,8 +508,11 @@ Example:
503508
"variables": {
504509
"--color-background-primary": "light-dark(#ffffff, #171717)",
505510
"--color-text-primary": "light-dark(#171717, #fafafa)",
506-
"--font-family-sans": "system-ui, sans-serif",
511+
"--font-sans": "Anthropic Sans, sans-serif",
507512
...
513+
},
514+
"css": {
515+
"fonts": "@font-face { font-family: \"Custom Font Name\"; src: url(\"https://...\"); }"
508516
}
509517
},
510518
"displayMode": "inline",
@@ -638,7 +646,46 @@ Example usage of standardized CSS variables:
638646
.container {
639647
background: var(--color-background-primary);
640648
color: var(--color-text-primary);
641-
font: var(--font-style-body);
649+
font-family: var(--font-sans);
650+
}
651+
```
652+
653+
#### Custom Fonts
654+
655+
Hosts can provide custom fonts via `styles.css.fonts`, which can contain `@font-face` rules for self-hosted fonts, `@import` statements for font services like Google Fonts, or both:
656+
657+
```typescript
658+
hostContext.styles.variables["--font-sans"] = '"Font Name", sans-serif';
659+
660+
// Self-hosted fonts
661+
hostContext.styles.css.fonts = `
662+
@font-face {
663+
font-family: "Font Name";
664+
src: url("https://url-where-font-is-hosted.com/.../Regular.otf") format("opentype");
665+
font-weight: 400;
666+
font-style: normal;
667+
font-display: swap;
668+
}
669+
@font-face {
670+
font-family: "Font Name";
671+
src: url("https://url-where-font-is-hosted.com/.../Medium.otf") format("opentype");
672+
font-weight: 500;
673+
font-style: medium;
674+
font-display: swap;
675+
}
676+
`;
677+
678+
// Google Fonts
679+
hostContext.styles.css.fonts = `
680+
@import url('https://fonts.googleapis.com/css2?family=Font+Name&display=swap');
681+
`;
682+
```
683+
684+
Apps can use the `applyHostFonts` utility to inject the font CSS into the document:
685+
686+
```typescript
687+
if (hostContext.styles?.css?.fonts) {
688+
applyHostFonts(hostContext.styles.css.fonts);
642689
}
643690
```
644691

src/app.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ export { PostMessageTransport } from "./message-transport";
5252
export * from "./types";
5353
export {
5454
applyHostStyleVariables,
55+
applyHostFonts,
5556
getDocumentTheme,
5657
applyDocumentTheme,
5758
} from "./styles";

src/generated/schema.json

Lines changed: 55 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/generated/schema.test.ts

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/generated/schema.ts

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/react/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
*
1111
* - {@link useApp} - React hook to create and connect an MCP App
1212
* - {@link useHostStyleVariables} - React hook to apply host style variables and theme
13+
* - {@link useHostFonts} - React hook to apply host fonts
1314
* - {@link useDocumentTheme} - React hook for reactive document theme
1415
* - {@link useAutoResize} - React hook for manual auto-resize control (rarely needed)
1516
*

0 commit comments

Comments
 (0)