Skip to content

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.

BLURT_ACCOUNT is the account you act as. BLURT_POSTING_KEY may be either:

  1. A delegated account's posting key (recommended). Create/own a separate account, grant it posting authority over BLURT_ACCOUNT (add it to your posting account_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.
  2. 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.

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:

json
{
  "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" }
    }
  }
}
bash
# ~/.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/3600

The 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_BANNED denylist. 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_LIMITS when 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:

dotenv
BLURT_WRITE_PROFILE=curator

Profiles:

ProfileEnablesIntended operator posture
noneno write toolsKeep a key configured but temporarily expose no write surface.
curatorclaim-rewards, upvoteSafer new-user default: rewards + voting only.
socialcurator plus follow, mute, subscribe-community, read-notifications, reblogSocial/community actions, but no original text publishing.
publisherall current publishing/social/reward toolsTrusted local assistant that may comment and publish posts. Future high-risk tools should be classified deliberately before joining this profile.
fullevery write tool in this releaseExplicit 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:

dotenv
BLURT_WRITE_PROFILE=social
BLURT_WRITE_TOOLS_BANNED=upvote

Local 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:

dotenv
BLURT_WRITE_RATE_LIMITS=claim-rewards=6/3600,upvote=30/3600,post=10/3600

This 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_LIMITS when 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.

ToolTool nameOperationOptional cap exampleProfiles
blurt-claim-rewardsclaim-rewardsclaim_reward_balanceclaim-rewards=6/3600curator, social, publisher, full
blurt-upvoteupvotevoteupvote=30/3600curator, social, publisher, full
blurt-commentcommentcomment (reply)comment=10/3600publisher, full
blurt-postpostcomment (top-level)post=10/3600publisher, full
blurt-followfollowcustom_json followfollow=30/3600social, publisher, full
blurt-mutemutecustom_json follow/ignoremute=30/3600social, publisher, full
blurt-subscribe-communitysubscribe-communitycustom_json communitysubscribe-community=30/3600social, publisher, full
blurt-reblogreblogcustom_json reblogreblog=30/3600social, publisher, full
blurt-read-notificationsread-notificationscustom_json notifyread-notifications=30/3600social, 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:

dotenv
BLURT_UNSAFE_ALLOW_HTTP_SIGNING_WITH_POSTING_KEY=I_ACCEPT_FULL_RESPONSIBILITY_FOR_EXPOSING_BLURT_WRITE_TOOLS_OVER_HTTP

Any 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-MCP footer (linking back to this repository) appended after a blank line, and json_metadata.app is set to blurt-mcp/<version>.
  • Posts are public and permanent — use dry_run: true first 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-MCP footer and json_metadata.app = blurt-mcp/<version> stamping as blurt-comment; the tags are stored in json_metadata.tags.
  • Posts are public and permanent — use dry_run: true first to review the exact final post.

blurt-follow

Follows or unfollows another account (custom_json id follow).

  • Parameters: account, action (follow | unfollow, default follow), 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, default mute), 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, default subscribe), 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 (default false), 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 with get-account-notifications to read them first.