google-fonts-mcp
Allows searching the Google Fonts catalogue, retrieving font metadata, previewing text in a chosen font as HTML, and generating HTML and CSS embed code for web pages.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@google-fonts-mcpFind me some popular monospace fonts"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
google-fonts-mcp
An MCP server that lets AI assistants search, inspect, preview and embed Google Fonts.
What it does
google-fonts-mcp connects Claude Desktop (or any MCP client) to the Google Fonts Web Fonts Developer API. It loads the full font catalogue once, sorted by popularity, caches it in memory, and answers from the cache after that. If you misspell a family name, it suggests the closest matches.
search_fonts: find families by name and/or category, most popular first.get_font_details: get a family's category, weights, variants, subsets, version and last-modified date.preview_text: render sample text in a font as a self-contained HTML page.get_embed_code: get the<link>tags and CSSfont-familydeclaration for a web page.
Related MCP server: Google Drive MCP Server
Examples
"Find me some popular monospace fonts."
Calls search_fonts with category: "monospace" and returns a numbered list:
Found 10 fonts matching category monospace:
1. Roboto Mono (monospace) - weights: 100, 200, 300, 400, 500, 600, 700
2. Source Code Pro (monospace) - weights: 200, 300, 400, 500, 600, 700, 800, 900
3. JetBrains Mono (monospace) - weights: 100, 200, 300, 400, 500, 600, 700, 800
..."Show me 'Hello, world' in Playfair Display, bold italic, at 64px."
Calls preview_text with family: "Playfair Display", text: "Hello, world", size: 64, weight: 700, italic: true. Returns a one-line summary plus a self-contained HTML page that loads just that style:
Preview of Playfair Display (serif) at 64px, weight 700 italic, colour #111111.If the family doesn't have that weight and style, you get the list of variants it does have.
"How do I add Inter at 400 and 600 to my site?"
Calls get_embed_code with family: "Inter", weights: [400, 600]:
Embed code for Inter (weights 400, 600):
HTML (place in <head>):
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap" rel="stylesheet">
CSS:
font-family: 'Inter', system-ui, -apple-system, 'Segoe UI', Helvetica, Arial, sans-serif;Results come from the live Google Fonts catalogue, so exact lists and weights may differ.
Installation
npx (recommended)
No install step. Your MCP client runs the server on demand:
npx -y google-fonts-mcpRequires Node.js 18 or later. See Configuration for the Claude Desktop setup.
From source
git clone https://github.com/Maxamed-Maxamed/google-fonts-mcp.git
cd google-fonts-mcp
npm install
npm run buildThe built server is dist/index.js.
Getting a Google Fonts API key
Go to console.cloud.google.com and sign in.
Create a project, or select an existing one, from the project picker in the top bar.
Open APIs & Services → Library, search for Web Fonts Developer API, and click Enable.
Open APIs & Services → Credentials, click Create credentials → API key, and copy the key.
Optional: click Edit API key and, under API restrictions, restrict it to the Web Fonts Developer API.
The key is read from the GOOGLE_FONTS_API_KEY environment variable. When running from source you can put it in a .env file instead:
cp .env.example .env
# then edit .env and set GOOGLE_FONTS_API_KEYConfiguration
Add the server to your claude_desktop_config.json:
OS | Config file path |
Windows |
|
macOS |
|
macOS
{
"mcpServers": {
"google-fonts": {
"command": "npx",
"args": ["-y", "google-fonts-mcp"],
"env": {
"GOOGLE_FONTS_API_KEY": "your_api_key_here"
}
}
}
}Windows
{
"mcpServers": {
"google-fonts": {
"command": "cmd",
"args": ["/c", "npx", "-y", "google-fonts-mcp"],
"env": {
"GOOGLE_FONTS_API_KEY": "your_api_key_here"
}
}
}
}Running a local build
Point node at the built file instead of using npx:
{
"mcpServers": {
"google-fonts": {
"command": "node",
"args": ["/absolute/path/to/google-fonts-mcp/dist/index.js"],
"env": {
"GOOGLE_FONTS_API_KEY": "your_api_key_here"
}
}
}
}On Windows, escape backslashes in the path (C:\\Users\\you\\google-fonts-mcp\\dist\\index.js) or use forward slashes.
Restart Claude Desktop after editing the config.
Tool reference
Family names are matched case-insensitively. If no family matches, the error lists up to five close matches.
search_fonts
Search families by name and/or category. Results are sorted by popularity. Provide at least one of query or category.
Parameter | Type | Required | Default | Description |
| string | No | — | Case-insensitive text to match anywhere in the family name |
| string | No | — | One of |
| number | No |
| Maximum results, integer from 1 to 50. Values above 50 are capped at 50 |
Returns a numbered list of families with their category and available weights.
get_font_details
Get full metadata for one family.
Parameter | Type | Required | Default | Description |
| string | Yes | — | Exact family name, e.g. |
Returns the category, weights, variants, subsets, version and last-modified date.
preview_text
Render sample text in a font. The weight and italic combination must exist in the family.
Parameter | Type | Required | Default | Description |
| string | Yes | — | Family name, e.g. |
| string | No |
| Sample text to render |
| number | No |
| Font size in pixels, 8 to 200 |
| number | No |
| Font weight as an integer, e.g. |
| boolean | No |
| Render in italic |
| string | No |
| Hex ( |
Returns a summary line and a self-contained HTML page. The page loads only the requested style from the Google Fonts CSS API, and the sample text is HTML-escaped.
get_embed_code
Get the HTML and CSS needed to use a family on a web page.
Parameter | Type | Required | Default | Description |
| string | Yes | — | Family name, e.g. |
| number[] | No |
| Upright weights to load, as integers. Duplicates are removed |
Returns preconnect and stylesheet <link> tags plus a font-family declaration with a fallback stack that matches the font's category. If any requested weight is missing, the error lists the weights the family has.
Development
Project structure
google-fonts-mcp/
├── src/
│ ├── index.ts # MCP server: tool definitions, argument validation, handlers
│ ├── fonts.ts # Google Fonts API client, caching, search and fuzzy matching
│ └── preview.ts # Variant helpers, CSS2 URL builder, fallback stacks, HTML preview
├── dist/ # Compiled output (generated by npm run build)
├── .env.example # Template for GOOGLE_FONTS_API_KEY
├── package.json
└── tsconfig.jsonnpm scripts
Script | Command | What it does |
|
| Compile |
|
| Recompile on every change |
|
| Run the server on stdio |
Testing
There is no automated test suite yet. Test the tools interactively with the MCP Inspector:
npm run build
npx @modelcontextprotocol/inspector node dist/index.jsThe server loads .env automatically, so set your key there first. In the Inspector, open Tools, click List Tools, and call each tool with sample arguments.
Things worth checking after a change:
A misspelled family (e.g.
"Robotto") returns suggestions.preview_textwith a weight the family lacks returns the available variants.get_embed_codewith a missing weight returns the available weights.Starting without
GOOGLE_FONTS_API_KEYlogs a warning, and tool calls return a clear error.
The server writes logs to stderr because stdout carries the MCP protocol. Don't add console.log calls.
Contributing
Fork the repo and create a branch from
main.Make your change and run
npm run buildto make sure it compiles.Test the affected tools with the MCP Inspector.
Open a pull request that describes the change and how you tested it.
Bug reports and feature requests go in GitHub Issues.
License
MIT © Maxamed Maxamed
Available Tools
4 toolsget_embed_codeB
Get the HTML link tags and CSS font-family declaration to use a Google Font on a web page.
| Name | Required | Description | Default |
|---|---|---|---|
| family | Yes | Family name, case-insensitive (e.g. "Open Sans") | |
| weights | No | Upright weights to load, e.g. [400, 700] |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It discloses that the tool returns 'HTML link tags and CSS font-family declaration' which gives some behavioral insight into what the tool produces. However, it doesn't mention any side effects (likely none), performance characteristics, or error conditions, but for a seemingly read-only operation, this is adequate. No contradiction with annotations since none exist.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence that conveys the core purpose efficiently. It doesn't waste words, and it front-loads the key action ('Get the HTML link tags and CSS font-family declaration'). It could be slightly more detailed, but it's concise and well-structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple tool with two parameters and no output schema, the description is reasonably complete. It tells the agent what it returns and for what purpose. However, without annotations, it lacks explicit guidance on error handling, network dependencies, or whether the tool works offline, but those are minor gaps. The description is adequate for an agent to call the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents both parameters (family and weights). The description adds minimal extra meaning beyond that; it implies the parameters are used to generate the embed code but doesn't add syntax or format details beyond the schema. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: it returns HTML link tags and CSS font-family declarations for using a Google Font. It specifies the resource (Google Font) and the output type (HTML/CSS), which distinguishes it from siblings like search_fonts and get_font_details. However, it doesn't explicitly differentiate itself from preview_text, though the purpose is clear enough.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the usage scenario (when you need embed code for a font) but doesn't explicitly state when to use this tool over alternatives. It doesn't provide exclusions or alternatives. The context is clear but not explicit, so it gets a 3.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_font_detailsA
Get full metadata for a Google Fonts family: category, variants, subsets, version and last modified date.
| Name | Required | Description | Default |
|---|---|---|---|
| family | Yes | Exact family name, case-insensitive (e.g. "Open Sans") |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are present, so the description carries the full burden. It discloses what information is returned (category, variants, subsets, etc.) and implies a safe read operation via 'Get'. However, it does not mention response structure, error behavior, or any rate limits, which leaves some behavioral gaps for a tool with zero annotation coverage.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single sentence that front-loads the action ('Get full metadata') and then lists specific fields. Every word earns its place; there is no filler or repetition of schema information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple one-parameter read tool, the description covers the core purpose and return data. It lacks an explicit output format (e.g., JSON object), but the field list is a reasonable substitute given the straightforward nature of the tool and the absence of complex requirements.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the schema already explains the 'family' parameter with an example and case-insensitivity. The description adds context about the resource type (Google Fonts) but does not add meaningful parameter semantics beyond the schema, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description states a specific verb ('Get') and resource ('full metadata for a Google Fonts family'), and enumerates the specific data fields returned (category, variants, subsets, version, last modified date). This clearly distinguishes it from siblings like search_fonts and get_embed_code.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description makes clear when to use this tool: when you need full metadata for a specific font family. It does not explicitly name alternatives or state when not to use it, but the context is unambiguous enough that an agent can infer the choice between this and search_fonts.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
preview_textA
Render sample text in a Google Font. Returns a self-contained HTML page. The weight/italic combination must exist in the family.
| Name | Required | Description | Default |
|---|---|---|---|
| size | No | Font size in pixels (8-200) | |
| text | No | Sample text to render | The quick brown fox jumps over the lazy dog |
| colour | No | Text colour: hex (e.g. "#1a1a1a"), a CSS colour name, or rgb()/hsl() | #111111 |
| family | Yes | Family name, case-insensitive (e.g. "Open Sans") | |
| italic | No | Render in italic | |
| weight | No | Font weight, e.g. 400 or 700 |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the behavioral transparency burden. It usefully discloses that the tool returns a self-contained HTML page and that the weight/italic combination must exist in the family, which informs expected behavior and failure conditions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with no filler. The primary purpose is stated first, the output type second, and the critical constraint third. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a relatively simple rendering tool with fully documented parameters, the description is adequate. It explains what is returned and the key validity constraint. It could be more complete by mentioning what happens if the font or weight/italic combination is not found, but no critical information needed to attempt a call is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds semantic value beyond the schema by highlighting that weight and italic are not independent choices but must correspond to an actual combination available in the specified family.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource: 'Render sample text in a Google Font.' It also states the output type ('self-contained HTML page'), making it clearly distinct from sibling tools like search_fonts or get_font_details.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly implies this tool is for previewing how text looks in a font, and the 'must exist in the family' note adds a usage constraint. However, it does not explicitly compare with alternatives or state when to prefer this over search_fonts or get_font_details.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_fontsA
Search Google Fonts by family name and/or category. Results are sorted by popularity. Provide at least one of query or category.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of results (default 10, max 50) | |
| query | No | Case-insensitive text to match in the family name | |
| category | No | Only return fonts in this category |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the behavioral burden itself. It adds value beyond the schema by stating that results are sorted by popularity and that at least one search criterion is required. It does not spell out the result shape, but for a read-only search tool that is a minor omission.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short, purposeful sentences with no filler. Every sentence contributes either the operation, a behavioral detail, or a usage constraint.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only search with fully documented parameters, the description is mostly complete: it covers search dimensions, sort order, and the minimum-input rule. The only real gap is not describing the return format, but the absence of an output schema makes this a minor, not critical, omission.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already describes each parameter, so the baseline is 3. The description earns a 4 by adding a key inter-parameter constraint: query and category can be used together or alone, but at least one is mandatory. This is not encoded in the required-parameters list, making it genuinely useful.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb ('Search'), resource ('Google Fonts'), and criteria ('family name and/or category'). This clearly distinguishes search_fonts from sibling tools like get_font_details, preview_text, and get_embed_code.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It clearly states the input requirement that at least one of query or category must be provided, which is useful. However, it does not explicitly say when to prefer this tool over its siblings or when not to use it, so routing guidance is only implied by the tool's purpose.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
4 tool updates
v0.1.0- First observed
get_embed_code - First observed
get_font_details - First observed
preview_text - First observed
search_fonts
TDQS
Scored across 4 tools
Each tool has a clearly distinct role: finding fonts, inspecting metadata, previewing text, and generating embed code. There is no functional overlap between any of the tools.
All tool names follow a consistent verb_noun snake_case pattern: search_fonts, get_font_details, preview_text, get_embed_code. This makes the toolset predictable and easy to navigate.
Four tools is well-scoped for a Google Fonts MCP server. Each tool covers a distinct stage in the font selection and integration workflow without redundancy.
The toolset covers the full practical lifecycle: discovering fonts, examining their metadata, previewing custom text, and obtaining integration code. No critical workflow is missing for typical font lookup and embedding use cases.
Maintenance
Related MCP Connectors
MCP server for Google Veo AI video generation
Use AI models for chat, image, and video generation from Claude Code and other MCP hosts.
MCP server for AI dialogue using various LLM models via AceDataCloud
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceAn MCP (Model Context Protocol) server that provides Google search capabilities and webpage content analysis tools. This server enables AI models to perform Google searches and analyze webpage content programmatically.17 npm256ISC
- AlicenseNot gradedqualityDmaintenanceA server that provides a Machine Control Protocol (MCP) interface to search, access, and interact with Google Drive files and folders, enabling AI assistants to work with Google Drive content.8MIT
- AlicenseAqualityAmaintenanceMCP server for searching Google Fonts and generating complete CSS/Tailwind typographic systems with font pairings and modular scales.582 PyPI14MIT
- AlicenseAqualityDmaintenanceA unified MCP server for Glyphs font design software, integrating handbook queries and API reference lookups. Enables searching documentation, managing plugins, and accessing development templates through Claude.25MIT