MCPcopy
hub / github.com/majodev/google-webfonts-helper

github.com/majodev/google-webfonts-helper @v1.7.1 sqlite

repository ↗ · DeepWiki ↗ · release v1.7.1 ↗
47 symbols 127 edges 27 files 0 documented · 0%
README

google-webfonts-helper Uptime Robot status Uptime Robot ratio (30 days) GitHub Sponsors

A Hassle-Free Way to Self-Host Google Fonts

https://gwfh.mranftl.com

Current Sponsors

Help me keep this service alive by sponsoring me. Thank you. ❤️

ToC

Give it a try: https://gwfh.mranftl.com

This service might be handy if you want to host a specific Google font on your own server: * font style and charset customization * CSS snippets * .eot, .woff, .woff2, .svg, .ttf font file formats download (zipped).

pic running

Running gwfh on your own server

I provide prebuilt Docker images via GitHub Packages. You can use them as follows:

# See https://developers.google.com/fonts/docs/developer_api for creating your own API-Key.

docker run -e GOOGLE_FONTS_API_KEY=<YOUR-API-KEY> -p 8080:8080 ghcr.io/majodev/google-webfonts-helper:<TAG>
# Express server listening on 8080, in production mode

Development

Quickstart

Do this to setup a development environment:

# Ensure to set the GOOGLE_FONTS_API_KEY env var inside your own gitignored .env file
# See https://developers.google.com/fonts/docs/developer_api for creating your own API-Key.
echo "GOOGLE_FONTS_API_KEY=<YOUR-API-KEY>" > .env

# Start up the development docker container (multistage Dockerfile, stage 1 only)
./docker-helper.sh --up
# [+] Running 1/0
#  ⠿ Container gwfh-service-1  Running
# node@3b506a285f7f:/app$

# within this development container:
node$ yarn --pure-lockfile
node$ ./node_modules/.bin/bower install

# start development server
node$ grunt serve
# [...]
# Express server listening on 9000, in development mode

# The application is now available at http://127.0.0.1:9000 (watching for code changes)

# start production server (same command as within the final docker multistage build)
node$ grunt build
node$ NODE_ENV=production node dist/server/app.js
# Express server listening on 8080, in production mode

Production build

If you want to build and run your own production container locally:

# Build the production docker container (final stage)
docker build . -t <your-image-tag>

# Run it (if you have previously started the development container, halt it!)
./docker-helper.sh --halt
docker run -e GOOGLE_FONTS_API_KEY=<YOUR-API-KEY> -p 8080:8080 <your-image-tag>
# Express server listening on 8080, in production mode

To mitigate security issues especially with the projects' deprecated dependencies, the final image is based on a minimal container image. It runs rootless and has no development dependencies.

JSON API

The API is public, feel free to use it directly (rate-limits may apply).

GET /api/fonts

Returns a list of all fonts, sorted by popularity. E.g. curl https://gwfh.mranftl.com/api/fonts:

[{
  "id": "open-sans",
  "family": "Open Sans",
  "variants": ["300", "300italic", "regular", "italic", "600", "600italic", "700", "700italic", "800", "800italic"],
  "subsets": ["devanagari", "greek", "latin", "cyrillic-ext", "cyrillic", "greek-ext", "vietnamese", "latin-ext"],
  "category": "sans-serif",
  "version": "v10",
  "lastModified": "2014-10-17",
  "popularity": 1,
  "defSubset": "latin",
  "defVariant": "regular"
} [...]
]

GET /api/fonts/[id]?subsets=latin,latin-ext

Returns a font with urls to the actual font files google's servers. subsets is optional (will serve the defSubset if unspecified). E.g. curl "https://gwfh.mranftl.com/api/fonts/modern-antiqua?subsets=latin,latin-ext" (the double quotes are important as query parameters may else be stripped!):

{
  "id": "modern-antiqua",
  "family": "Modern Antiqua",
  "variants": [{
    "id": "regular",
    "eot": "https://fonts.gstatic.com/s/modernantiqua/v6/8qX_tr6Xzy4t9fvZDXPkhzThM-TJeMvVB0dIsYy4U7E.eot",
    "fontFamily": "'Modern Antiqua'",
    "fontStyle": "normal",
    "fontWeight": "400",
    "woff": "https://fonts.gstatic.com/s/modernantiqua/v6/8qX_tr6Xzy4t9fvZDXPkh1bbnkJREviNM815YSrb1io.woff",
    "local": ["Modern Antiqua Regular", "ModernAntiqua-Regular"],
    "ttf": "https://fonts.gstatic.com/s/modernantiqua/v6/8qX_tr6Xzy4t9fvZDXPkhxr_S_FdaWWVbb1LgBbjq4o.ttf",
    "svg": "https://fonts.gstatic.com/l/font?kit=8qX_tr6Xzy4t9fvZDXPkh0sAoW0rAsWAgyWthbXBUKs#ModernAntiqua",
    "woff2": "https://fonts.gstatic.com/s/modernantiqua/v6/8qX_tr6Xzy4t9fvZDXPkh08GHjg64nS_BBLu6wRo0k8.woff2"
  }],
  "subsets": ["latin", "latin-ext"],
  "category": "display",
  "version": "v6",
  "lastModified": "2014-08-28",
  "popularity": 522,
  "defSubset": "latin",
  "defVariant": "regular",
  "subsetMap": {
    "latin": true,
    "latin-ext": true
  },
  "storeID": "latin-ext_latin"
}

GET /api/fonts/[id]?download=zip&subsets=latin&formats=woff,woff2&variants=regular

Download a zipped archive with all .eot, .woff, .woff2, .svg, .ttf files of a specified font. The query parameters formats and variants are optional (includes everything if no filtering is applied). is E.g. curl -o fontfiles.zip "https://gwfh.mranftl.com/api/fonts/lato?download=zip&subsets=latin,latin-ext&variants=regular,700&formats=woff" (the double quotes are important as query parameters may else be stripped!)

History

2025:

  • Switch to node:22 for the final image.
  • Adds support for linux/arm64 architecture (patches [imagemin/optipng-bin](https://github.com/imagemin/optipng-

Extension points exported contracts — how you extend this code

IUserAgents (Interface)
(no doc)
server/config.ts
IFontSubsetArchive (Interface)
(no doc)
server/logic/fetchFontSubsetArchive.ts
IAPIListFont (Interface)
(no doc)
server/api/fonts.controller.ts
IFontFile (Interface)
(no doc)
server/logic/fetchFontSubsetArchive.ts
IAPIFont (Interface)
(no doc)
server/api/fonts.controller.ts
IFontItem (Interface)
(no doc)
server/logic/fetchGoogleFonts.ts
IGoogleFontsRes (Interface)
(no doc)
server/logic/fetchGoogleFonts.ts
IGoogleFontsResItem (Interface)
(no doc)
server/logic/fetchGoogleFonts.ts

Core symbols most depended-on inside this repo

getStats
called by 29
server/logic/store.ts
asyncRetry
called by 6
server/utils/asyncRetry.ts
getCSSRuleDeclarationPropertyValue
called by 5
server/logic/fetchCSS.ts
reinitStore
called by 3
server/logic/store.ts
apiError
called by 2
client/app/fonts/fonts.controller.js
setCustomizationReloadMessage
called by 2
client/app/fonts/fonts.controller.js
synchronizedBy
called by 2
server/utils/synchronized.ts
transform
called by 2
server/logic/fetchGoogleFonts.ts

Shape

Function 34
Interface 13

Languages

TypeScript100%

Modules by API surface

server/logic/store.ts10 symbols
server/logic/core.ts6 symbols
server/logic/fetchGoogleFonts.ts5 symbols
server/api/fonts.controller.ts5 symbols
server/logic/fetchFontSubsetArchive.ts4 symbols
server/logic/fetchCSS.ts4 symbols
server/utils/synchronized.ts3 symbols
server/logic/fetchFontURLs.ts3 symbols
client/app/fonts/fonts.controller.js2 symbols
server/utils/asyncRetry.ts1 symbols
server/routes.ts1 symbols
server/config.ts1 symbols

Dependencies from manifests, versioned

@types/async3.2.16 · 1×
@types/bluebird3.5.38 · 1×
@types/css0.0.33 · 1×
@types/express4.17.17 · 1×
@types/lodash4.14.191 · 1×
@types/mocha10.0.1 · 1×
@types/node18 · 1×
@types/speakingurl13.0.3 · 1×
@types/supertest2.0.12 · 1×
@typescript-eslint/eslint-plugin5.52.0 · 1×
@typescript-eslint/parser5.52.0 · 1×
axios1.12.2 · 1×

For agents

$ claude mcp add google-webfonts-helper \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact