Changelog
Release Notes
All notable changes to the ActivityPub MCP Server are documented here. The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
v3.2.1 - 2026-06-22
Dependency maintenance and security patch. No source or API changes — tool names, schemas, and responses are identical to 3.2.0. See CHANGELOG.md for the complete entry.
Security
- undici 7.26.0 → 7.28.0 — clears a HIGH-severity advisory chain affecting undici
<= 7.27.2(the HTTP client behind every Fediverse fetch): TLS certificate-validation bypass, shared-cache information disclosure,Set-Cookieheader injection, WebSocket denial of service, and SOCKS5 proxy-routing issues. Stayed on the 7.x line because undici 8 requires Node ≥ 22.19 while this server supports Node ≥ 20.
Changed
- Dependency maintenance — refreshed transitive and dev/build dependencies and pinned CI actions (
actions/checkout7,softprops/action-gh-release) to their latest patches.
v3.2.0 - 2026-06-16
Structured tool output and Smithery listing improvements. No breaking changes — tool names and human-readable responses are unchanged; structured output is purely additive. See CHANGELOG.md for the complete entry.
Added
- Structured tool results — every read/default tool now declares an
outputSchemaand returnsstructuredContentalongside the existing text, so MCP clients can type-check responses. The prose output is unchanged. - Smithery listing — homepage ownership verification and a backlink from the README and docs site.
Changed
.mcpbrelease pipeline embeds the live tool schemas (inputSchema/outputSchema) in the bundle manifest, captured from the running server and packaged via a plain zip — the metadata Smithery’s capability score reads.
Fixed
get-relationship— theaccountIdsrejection-guard parameter now carries a description, completing parameter-description coverage.
v3.1.6 - 2026-06-15
Correctness, hardening, and docs patch from a third end-to-end review. Fixes a silent read-path data loss, several remote-input edge cases, and a cluster of tool-reference documentation drift. No breaking changes. See CHANGELOG.md for the complete entry.
Fixed
get-public-timelineno longer silently drops posts — it rendered only the first 15 of up to 40 fetched posts while advertising a cursor derived from the last fetched post, so the unshown tail was skipped and unreachable on the next page. All fetched posts are now rendered.fetch-timelinesurfaces content warnings — a CW’d post (summary+content) showed the sensitive body with no warning marker, unlike every other read tool; the⚠️ CW:marker is now emitted.- Mastodon timeline cursor is taken from the last raw item, not the last surviving post, so dropping a malformed trailing record no longer causes the next page to re-fetch and duplicate posts.
- Misskey account search drops records without a username, mirroring the Mastodon path, instead of surfacing a garbage
undefined@hosthandle. instances.socialpagination no longer under-reportshasMorewhen a row with an empty domain is filtered out of a full page.- NodeInfo software cache re-checks the operator blocklist on a hit, so blocking an instance takes effect immediately instead of after the 24h TTL.
Security
- Prompt-injection envelope label is angle-bracket-escaped — a lone
>from an unvalidated remote domain could close the<untrusted-content source="…">opening tag early; the label now escapes</>. - HTTP transport tolerates a malformed/empty
Hostheader — it previously threw before routing/auth, dropping the connection with no response; the path/query are now parsed against a fixed base (the real Host is still validated by the SDK’s rebinding protection). - OAuth
issmix-up check fails closed on a malformed issuer — a non-URLissfrom a hostile authorization server now produces the intended mix-up error instead of an uncaughtTypeError.
Changed
MAX_RETRIESis floored at 1 —0previously made the retry loop body never execute, silently issuing no request and bricking every remote read/write.- Tool reference (
tools.mdx) reconciled with the validators — removed documented inputs the tools reject (discover-actorprofile URLs,search --resolve,get-notifications --excludeTypes,maxIdon bookmarks/favourites/scheduled-posts,upload-mediaURL), corrected theget-public-timelinescope default tofederated, relaxed the overstated one-hourscheduledAtrule to “must be in the future,” and added thestatus/updatenotification types.
v3.1.5 - 2026-06-15
Maintenance release — dependency, toolchain, and CI/security hardening with no runtime behavior changes; the published server is functionally identical to v3.1.4. See CHANGELOG.md for the complete entry.
Changed
- Migrated the build to TypeScript 6 and refreshed the dev/test/build dependency groups (vitest, msw, biome, astro, and others via Dependabot).
- Cleaned up
tsconfig.jsonfor TypeScript 6: explicitrootDir, dropped the deprecatedbaseUrland an unused path alias.
Security
- Deduplicated esbuild to the patched
0.28.1, clearing two dev-toolchain advisories (GHSA-gv7w-rqvm-qjhr, GHSA-g7r4-m6w7-qqqr). esbuild is build-time only and never shipped. - Scoped the blocking CI
npm auditgate to production dependencies (what ships indist/), so dev-only docs-site advisories no longer block releases; the strict production audit remains required and clean.
v3.1.4 - 2026-06-10
Security, correctness, and distribution patch from a second end-to-end review. Restores real fetch-timeline content, un-breaks subsystem logging and Windows login, hardens read timeouts, the thread privacy gate, the Mastodon read path, SSRF range coverage, the Windows installer, and the release supply chain. See CHANGELOG.md for the complete entry.
Fixed
fetch-timelinerenders real content again — outbox items areCreate/Announceactivities, so readingcontentoff the wrapper showed every post as[Create] (empty); the nested object is now unwrapped.- Subsystem logs are no longer silently dropped — logtape categories are array-based, so
getLogger("activitypub-mcp:http")had no sink; ~13 subsystems (including security/audit warnings) now log via the array-child form. - Read timeouts cover the response body, not just headers — a hostile instance could send headers then trickle the body forever to pin a tool call; the deadline now spans the body read.
get-scheduled-postsworks withoutACTIVITYPUB_ENABLE_WRITES— it is an authenticated read but was registered inside the write-gated block.post-threadresource resolves the canonical ActivityPub URI via the REST API instead of the dead/web/statuses/SPA route, and validates{statusId}against path-segment injection.- Windows
loginopens the browser correctly —cmd /c startsplit the OAuth URL at its&separators; it now uses rundll32’s FileProtocolHandler (no shell parsing).
Security
- Thread reads don’t beacon to attacker-chosen hosts — the cross-origin gate now also covers the root post’s
replies-collection URL (default-off). - SSRF private-range coverage corrected — IPv4
224.0.0.0/4&240.0.0.0/4and IPv6ff00::/8& Teredo2001::/32now match their full ranges. - Mastodon read adapter hardened to parity with Misskey — timeline/trending/search results are structurally validated, count-coerced, and capped at the requested limit.
install.ps1no longer wipes other MCP servers on Windows PowerShell 5.1 — it delegates to the shared Node merge helper, which preserves existing servers and refuses to clobber unparseable configs.- Release supply chain tightened — the
.mcpbbuilder is version-pinned and installed with--ignore-scripts; release jobs drop to least-privilege permissions and check out withpersist-credentials: false.
Changed
- CI enforces the per-directory coverage thresholds via a dedicated coverage job.
- The README “Add to Cursor” button uses Cursor’s
https://cursor.com/install-mcpwrapper (GitHub strips rawcursor://hrefs).
v3.1.3 - 2026-06-09
Security & correctness hardening patch from an end-to-end review. Fixes a stdio shutdown hang, hardens upload-media (size cap + path-leak fix), gates cross-origin thread fetches, hardens the Misskey read path, and tightens the install/release supply chain. See CHANGELOG.md for the complete entry.
Fixed
Ctrl+Cnow exits the stdio server — graceful shutdown never closed the MCP transport, so the stdin listener kept the process alive and SIGINT/SIGTERM hung. The transport is now closed on shutdown.- Misskey
directmessages fail loud instead of silently posting to no one (aspecifiednote with no recipients is author-only); the tool now reports that DMs aren’t wired up for Misskey. - Malformed remote items no longer fail a whole read — the Misskey read adapter drops a bad note/coerces non-numeric reaction counts and enforces the requested
limit, instead of throwing on one record. - Numeric env vars are validated and clamped —
AUDIT_LOG_MAX_ENTRIES=0no longer silently disables the audit trail,MAX_RESPONSE_SIZE=10MBno longer parses to 10 bytes, and negative timeouts are rejected.
Security
upload-mediacaps file size before reading (MAX_UPLOAD_SIZE, default 100 MB), so a coerced/oversized path can’t exhaust memory.upload-mediaerrors no longer leak absolute filesystem paths or errno — a prompt-injected model can’t use them as a filesystem-enumeration oracle; the audit log records only the file basename.- Cross-origin thread fetches are gated for ancestors too — the
inReplyTowalk now honorsMCP_THREAD_CROSS_ORIGIN_FETCH=falselike the reply branch, closing a fetch-amplification/privacy-control bypass. get-scheduled-postsis annotated read-only (was mislabeled destructive).- Supply chain: the install script parses existing config with
JSON.parse(no morenode -einterpolation), the registry publish job pins and checksum-verifiesmcp-publisherand dropssecrets: inherit, and the token-holding release jobs runnpm ci --ignore-scripts.
Known limitations
- The HTTP transport still serves one MCP session per process; proper multi-session support is tracked for a follow-up. The default stdio transport is unaffected.
v3.1.2 - 2026-06-09
Correctness, logging, and audit patch. Fixes a logging bug that polluted the stdio JSON-RPC stream, a cache misconfiguration that could hang startup, and a missing post idempotency key; records SSRF and rate-limit denials in the audit trail; and removes dead support links. See CHANGELOG.md for the complete entry.
Fixed
- Logs no longer corrupt the stdio JSON-RPC stream — logtape’s console sink routed
info/debugto stdout, the channel the stdio transport uses for MCP frames; all log levels now go to stderr. CACHE_MAX_SIZE=0no longer hangs the server — a non-positive cache size made the LRU eviction loop spin forever on the first write; it is now clamped to 1.- Mastodon posts send an
Idempotency-Keyderived from the post content, so a retried post can’t duplicate. LOG_LEVEL=warnworks as documented — the value is normalized to logtape’swarning, with unknown values falling back toinfo.
Security
- SSRF blocks and rate-limit denials are now recorded in the audit trail — the two audit methods existed but had no callers, so the most security-relevant events were invisible.
Changed
- Dead GitHub Discussions links removed — Discussions is disabled, so the footer, troubleshooting, and
llms.txtlinks now point at GitHub Issues.
v3.1.1 - 2026-06-05
Correctness & distribution patch. Closes a media-upload exfiltration vector, fixes Misskey relationship and outbox-pagination bugs, and makes every release ship the one-click Claude Desktop bundle. See CHANGELOG.md for the complete entry.
Security
upload-medianow validates file content by magic bytes and refuses anything that is not a recognized image/video/audio file, so a prompt-injected model can no longer name an arbitrary path (a key, the credential store, a.env) and exfiltrate it to a public media URL.
Fixed
- Misskey relationship results —
users/relationreturns a one-element array for a single user id, which the adapter read as a bare object, so follow / mute / block results came backfalse. Both shapes are handled now. - Outbox pagination no longer reports
hasMore: trueon a full final page with nonextcursor.
Distribution
- The Claude Desktop Extension (
.mcpb) is built and attached to every release, so the README’s one-click install always resolves on the latest release.
v3.1.0 - 2026-06-04
Multi-platform reads & activation fixes. Misskey/Foundkey instances now work for search, trending, and public timelines; a broken homepage install command and several docs-drift issues are fixed; and an IPv6 SSRF gap is closed. See CHANGELOG.md for the complete entry.
Added
- Misskey / Foundkey read support for
search,get-trending-hashtags,get-trending-posts, andget-public-timeline, routed per instance by NodeInfo software detection and normalized into Mastodon-shaped results. - Authentication guide documenting the
activitypub-mcp login(Mastodon OAuth2 / Misskey MiAuth) flow, credential storage, and multi-account usage.
Fixed
- The site’s “Quick install” command (
npx activitypub-mcp install→npx -y activitypub-mcp); running the bin directly in a terminal now prints a hint instead of appearing to hang; getting-started docs reconciled with the actual configuration (phantom env vars and wrong defaults removed).
Security
- Full IPv6 private-range SSRF blocking (
fc00::/7,fe80::/10,fec0::/10) — closes a gap where most of those ranges were reachable via crafted IPv6 hosts. - All GitHub Actions pinned to commit SHAs so a retagged or compromised action can’t run in the credential-bearing release jobs.
v3.0.1 - 2026-06-02
Correctness & distribution. A cross-origin redirect security fix, Misskey and remote-fetch correctness fixes, and the server is now publishable to the official MCP Registry. See CHANGELOG.md for the complete entry.
Security
- Cross-origin redirect credential stripping.
Authorization,Cookie, and the request body are dropped when an outbound fetch is redirected to a different origin, so credentials can never leak to an unexpected host.
Added
- MCP Registry manifest. A
server.jsonand amcpNamemarker make the server publishable to registry.modelcontextprotocol.io — npm package, stdio transport, read-only by default.
Fixed
- Misskey
get-home-timelinenow mapsminIdto the correct API parameter - Remote fetches honor
Retry-After, retry transient (5xx / network) failures with backoff, and tolerate ActivityStreamsto/ccdelivered as a single string
v3.0.0 - 2026-05-31
Security & surface-reduction overhaul. Read-only by default, an untrusted-content envelope, and a leaner tool surface. See the v3 Migration Guide for full upgrade details, and CHANGELOG.md for the complete entry.
Breaking & Changed
- Read-only by default. Mutation tools (post, reply, boost, follow, vote, scheduled posts, …) are only registered when
ACTIVITYPUB_ENABLE_WRITES=true discover-instances-liverenamed todiscover-instances; the staticrecommend-instancesand old staticdiscover-instancesare removedsearch-instance/search-accounts/search-hashtags/search-postsconsolidated intosearch(passtype: "all" | "accounts" | "posts" | "hashtags")get-local-timeline+get-federated-timelineconsolidated intoget-public-timeline(passscope: "local" | "federated")get-instance-softwareremoved;get-instance-infonow includes the software-detection block- All remote Fediverse content wrapped in an
<untrusted-content>envelope before it reaches the model
Added
ACTIVITYPUB_ENABLE_WRITES— master switch for all mutation tools (defaultfalse)MCP_HTTP_ALLOWED_HOSTS/MCP_HTTP_ALLOWED_ORIGINS— allowlists for HTTP-transport DNS-rebinding protection- Browser-based login:
activitypub-mcp login <instance>(Mastodon OAuth2 PKCE / Misskey MiAuth), pluslogoutandaccounts; credentials persisted toaccounts.json(mode0600) ACTIVITYPUB_CONFIG_DIRto override the credential-store location
Removed
- Export tools (
export-timeline,export-thread,export-account-info,export-hashtag) health-check/performance-metricstools, the telemetry subsystem, and the/metricsendpointbatch-fetch-actors/batch-fetch-posts,convert-url,recommend-instances- MCP prompts
community-health,compare-instances,content-strategy,discover-content,migration-helper,thread-composer(five remain)
Security
- Complete DNS-rebinding IP-pinning on all outbound fetch paths (previously HTTP transport only)
<untrusted-content>envelope structurally isolates Fediverse text from trusted context- HTTP transport rejects unexpected
Host/Originheaders with403
v2.2.0 - 2026-05-29
Added
- Platform-aware write layer. Authenticated operations route to the correct Fediverse API per instance via NodeInfo software detection; a new Misskey/Foundkey adapter covers core-parity ops. Mastodon-API-compatible software (Pleroma, Akkoma, GotoSocial, Sharkey, Firefish) and undetected instances keep using the Mastodon adapter
UnsupportedOnPlatformErrorfor operations with no Misskey equivalent (bookmarks, poll voting, scheduled posts)
v2.1.0 - 2026-05-28
Added
get-instance-softwaretool. NodeInfo 2.0/2.1 software + version detection (Mastodon, Pleroma, Misskey, Akkoma, Sharkey, GotoSocial, Friendica, …)activitypub://instance-info/{domain}enriched with a structuredsoftware:blockMCP_INSTANCE_SOFTWARE_TTL_MSto tune the NodeInfo positive-cache TTL (default 24h)- Dependabot config (weekly grouped npm + GitHub Actions updates)
Breaking
activitypub://post-thread/{postUrl}URI form removed (deprecated in v2.0.0); useactivitypub://post-thread/{domain}/{statusId}activitypub://instance-info/{domain}softwarefield is now an object (was a string); readbody.software.software?.name
v2.0.0 - 2026-05-27
Security & correctness focused release. See the v2 Migration Guide for full breaking-change details, and CHANGELOG.md for the complete entry.
Breaking
MCP_HTTP_SECRETis required whenMCP_TRANSPORT_MODE=http(no default; ≥16 chars)MCP_HTTP_CORS_ORIGINSdefaults to empty (was permissive); set explicitly for browser clientsACTIVITYPUB_ACCOUNTSuses|as the field delimiter (colon form rejected at startup)HEALTH_CHECK_ENABLEDremoved; replaced withHEALTH_CHECK_EXTERNAL_PROBE- MCP tool arg renamed:
scheduledId→scheduledPostIdon cancel-scheduled-post / update-scheduled-post - Node 20+ required (was 18+)
Added
- SSRF guards + streaming response-size caps on every outbound fetch
- Thread traversal caps:
MCP_THREAD_MAX_DEPTH,MCP_THREAD_MAX_REPLIES,MCP_THREAD_CROSS_ORIGIN_FETCH - Bearer-token auth middleware on
/mcpand/metrics - Full-surface audit logging (success + failure) across every write tool
post-statusacceptsmediaIdsandscheduledAtdirectly- Dynamic server-info capabilities from a live tool/resource/prompt registry
Fixed
- Pagination cursor preserves
limit/min_id/max_id/since_id - 304 Not Modified no longer surfaces as a spurious error
search-instancerenders prose instead of raw JSON;fetch-timelinerenders all posts- Filter composition in tool list is cumulative (was last-write-wins)
- PerformanceMonitor interval is unref’d so it never blocks shutdown
Internal
- Source reorganized into topic directories:
activitypub/,audit/,discovery/,policy/,resilience/,telemetry/,transport/,validation/ - CI: typecheck step, daily integration suite, tarball-contents check, bin smoke test
- TypeScript
noUnusedLocals/noUnusedParametersand BiomenoUnusedVariablesenforced
Earlier releases — v1.x
For v1.0.0 and v1.1.0 release notes (initial public release and the authenticated-write-tools / multi-account additions), see the canonical CHANGELOG.md in the repository.
Migration Guides
Upgrading to v3.0.0
v3 is a security and surface-reduction overhaul: read-only by default, an untrusted-content envelope, and a trimmed tool set. See the full v3 Migration Guide for details on enabling writes (ACTIVITYPUB_ENABLE_WRITES=true), the renamed/consolidated tools (search, get-public-timeline, discover-instances), and the removed tools and prompts.
Upgrading to v2.0.0
v2 introduces several breaking changes — most around security defaults and config formats. See the full v2 Migration Guide for before/after snippets covering:
- Setting
MCP_HTTP_SECRET+ an explicitMCP_HTTP_CORS_ORIGINSfor HTTP transport - Migrating
ACTIVITYPUB_ACCOUNTSfrom colon (:) to pipe (|) delimiter - Replacing
HEALTH_CHECK_ENABLEDwithHEALTH_CHECK_EXTERNAL_PROBE - Renaming MCP tool args:
scheduledId→scheduledPostId - Bumping your runtime to Node 20+
Upgrading to v1.0.0
No breaking changes from v0.9.0. Simply update your package:
npm update activitypub-mcp
Contributing
We welcome contributions to the ActivityPub MCP Server! Here’s how you can help:
Bug Reports
Found a bug? Please report it on our GitHub issues page with:
- Detailed description of the issue
- Steps to reproduce
- Expected vs actual behavior
- Environment information
Feature Requests
Have an idea for a new feature? We’d love to hear it:
- Describe the feature and its benefits
- Provide use cases and examples
- Consider implementation complexity
- Check existing issues first
Code Contributions
Ready to contribute code? Follow our guidelines:
- Fork the repository and create a feature branch
- Follow our coding standards and conventions
- Add tests for new functionality
- Update documentation as needed