-
Notifications
You must be signed in to change notification settings - Fork 49
[MCP Apps] Add way to pass custom fonts #159
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -409,6 +409,11 @@ interface HostContext { | |
| styles?: { | ||
| /** CSS variables for theming */ | ||
| variables?: Record<McpUiStyleVariableKey, string | undefined>; | ||
| /** CSS blocks that apps can inject */ | ||
| css?: { | ||
| /** CSS for font loading (@font-face rules or @import statements) */ | ||
| fonts?: string; | ||
| }; | ||
| }; | ||
| /** How the UI is currently displayed */ | ||
| displayMode?: "inline" | "fullscreen" | "pip"; | ||
|
|
@@ -461,8 +466,11 @@ Example: | |
| "variables": { | ||
| "--color-background-primary": "light-dark(#ffffff, #171717)", | ||
| "--color-text-primary": "light-dark(#171717, #fafafa)", | ||
| "--font-family-sans": "system-ui, sans-serif", | ||
| "--font-sans": "Anthropic Sans, sans-serif", | ||
| ... | ||
| }, | ||
| "css": { | ||
| "fonts": "@font-face { font-family: \"Custom Font Name\"; src: url(\"https://...\"); }" | ||
| } | ||
| }, | ||
| "displayMode": "inline", | ||
|
|
@@ -596,7 +604,46 @@ Example usage of standardized CSS variables: | |
| .container { | ||
| background: var(--color-background-primary); | ||
| color: var(--color-text-primary); | ||
| font: var(--font-style-body); | ||
| font-family: var(--font-sans); | ||
| } | ||
| ``` | ||
|
|
||
| #### Custom Fonts | ||
|
|
||
| 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: | ||
|
|
||
| ```typescript | ||
| hostContext.styles.variables["--font-sans"] = '"Font Name", sans-serif'; | ||
|
|
||
| // Self-hosted fonts | ||
| hostContext.styles.css.fonts = ` | ||
| @font-face { | ||
| font-family: "Font Name"; | ||
| src: url("https://url-where-font-is-hosted.com/.../Regular.otf") format("opentype"); | ||
| font-weight: 400; | ||
| font-style: normal; | ||
| font-display: swap; | ||
| } | ||
| @font-face { | ||
| font-family: "Font Name"; | ||
| src: url("https://url-where-font-is-hosted.com/.../Medium.otf") format("opentype"); | ||
| font-weight: 500; | ||
| font-style: medium; | ||
| font-display: swap; | ||
| } | ||
| `; | ||
|
|
||
| // Google Fonts | ||
| hostContext.styles.css.fonts = ` | ||
| @import url('https://fonts.googleapis.com/css2?family=Font+Name&display=swap'); | ||
| `; | ||
| ``` | ||
|
|
||
| Apps can use the `applyHostFonts` utility to inject the font CSS into the document: | ||
|
|
||
| ```typescript | ||
| if (hostContext.styles?.css?.fonts) { | ||
| applyHostFonts(hostContext.styles.css.fonts); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we want to refer to specific implementations in the abstract spec itself?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wdym refer to specific implementations? I have more specific examples of how hosts can specify font files elsewhere in this file already if that's what you're asking! |
||
| } | ||
| ``` | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not conceptually different than having an arbitrary css chunk that can be injected, which we didn't want to introduce.
Perhaps we need to make it more restricted somehow?
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes this was considered, but I think it's worth it b/c this is the most ergonomic and flexible approach by far. Also, the host can already just inject arbitrary css directly into the app HTML anyways. So this doesn't change the "security" at all. We kind of have to trust hosts b/c they're already hosting the app and could do any number of things to it