themeseed
Provides tools for analyzing a Ghost theme, generating and publishing realistic demo content (posts, feature images, galleries, video embeds) to a Ghost CMS, and removing the generated content.
Allows the MCP server to search for and embed YouTube videos into generated posts, respecting the theme's video embed capabilities.
Click on "Install 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., "@themeseedseed my blog with realistic demo content matching its theme"
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.
themeseed
Fill a CMS with realistic demo content so you can judge a theme against real-looking articles — instead of an empty install, a "Coming soon" placeholder, or a wall of lorem ipsum.
themeseed reads the active theme first, works out what it can actually display, and then generates content that fits: hero images at the theme's own aspect ratio, galleries only where the theme has gallery styles, real embedded videos only where it has embed styles, and articles long enough to fill the layout the designer built.
It ships as both an MCP server (drive it from Claude Code, Cursor, Windsurf, Claude Desktop, VS Code, Zed…) and a CLI.
themeseed add-site --slug blog --url http://localhost:2368
themeseed analyze blog # what can this theme display?
themeseed seed blog -t "SaaS productivity blog" -c 15
themeseed wipe blog # remove exactly what it createdContents
Related MCP server: wp-cli-mcp
Why
Evaluating a theme against an empty site tells you almost nothing. The hero looks fine because there is no hero. The archive grid looks tidy because there are three posts. The typography looks great for 200 words and falls apart at 1,500.
Filling the site by hand is an hour of work you throw away. Filling it with lorem ipsum tells you about the typography and nothing about the layout, because lorem ipsum has no headings, no images, no galleries, no pull quotes and no embeds.
themeseed produces content shaped like the real thing — and shaped like this theme's real thing, because it reads the theme before it writes anything.
Install
themeseed is published to IndiaNIC's private registry. Point the @indianic scope at it once:
npm config set @indianic:registry https://npm.indianic.in/
npm login --registry https://npm.indianic.in/ --scope @indianicThen install globally:
npm install -g @indianic/themeseedOr run it without installing:
npx @indianic/themeseed initNode 20 or newer is required.
Registry note. The public-npm / public-GitHub story is still undecided — see Open questions. Today this package exists only on
npm.indianic.in.
Quick start
themeseed initinit does three things:
Detects MCP-capable tools installed on your machine.
Asks which of them to register the themeseed MCP server with, and writes each one's config in its own native format (merging, never replacing).
Offers to add your first site.
Adding a site verifies the credentials before saving them, so a bad key fails immediately rather than half way through a seed run.
$ themeseed analyze blog
bohomian v1.0.0
Bohomian — a quiet, Scandinavian Ghost theme.
feature image yes (ratio ≈ 1.33)
gallery card yes
video embed yes
bookmark card yes
wide images yes
shows tags yes
shows author yes (with avatar)
reading time yes
target length ~1400 words (910–2030)
posts per page 12
confidence 0.95 via local-theme-files, rendered-siteThen fill it:
$ themeseed seed blog -t "SaaS productivity blog" -c 15
✔ Created 15 of 15 post(s) on "blog"
theme bohomian
feature images 15
inline images 5
galleries 5
video embeds 5Every post is tagged #themeseed (an internal, non-public tag on Ghost), which is how
themeseed wipe removes exactly this content and nothing else.
CLI reference
themeseed uses commander for argument parsing and @clack/prompts for interactive input. Prompts degrade to plain line output when stdout is not a TTY, so piping and CI logs stay readable.
Setup
Command | What it does |
| First-run setup: detect editors, register the MCP server, add a site |
| Register the MCP server with an editor, without the full init flow |
| Remove the MCP server from editor configuration |
| Print the JSON snippet for manual configuration |
| Check the registry for a newer version and install it |
| Print the installed version |
| Show help (also |
Sites
Command | What it does |
| Register a CMS. Verifies credentials before saving |
| Forget a site. Deletes no content |
| List configured sites (never prints credentials) |
| Set the default site used when no slug is given |
add-site accepts --slug, --platform, --url, --key and --themes-dir for scripting.
Prefer the interactive prompt for the key: a credential passed as a flag lands in your shell
history and in ps output.
Content
Command | What it does |
| Report what the active theme can display, with evidence |
| Generate and publish content that suits the theme |
| List content themeseed created |
| Delete everything themeseed created |
seed options:
Flag | Default | Meaning |
| prompted | What the publication is about |
|
| How many posts to create |
|
|
|
| off | Create drafts instead of published posts |
| — | Author to attribute posts to |
| off | Skip YouTube lookups (faster, fully offline) |
| topic hash | Seed the generator for reproducible output |
| off | Skip the confirmation prompt |
MCP tools
Run themeseed install to register the server, or add it by hand:
{
"mcpServers": {
"themeseed": {
"command": "npx",
"args": ["-y", "--package", "@indianic/themeseed", "themeseed-mcp"],
"env": { "npm_config_registry": "https://npm.indianic.in/" }
}
}
}VS Code nests servers under servers rather than mcpServers; Zed calls them
context_servers. themeseed install handles each format for you.
Tool | Parameters | What it does |
|
| Reports theme capabilities, with evidence and a confidence score |
|
| Analyzes, generates, sources images, publishes |
|
| Lists everything themeseed created |
|
| Deletes it. Defaults to a dry run — |
|
| Registers a site, verifying credentials first |
| — | Lists sites. Never returns credentials |
|
| Forgets a site |
Tip: pass your own headlines to generate_posts via titles. The built-in engine writes
serviceable copy, but a model that knows the client's voice writes better copy — this lets it
supply the words while themeseed handles structure, images, capability-gating and publishing.
How theme analysis works
This is the part that makes the output fit rather than merely exist.
Ghost's Admin API will not serve theme files: GET /ghost/api/admin/themes/ returns
403 NoPermissionError for API-token auth on every Ghost version, because it requires a staff
session. So themeseed uses two strategies and merges them.
1. Local theme files (confidence 0.9) — when Ghost runs on this machine and you point
--themes-dir at content/themes. Reads the active theme's .hbs templates, package.json
and compiled CSS. This is as close to ground truth as it gets: card_assets: true proves every
Koenig card is styled; {{#if feature_image}} proves the hero is rendered; a table-of-contents
partial proves the theme expects long articles.
2. The rendered site (confidence 0.6) — always available, including Ghost(Pro) and any
remote install. The trick: a theme's own stylesheet is a public asset. Fetching it and looking
for kg-gallery-container, kg-embed-card, kg-width-wide answers the card questions with
real evidence rather than assumption. The rendered post page supplies the rest — hero, tags,
author avatar, reading time.
The higher-confidence strategy wins any contested field; the lower one fills what nobody else measured. Anything still unmeasured falls back to conservative defaults and lowers the reported confidence, so a low number means "we guessed", not "the theme is limited".
Which theme is active comes from GET /ghost/api/admin/settings/ (active_theme), which
API tokens may read.
Every conclusion is recorded in evidence[]:
- [local-theme-files] package.json config.card_assets enables Ghost card styles for all cards
- [local-theme-files] feature image aspect-ratio ≈ 1.33 (most common of the ratios attached to
feature images; 3 occurrence(s), via class)
- [rendered-site] card selectors in served CSS — gallery:true embed:true bookmark:true wide:trueWhy capability-gating matters
A gallery card in a theme with no gallery styles renders as a broken-looking stack of images. That is worse than the plain post it replaced, because it makes a good theme look buggy. themeseed only emits a block when the theme was measured to support it.
Image sources
One interface, three interchangeable implementations, selected with --image-source.
local
Scans a directory (THEMESEED_LOCAL_IMAGE_DIR) and picks files whose aspect ratio is closest to
what the theme wants. Fully offline and reproducible. Descriptive filenames become alt text;
camera filenames like IMG_4821 are rejected in favour of the query, because bad alt text is
worse than generic alt text.
stock
Adapter | Key | Query-relevant? |
|
| yes |
|
| yes |
| none | no — real photos, but random |
Picks whichever key is present, else falls back to Lorem Picsum so the zero-config path still
works. Picsum returns genuine photographs at the right dimensions, which is enough to judge a
theme's layout, and useless for judging whether images match the copy — so every image it
returns carries a credit saying exactly that. Set THEMESEED_STOCK_PROVIDER to force one.
ai
Adapter | Key | Default model | Actually AI? |
|
|
| yes |
|
|
| yes |
|
|
| yes |
|
|
| yes |
| none | — | no |
Whichever key is present is used; THEMESEED_AI_IMAGE_ADAPTER forces one and
THEMESEED_AI_IMAGE_MODEL overrides the model. Each backend asks for output shape
differently — aspect_ratio, imageConfig.aspectRatio, named size presets — so themeseed
snaps the theme's measured ratio onto whatever that backend supports and the generator only
ever asks for a number.
Two things worth knowing before picking one:
Gemini image models require billing enabled on the project. Without it every call returns
429 RESOURCE_EXHAUSTEDimmediately, which reads like a rate limit that will clear on its own. It will not.fal keys are
<id>:<secret>, sent asAuthorization: Key …rather thanBearer.
procedural renders deterministic abstract artwork locally — gradients and soft geometry, no
network, no key. It exists so --image-source ai still produces valid, correctly-sized images
out of the box and so the integration tests are hermetic. It is not AI, and every image it
produces says so in its credit line.
Check what actually works on your machine, one image per configured adapter:
npx tsx scripts/probe-ai-adapters.ts --ratio 1.5Adding a backend (Replicate, Stability, a local diffusion server) means implementing
AiImageAdapter and adding one line to selectAiAdapter — see src/images/ai-source.ts.
Validation
Every image is parsed before upload. Stock APIs and CDNs return HTML error pages with image URLs often enough that uploading unverified bytes reliably produces posts full of broken images, so bytes that are not a decodable PNG/JPEG/GIF/WebP/AVIF are dropped with a warning.
Content generation
The default engine is deterministic, offline and free. It composes each paragraph from a claim, an elaboration and usually an example or caveat, drawn from rotating decks so a 1,400-word article does not visibly repeat. Titles cycle through five article shapes — guide, listicle, opinion, case study, explainer — so a batch of fifteen looks like a real publication's archive rather than fifteen variations of one headline.
It is not trying to write good essays. It is trying to produce headings, paragraph rhythm, article length, pull quotes, lists and images that stress a layout the way real content will.
Two ways to get better prose without touching the code:
Pass
titles(MCP) or use your own copy — the host model writes, themeseed structures.Implement
ContentEngine(src/content/engine.ts) and pass it togenerateSeedContent.
Videos are always real. themeseed searches YouTube, then confirms each candidate through the public oEmbed endpoint — which only answers for videos that exist and permit embedding — and takes the title, author and thumbnail from that response. A fabricated video ID renders as "Video unavailable", which looks like a broken theme, so ids are never invented.
Supported platforms
Platform | Status |
Ghost | ✅ Supported — Admin API, Lexical, image upload, theme analysis |
WordPress | 📋 Planned — contributions welcome |
Joomla | 📋 Planned — contributions welcome |
Drupal | 📋 Planned — contributions welcome |
Magento | 📋 Planned — contributions welcome |
Adding one is a self-contained job: implement CmsProvider, register it, add tests. Nothing in
the content generator, image sources, CLI or MCP tools needs to change. See
CONTRIBUTING.md.
Configuration
Sites live in ~/.themeseed/sites.json, written 0600, never inside a repository:
{
"version": 1,
"defaultSite": "blog",
"sites": {
"blog": {
"platform": "ghost",
"url": "http://localhost:2368",
"credentials": { "adminApiKey": "<id>:<secret>" },
"options": { "themesDir": "/path/to/ghost/content/themes" }
}
}
}Get a Ghost Admin API key from Ghost Admin → Settings → Integrations → Add custom integration. It is the key with a colon in it — the Content API key will not work.
Environment variables (all optional) are documented in .env.example.
THEMESEED_LOG_LEVEL=debug turns on verbose diagnostics; all logging goes to stderr, because
stdout belongs to the MCP protocol.
Architecture
src/
core/types.ts platform-neutral domain model — the contract everything shares
core/seed.ts analyze → generate → publish, used by both CLI and MCP
providers/provider.ts the CmsProvider interface
providers/registry.ts platform name → implementation (one line per platform)
providers/ghost/ the only place Ghost's vocabulary exists
content/generator.ts topic + capabilities → neutral blocks
content/engine.ts prose, behind a swappable interface
images/ local | stock | ai, behind one ImageSource interface
mcp/ MCP server and tools
cli/ commander + clackTwo rules hold the whole thing together:
Nothing outside
src/providers/<platform>/may import that platform's types. Shared code talks only toCmsProvider.The generator emits neutral blocks, never a CMS storage format. Conversion to Ghost's Lexical happens only in
src/providers/ghost/lexical.ts. This is what makes WordPress support a provider-only change rather than a rewrite.
Development
npm install
cp .env.example .env # point GHOST_TEST_BLOG_* at a disposable Ghost
npm run verify # typecheck + lint + unit tests
npm run test:e2e # integration tests against the real instance
npm run test:loop # the autonomous seed/verify/wipe loopnpm run test:loop seeds 15 posts, verifies them by reading back through Ghost's own Admin API
(deliberately not through themeseed's listSeeded, so a bug affecting both cannot hide), and
repeats until three consecutive clean runs, then wipes and confirms zero. Each iteration is
appended to test-loop.log.
Handy probes, none of which are part of the test suite:
npx tsx scripts/probe-theme.ts --themes-dir /path/to/content/themes
npx tsx scripts/probe-images.ts
npx tsx scripts/probe-video.ts "deep work"
npm run build && npx tsx scripts/probe-mcp.tsOpen questions
Three decisions are deliberately not settled in code. See OPEN-QUESTIONS.md for the full trade-offs.
License — currently MIT, provisionally. Confirm MIT vs Apache-2.0.
Distribution — private to
npm.indianic.in, or also public npm/GitHub under a public org.Stock image provider — standardise on Unsplash, Pexels, both, or keep all three.
License
MIT — see LICENSE. Provisional pending the decision above.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- Alicense-qualityDmaintenanceA comprehensive MCP server for WordPress automation that enables users to manage content, themes, and site configurations using AI-driven workflows and the WordPress REST API. It provides a wide array of tools for site planning, management, and optimization compatible with tools like Cursor and Claude.371ISC
- AlicenseBqualityDmaintenanceMCP server that gives AI tools full WordPress management via WP-CLI. 30+ tools for themes, plugins, posts, menus, users, database, scaffolding, and cache. Works locally or over SSH.34124MIT
- Alicense-qualityBmaintenanceOpen-source MCP server that turns any CMS backend into an AI-agent-ready content management system. It provides tools for content CRUD, idea management, and publication tracking, with safety features requiring human approval for publishing.MIT
- Alicense-qualityDmaintenanceMCP server for WordPress content management that provides a secure interface for AI assistants to interact with WordPress sites, enabling content creation, editing, and media management without destructive operations.MIT
Related MCP Connectors
WordPress MCP server: publish posts, AI images, SEO and full site management, self-hosted
WordPress MCP server: generate SEO posts, AI images, autoblog & WooCommerce on your self-hosted site
Security-first WordPress MCP server. 129 tools for Claude, ChatGPT, Gemini. Free on wp.org.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/ThemeAnax/themeseed'
If you have feedback or need assistance with the MCP directory API, please join our Discord server