Skip to main content
Glama
sumiVer2
by sumiVer2

hatena-blog-mcp

An MCP server for creating and updating Hatena Blog articles. It thinly wraps the Hatena Blog AtomPub API so that AI agents can draft, revise, and publish articles.

Setup

The package manager is pnpm (fixed via the packageManager field).

pnpm install   # 依存のインストールと同時に prepare で dist がビルドされる

Obtaining configuration values

The "Root endpoint" and "API key" are displayed under Hatena Blog's [Settings] > [Advanced Settings] > [AtomPub]. The root endpoint has the following format.

https://blog.hatena.ne.jp/{ブログ所有者のはてなID}/{ブログID}/atom

Environment variable

Required

Value

HATENA_ID

Yes

The Hatena ID of the account used for authentication (the owner of the API key)

HATENA_BLOG_ID

Yes

The {blog ID} part of the root endpoint (e.g. tech.example.hatenablog.com)

HATENA_API_KEY

Yes

API key

HATENA_BLOG_OWNER_ID

The {Hatena ID of the blog owner} part of the root endpoint. Defaults to HATENA_ID when omitted

  • For a blog you own, the owner and the operator are the same, so HATENA_BLOG_OWNER_ID is not needed

  • For a shared blog (such as a company tech blog), the owner and the operator differ. In that case, specify the blog owner's ID in HATENA_BLOG_OWNER_ID and your own account in HATENA_ID

  • Even if you use a custom domain on a paid plan, specify the domain before the custom domain setting in HATENA_BLOG_ID

See .env.example.

Registering with an MCP client

For Claude Code:

# 自分が所有するブログ
claude mcp add hatena-blog -s user \
  -e HATENA_ID=your-hatena-id \
  -e HATENA_BLOG_ID=your-blog.hatenablog.com \
  -e HATENA_API_KEY=your-api-key \
  -- node /absolute/path/to/hatena-blog-mcp/dist/index.js

# 共有ブログ(所有者と操作者が異なる場合は HATENA_BLOG_OWNER_ID を足す)
claude mcp add hatena-blog -s user \
  -e HATENA_ID=your-hatena-id \
  -e HATENA_BLOG_OWNER_ID=blog-owner-id \
  -e HATENA_BLOG_ID=blog-owner-id.hatenablog.com \
  -e HATENA_API_KEY=your-api-key \
  -- node /absolute/path/to/hatena-blog-mcp/dist/index.js

Adding -s user makes it available across all projects. Do not use -s project (the API key will be written to .mcp.json).

When writing directly to the configuration file:

{
  "mcpServers": {
    "hatena-blog": {
      "command": "node",
      "args": ["/absolute/path/to/tech-blog/dist/index.js"],
      "env": {
        "HATENA_ID": "your-hatena-id",
        "HATENA_BLOG_OWNER_ID": "blog-owner-id",
        "HATENA_BLOG_ID": "blog-owner-id.hatenablog.com",
        "HATENA_API_KEY": "your-api-key"
      }
    }
  }
}

Once registered, calling get_blog_info serves as a connectivity check.

Related MCP server: Blogger MCP Server

Tools

Blog-wide

Tool

Description

get_blog_info

Retrieves the blog title and available collections (also usable as a connectivity check)

list_categories

Lists the categories used in the blog

Entries

Tool

Description

list_entries

Lists entries in reverse chronological order (including drafts). Use next_page to fetch more

search_entries

Traverses pages and performs partial-match search on title, body, and categories

get_entry

Retrieves a single entry (the body remains in the registered notation)

create_entry

Creates a new entry (draft by default)

update_entry

Updates an entry with a diff-based update

Pages

list_pages / search_pages / get_page / create_page / update_page are provided in the same form as entries. Pages are only available on Hatena Blog paid plans (a 404 is returned on the free plan). Pages do not have categories, so there is no categories parameter.

Design decisions

Deletion is not implemented

Deletion of entries and pages (DELETE) exists on the API side but is intentionally not exposed as a tool. The impact of an accidental operation is too large and cannot be undone. Deletion should be done from the browser.

update_entry performs diff-based updates

Since AtomPub's PUT "replaces everything with the sent content," even when you only intend to fix the title, you must resend the body, categories, and post date/time in full. This server performs a GET followed by replacing only the specified items and then PUT inside update_entry.

  • Omitted items retain their current values

  • Omitting updated leaves the entry's post date/time (the displayed date) unchanged

  • Passing categories results in a replacement (not an addition). To keep existing categories, include them as well

New entries are drafts by default

The draft parameter of create_entry defaults to true. To prevent an agent operation from immediately publishing an entry, publishing only occurs when draft: false is explicitly specified.

Body notation

For content_type, you can specify text/x-markdown / text/x-hatena-syntax / text/html / text/plain (default is text/x-markdown). However, how it is actually interpreted follows the blog's "edit mode" setting, so it must be written to match the blog's settings. When updating an existing entry, the notation before editing is carried over.

Scheduled posting

Specify draft: true + scheduled: true + a future date/time for updated in create_entry.

List pagination

The Hatena Blog API returns few items per page, and the count is determined by the API side (the official documentation states 7 entries, but we have confirmed that 10 are actually returned). list_entries returns one page, and passing next_page as the page of the next call fetches more. To search across multiple entries at once, use search_entries, which traverses pages internally. Control the traversal amount with max_pages.

Authentication and the Hatena ID in the URL

WSSE authentication (the X-WSSE header) is used. A Nonce and Created are generated for each request, and Base64(SHA1(Nonce + Created + API key)) is sent as the PasswordDigest.

Note that the Hatena ID in the endpoint URL (the blog owner) and the account being authenticated are different things. Since API keys are issued per account rather than per blog, for a shared blog the combination is:

  • URL: https://blog.hatena.ne.jp/{owner's ID}/{blog ID}/atom

  • Authentication: your account's Hatena ID + API key

Confusing the two results in a 401 (the key does not belong to the owner) or a 403 (the account does not have permission for the blog). This server separates the two with HATENA_BLOG_OWNER_ID and HATENA_ID, and treats them as the same ID when omitted, so the same configuration method works for both your own blog and shared blogs.

Out of scope

  • Image upload: Outside the scope of AtomPub (the Hatena Fotolife API exists separately)

  • Changing page layouts: Not supported by the API. Configure from the browser

  • OAuth authentication: Only WSSE authentication with an API key is supported

Development

pnpm run typecheck   # 型チェック
pnpm test            # ユニットテスト(API はモック)
pnpm run build       # dist へビルド
pnpm run dev         # ビルドせずに起動
pnpm run inspect     # MCP Inspector で手動確認

Since pnpm 10 blocks dependency build scripts by default, only esbuild (used by tsx) is allowed via pnpm.onlyBuiltDependencies in package.json.

Structure

src/
  index.ts          エントリポイント(stdio トランスポート)
  server.ts         McpServer の組み立て
  config.ts         環境変数の読み込み
  hatena/
    client.ts       AtomPub の HTTP クライアント
    wsse.ts         WSSE 認証ヘッダの生成
    atom.ts         Atom XML のパース・生成
    types.ts        ドメイン型
  tools/
    blog.ts         ブログ全体に対するツール
    collection.ts   記事・固定ページ共通のツール定義
    shared.ts       ツールの共通ヘルパー

Since entries and pages have nearly the same structure on AtomPub, registerCollectionTools in tools/collection.ts is called with two different configurations: one for entries and one for pages.

License

MIT License. See LICENSE for details.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

No tool schema history has been recorded yet.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    Enables AI assistants to interact with the Google Blogger API v3 to manage blog posts and metadata. It supports the full post lifecycle including creating, updating, publishing, and deleting content through natural language.
    10
    17
    MIT
  • F
    license
    A
    quality
    D
    maintenance
    Enables AI clients to manage Hexo blogs by providing tools for article CRUD operations, local previewing, and GitHub Pages deployment. It also supports site configuration access and automated Git backups to streamline the entire blogging workflow.
    12
    1
    -
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables AI models to interact with Google Blogger blogs, manage posts, labels, and retrieve blog information via API key or OAuth2.
    19
    MIT

Latest Blog Posts

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/sumiVer2/hatena-blog-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server