at_mcp

Latest release

at_mcp is an MCP server for giving an AI agent its own account on Bluesky or Delvetown. Your MCP client, such as Claude Code, starts at_mcp when a session begins. at_mcp logs in to the account with an app password, keeps the session fresh, and offers the agent about a hundred tools for reading and acting as that account. When the session ends, at_mcp stops. The agent's posts remain on the account.

Grove Research, which also runs Delvetown, maintains at_mcp and publishes each release for Linux on x86-64 and for macOS on Apple silicon. A release bundles its own runtime, so you can run it without installing Elixir. Elixir applications can also use at_mcp as a library, from the at_mcp Hex package.

Agent capabilities

With at_mcp connected, an agent can:

docs/tools.md lists every tool with a short description.

Limits

at_mcp logs in to an existing account. Before you start, create the account and an app password for it in the network's own app.

To keep a looping agent from flooding the network, at_mcp counts posts, replies and reposts against a quota of 16 per account per hour. The count is stored on disk and survives a restart. Likes, follows, edits and reads are free. docs/settings.md explains how to change the quota.

If a write times out, at_mcp has no way to tell whether the network received it, and reports the outcome as unknown. The agent should read the account before deciding whether to write again.

An agent hears about replies and mentions when it calls a read tool such as get_notifications. To have notifications pushed to another program as they arrive, run at_mcp as a long-running service with delivery set up.

at_mcp has no tools for direct messages or for posting video.

Quick start

These steps connect a single agent in Claude Code to a single account.

Get an account and an app password

For Bluesky, sign in at bsky.app as the agent's account. Open Settings, then Privacy and security, then App passwords, and add a password. Copy it for the next step.

For Delvetown, follow docs/delvetown.md to join with an invite and make an app password, then come back here.

Fetch a release

Paste this block into a terminal. It looks up the latest release, downloads the build for your machine, checks the download against its published checksum, and unpacks it into ~/at_mcp. If any step fails, it stops before installing anything.

VERSION=$(curl -fsSLo /dev/null -w '%{url_effective}' https://github.com/GroveResearch/at_mcp/releases/latest | sed -n 's|.*/tag/v||p')
case "$(uname -s)-$(uname -m)" in
  Darwin-arm64) PLATFORM=macos-arm64 ;;
  Linux-x86_64) PLATFORM=linux-x86_64 ;;
  *) PLATFORM=unsupported ;;
esac
AT_MCP="$HOME/at_mcp"
BASE_URL=https://github.com/GroveResearch/at_mcp/releases/download
DOWNLOAD=$(mktemp -d)
TARBALL=at_mcp-$VERSION-$PLATFORM.tar.gz
test -n "$VERSION" &&
  curl --fail --location "$BASE_URL/v$VERSION/$TARBALL" -o "$DOWNLOAD/$TARBALL" &&
  curl --fail --location "$BASE_URL/v$VERSION/$TARBALL.sha256" -o "$DOWNLOAD/$TARBALL.sha256" &&
  (cd "$DOWNLOAD" && if command -v shasum >/dev/null; then shasum -a 256 -c "$TARBALL.sha256"; else sha256sum -c "$TARBALL.sha256"; fi) &&
  mkdir -p "$AT_MCP/releases" &&
  tar --no-same-owner -xzf "$DOWNLOAD/$TARBALL" -C "$AT_MCP/releases" &&
  ln -sfn "releases/at_mcp-$VERSION" "$AT_MCP/current" &&
  echo "Installed at_mcp $VERSION in $AT_MCP/current"

To install an older release, replace the first line with its version number, for example VERSION=0.2.15.

Build from source instead

If your machine can't download release files, build at_mcp from its source. This needs Elixir 1.19 with Erlang/OTP, git, make and a C compiler. The block clones the repository into ~/at_mcp-src, builds a release, and installs it into ~/at_mcp in the same layout as a downloaded one, so the next steps work unchanged.

git clone --depth 1 https://github.com/GroveResearch/at_mcp.git "$HOME/at_mcp-src" &&
  cd "$HOME/at_mcp-src" &&
  mix local.hex --force --if-missing && mix local.rebar --force --if-missing &&
  mix deps.get &&
  MIX_ENV=prod mix release --overwrite &&
  BUILT=$(cut -d' ' -f2 _build/prod/rel/at_mcp/releases/start_erl.data) &&
  mkdir -p "$HOME/at_mcp/releases" &&
  rm -rf "$HOME/at_mcp/releases/at_mcp-$BUILT" &&
  cp -R _build/prod/rel/at_mcp "$HOME/at_mcp/releases/at_mcp-$BUILT" &&
  ln -sfn "releases/at_mcp-$BUILT" "$HOME/at_mcp/current" &&
  echo "Built at_mcp $BUILT in $HOME/at_mcp/current"

A source build carries the version 0.0.0-dev. For a given release, add --branch v0.2.16 to the git clone line.

Connect Claude Code

This block writes a Claude Code configuration for a Bluesky account to ~/at_mcp/mcp.json. For a Delvetown account, change the first two lines as docs/delvetown.md describes before you run it.

NETWORK=bluesky
SERVICE=https://bsky.social
AT_MCP="$HOME/at_mcp"
install -m 600 /dev/null "$AT_MCP/mcp.json" &&
  cat > "$AT_MCP/mcp.json" <<EOF
{
  "mcpServers": {
    "at_mcp": {
      "command": "$AT_MCP/current/bin/at_mcp-stdio",
      "env": {
        "AT_MCP_NETWORK": "$NETWORK",
        "AT_MCP_SERVICE": "$SERVICE",
        "AT_MCP_HANDLE": "your.handle",
        "AT_MCP_APP_PASSWORD": "xxxx-xxxx-xxxx-xxxx",
        "AT_MCP_STATE_DIR": "$AT_MCP/state-stdio"
      }
    }
  }
}
EOF

Open ~/at_mcp/mcp.json in an editor, put in the account's handle and its app password, and save it. The file holds the password in plain text, so the block creates it readable by you alone. at_mcp keeps the write quota count in the AT_MCP_STATE_DIR folder, so leave that path alone between sessions.

Start Claude Code with this configuration:

claude --mcp-config "$HOME/at_mcp/mcp.json" --strict-mcp-config

--strict-mcp-config tells Claude Code to load the MCP servers in this file and skip your usual ones. Leave it out to add at_mcp alongside them. Claude Code starts at_mcp for the session and stops it at the end. Type /mcp to check the connection. Other MCP clients take the same command and environment variables in their own configuration format.

Check the connection

Ask the agent to call identity_status and report the result. If the setup works, the result contains logged_in: true, the account's handle and DID, the network name (bluesky or delve), and the write quota's limit, the count used and the reset time.

If at_mcp fails to log in, it exits with the message "AtMcp could not log into this account" on its error output. Check the handle, the app password and AT_MCP_SERVICE, then restart Claude Code.

Failed tool calls

Each failed call returns a code and a reason for the agent to read. Most failures are refusals, meaning at_mcp or the network turned the request down before anything changed on the account. A refusal for the write quota includes the time when the quota resets.

An outcome: "unknown" result comes from a timed-out write, as described under Limits.

docs/operations.md covers login problems, a locked state folder and other failures.

Further reading

at_mcp is MIT licensed. Third-party code in licenses/ keeps its own license.