Write operations (signing) — opt-in, local by default
Write operations are off by default. They are registered only on the stdio server by default, and only when a valid posting authority is configured. The normal HTTP server refuses to start if a posting key is present; an explicitly unsafe HTTP override exists only for trusted operator-controlled deployments (see Advanced: unsafe HTTP signing for trusted deployments).
Read security guide for the full threat model and the principles every write tool follows.
Which key — delegated posting authority (recommended)
BLURT_ACCOUNT is the account you act as. BLURT_POSTING_KEY may be either:
- A delegated account's posting key (recommended). Create/own a separate account, grant it posting authority over
BLURT_ACCOUNT(add it to your postingaccount_auths— most wallets call this "posting authority"), and configure the MCP with that account's posting key. Your own key is never shared, and you can revoke access in one operation (remove the authority) without rotating any key. - Your account's own posting key. Simpler, but to revoke it you must change your posting key.
On startup the server validates that the key has posting authority over BLURT_ACCOUNT — directly, or through a delegated account — and refuses owner/active keys. The posting authority cannot move funds.
Recommended setup — key in a file you control, outside the repo
Put the secret in a file outside the project (e.g. ~/.config/blurt-mcp/secret.env, chmod 600), and point the stdio launcher at it with BLURT_ENV_FILE — the launcher itself carries no secret:
{
"mcpServers": {
"blurt": {
"command": "node",
"args": ["/absolute/path/to/blurt-mcp-server/dist/server-stdio.js"],
"env": { "BLURT_ENV_FILE": "/home/you/.config/blurt-mcp/secret.env" }
}
}
}# ~/.config/blurt-mcp/secret.env (chmod 600)
BLURT_ACCOUNT=youraccount
BLURT_POSTING_KEY=5J...
# recommended for new users — claim rewards + upvote only:
BLURT_WRITE_PROFILE=curator
# optional — subtract individual tools from the selected profile:
# BLURT_WRITE_TOOLS_BANNED=upvote
# optional neutral safety default — omitted dry_run parameters preview first:
# BLURT_DRY_RUN_DEFAULT=true
# optional local brake against accidental loops, disabled when unset:
# BLURT_WRITE_RATE_LIMITS=claim-rewards=6/3600,upvote=30/3600The server loads BLURT_ENV_FILE (or, if unset, the project's .env) regardless of the working directory the desktop app launches it from. Variables already set in the launcher's env block take precedence over the file, so you can also place the values directly in env if you prefer.
Do not put the posting key in the project's
.env: the HTTP server would then refuse to start, and the secret would live inside the working tree. Keep it in a file outside the repo.
Guarantees
- Only the posting key is accepted (active/owner are refused; it cannot move funds). The key is used solely for local signing — never sent to the network, logs, or other dependencies.
- Write tools are registered only on the stdio server by default, gated by the validated key and the
BLURT_WRITE_TOOLS_BANNEDdenylist. The HTTP server refuses to start with a key unless the operator explicitly enables the unsafe trusted-deployment override below. - The MCP server does not add write rate limits by default. Operators may opt in to process-local per-tool caps with
BLURT_WRITE_RATE_LIMITSwhen they want an extra brake against accidental loops or a misconfigured agent. These caps are not moderation rules and do not decide which accounts, tags or communities are allowed.
Every write tool supports dry_run: true to preview without broadcasting, and your AI client also prompts you to approve each tool call before it runs. Operators who prefer preview-first behavior can set BLURT_DRY_RUN_DEFAULT=true; omitted dry_run parameters then default to preview mode, while an explicit dry_run: false still executes the operation.
Neutral infrastructure boundary
The Blurt MCP server is neutral infrastructure. It validates signing safety and transport boundaries, but it does not add default write throttling. Optional operator controls such as BLURT_WRITE_RATE_LIMITS, BLURT_WRITE_TOOLS_BANNED and BLURT_DRY_RUN_DEFAULT are deployment controls for a specific server process; they are not Blurt blockchain protocol rules. Blurt blockchain Layer 1 and RPC operators keep their own protections. See ADR 0001.
Enabling tools with capability profiles
BLURT_WRITE_PROFILE is the recommended control for new deployments. It enables a semantic set of capabilities, so operators do not need to maintain a long comma-separated list of every tool and do not need to edit config just because a future release adds a tool that clearly belongs to the same profile.
If BLURT_WRITE_PROFILE is unset, the server preserves the historical behavior for backward compatibility: all current write tools are enabled, and BLURT_WRITE_TOOLS_BANNED subtracts specific ones.
Recommended starting point:
BLURT_WRITE_PROFILE=curatorProfiles:
| Profile | Enables | Intended operator posture |
|---|---|---|
none | no write tools | Keep a key configured but temporarily expose no write surface. |
curator | claim-rewards, upvote | Safer new-user default: rewards + voting only. |
social | curator plus follow, mute, subscribe-community, read-notifications, reblog | Social/community actions, but no original text publishing. |
publisher | all current publishing/social/reward tools | Trusted local assistant that may comment and publish posts. Future high-risk tools should be classified deliberately before joining this profile. |
full | every write tool in this release | Explicit full-access mode; equivalent to legacy unset-profile behavior for current tools. |
BLURT_WRITE_TOOLS_BANNED remains supported as a backward-compatible subtractive control. It always removes individual tools from whichever profile is active (or from legacy full mode when no profile is set). For example, a social operator that wants to allow follows/community/reblogs but not upvotes:
BLURT_WRITE_PROFILE=social
BLURT_WRITE_TOOLS_BANNED=upvoteLocal write rate limits are optional
BLURT_WRITE_RATE_LIMITS is the only MCP-server write throttling mechanism. It is disabled when unset. The format is a comma-separated list of tool=max/windowSeconds entries:
BLURT_WRITE_RATE_LIMITS=claim-rewards=6/3600,upvote=30/3600,post=10/3600This limit is process-local and in-memory. It resets when the process restarts and does not coordinate across replicas. Use it only as a local safety brake for a particular deployment.
Layer distinction:
- Blurt blockchain Layer 1 still enforces its own protocol rules: signature authority, transaction validity, voting mana/economics, duplicate/conflicting operations where applicable, and irreversible public history.
- Public RPC nodes may enforce their own traffic limits, quotas, connection limits or abuse controls. Those limits depend on the node operator and are outside this MCP server.
- This MCP server only enforces posting-key validation, transport gating, selected write-tool registration, optional dry-run defaults, and optional
BLURT_WRITE_RATE_LIMITSwhen the operator sets them.
Canonical write tool list
Use the tool name column below for denylist entries. Unknown denylist names are ignored so old configuration remains forward-compatible across releases; an unknown BLURT_WRITE_PROFILE fails closed at startup.
| Tool | Tool name | Operation | Optional cap example | Profiles |
|---|---|---|---|---|
blurt-claim-rewards | claim-rewards | claim_reward_balance | claim-rewards=6/3600 | curator, social, publisher, full |
blurt-upvote | upvote | vote | upvote=30/3600 | curator, social, publisher, full |
blurt-comment | comment | comment (reply) | comment=10/3600 | publisher, full |
blurt-post | post | comment (top-level) | post=10/3600 | publisher, full |
blurt-follow | follow | custom_json follow | follow=30/3600 | social, publisher, full |
blurt-mute | mute | custom_json follow/ignore | mute=30/3600 | social, publisher, full |
blurt-subscribe-community | subscribe-community | custom_json community | subscribe-community=30/3600 | social, publisher, full |
blurt-reblog | reblog | custom_json reblog | reblog=30/3600 | social, publisher, full |
blurt-read-notifications | read-notifications | custom_json notify | read-notifications=30/3600 | social, publisher, full |
Advanced: unsafe HTTP signing for trusted deployments
The default and recommended signing mode is still local stdio. However, experienced operators who run a private, authenticated, access-controlled deployment may deliberately opt in to exposing the same write tools over the HTTP MCP endpoint.
This is intentionally hard to enable. You must configure a valid write context (BLURT_ACCOUNT and BLURT_POSTING_KEY) and set this exact environment variable/value on the HTTP server process:
BLURT_UNSAFE_ALLOW_HTTP_SIGNING_WITH_POSTING_KEY=I_ACCEPT_FULL_RESPONSIBILITY_FOR_EXPOSING_BLURT_WRITE_TOOLS_OVER_HTTPAny other value is ignored and the HTTP server still refuses to start with BLURT_POSTING_KEY set. When the override is active, startup prints a large UNSAFE HTTP SIGNING ENABLED warning to stderr. The override does not weaken the other write policies: active/owner keys are still refused, posting authority is still validated, BLURT_WRITE_TOOLS_BANNED still applies, and any configured BLURT_WRITE_RATE_LIMITS still apply.
Use this only when the HTTP endpoint is protected by your own authentication, TLS, network isolation, reverse-proxy controls, monitoring, and operational procedures. Do not use it for the public hosted endpoint, an anonymous service, or an unauthenticated LAN/WAN deployment. The operator accepts full responsibility for every on-chain operation signed by that process. See security guide for the full rationale and threat model.
blurt-claim-rewards
Claims the configured account's pending author/curation rewards (claim_reward_balance), moving them into the account's balance and Blurt Power. Acts only on the configured account; no parameter targets another account. Returns the pending amounts and, when executed, the transaction id.
blurt-upvote
Upvotes a post or comment (vote) as the configured account.
- Parameters:
author,permlink,weight(percent, 1-100, default 100),dry_run. - Only the configured account votes; on chain, weight 100% = 10000.
blurt-comment
Posts a reply (comment) to a post or comment as the configured account.
- Parameters:
parent_author,parent_permlink,body(markdown),dry_run. - A unique permlink is generated automatically. The body gets a
via Blurt-MCPfooter (linking back to this repository) appended after a blank line, andjson_metadata.appis set toblurt-mcp/<version>. - Posts are public and permanent — use
dry_run: truefirst to review the exact final body.
blurt-post
Publishes a new top-level post (comment with an empty parent) as the configured account.
- Parameters:
title,body(markdown),tags(1–8 lowercase tags; the first is the main category),dry_run. - A unique permlink is generated from the title. Same
via Blurt-MCPfooter andjson_metadata.app = blurt-mcp/<version>stamping asblurt-comment; the tags are stored injson_metadata.tags. - Posts are public and permanent — use
dry_run: truefirst to review the exact final post.
blurt-follow
Follows or unfollows another account (custom_json id follow).
- Parameters:
account,action(follow|unfollow, defaultfollow),dry_run.
blurt-mute
Mutes (ignores) or unmutes another account (custom_json id follow, what: ['ignore']), hiding its content in compatible frontends.
- Parameters:
account,action(mute|unmute, defaultmute),dry_run.
blurt-subscribe-community
Subscribes the account to a community, or unsubscribes from it (custom_json id community).
- Parameters:
community(name/id, e.g.blurt-192372),action(subscribe|unsubscribe, defaultsubscribe),dry_run.
blurt-reblog
Reblogs (re-shares) a post to the account's blog (custom_json id reblog), or removes a prior reblog.
- Parameters:
author,permlink,undo(defaultfalse),dry_run.
blurt-read-notifications
Marks the account's notifications as read up to now (custom_json id notify, setLastRead). Acts only on the configured account; no parameter targets another account.
- Parameter:
dry_run. Pair withget-account-notificationsto read them first.