Blog
The indexer of The Smarter Project’s blog.
index_blog() brings the blog’s RepositoryIndex
up to date with its published posts, so that the MCP server’s search_blog and
read_blog_post tools can read them as they read a repository’s documentation:
It reads every published post from the blog’s public WordPress REST api,
/wp-json/wp/v2/posts, 100 posts a request.It fingerprints the posts by their ids and modification times. If the fingerprint is already indexed, there is nothing to do.
Otherwise it converts each post’s html to Markdown-like text, with its illustrations as Markdown images,
, which Smarter Chat displays, and replaces the blog’s files in one transaction, withstore_files(). A post’s path is its permalink’s path, e.g.2026/10/26/release-smarter-api-v0-6, and the fingerprint is stored as the index’scommit_sha.
The url is the fixed url of the project’s public blog, not a user-supplied one, so the
requests do not go through smarter.apps.llmtool.plugin.safe_http.
Note
Experimental. The MCPServer was designed and coded by Claude Code (Anthropic’s Claude Opus 5.5), with Lawrence McDaniel as co-author. It is experimental, and will be documented.
- class smarter.apps.mcpserver.blog.WordPressPost(*, id, date, modified, slug, link, title, content)[source]
Bases:
BaseModelA post, as the WordPress REST api returns it.
Only the fields that the indexer reads are modeled. WordPress and its plugins add others, e.g.
protectedandraw, which are ignored.- content: WordPressRendered
- model_config = {'extra': 'ignore'}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- title: WordPressRendered
- smarter.apps.mcpserver.blog.fetch_posts(blog)[source]
Return the blog’s published posts, newest first, from its WordPress REST api.
- Parameters:
blog (
ProjectBlog) – The blog.- Return type:
- Returns:
The posts.
- Raises:
SmarterMCPServerIndexError – If the blog does not answer with posts.
- smarter.apps.mcpserver.blog.html_to_text(content, base_url='')[source]
Return a post’s html as Markdown-like text, for search and for an LLM to read.
- smarter.apps.mcpserver.blog.index_blog(force=False, blog=None)[source]
Bring the blog’s index up to date with its published posts.
- Parameters:
force (
bool) – Index the posts even if they are already indexed.blog (
ProjectBlog|None) – The blog. Defaults toproject_blog().
- Return type:
- Returns:
The blog’s index. If indexing fails, its
errorsays why, and an existing index is kept.
Example usage:
index = index_blog() index.file_count # the number of posts
- smarter.apps.mcpserver.blog.post_file(blog, post)[source]
Return a post as a file of the blog’s index.
The text starts with the post’s title, dates and url, so that a reader of any part of it can cite it. A post longer than
MAX_FILE_BYTESis truncated.- Parameters:
blog (
ProjectBlog) – The blog.post (
WordPressPost) – The post.
- Return type:
- Returns:
The file.
- smarter.apps.mcpserver.blog.posts_fingerprint(posts)[source]
Return a fingerprint of the posts, which changes when a post is published, changed or removed.
- Parameters:
posts (
list[WordPressPost]) – The posts.- Return type:
- Returns:
40 hexadecimal characters, the size of a commit’s sha.