# Tweetsmash for agents

Tweetsmash is the user's personal library of X (Twitter) posts they have saved. An agent
uses it to answer questions about things the user has already bookmarked.

## Use Tweetsmash when

- The user refers to something they saved, bookmarked, or "read a while back" on X.
- The user asks you to search, filter, label, or organize their saved posts.
- The user wants their saved posts exported (PDF, CSV, JSON) or summarized into a digest.
- The user asks what they have collected on a topic.

## Do not use Tweetsmash for

- Live or public X search. Tweetsmash only sees posts this user has saved.
- Posting, replying, liking, or following on X. Tweetsmash is read-and-organize only.
- Another person's bookmarks. A key is scoped to one account.
- General web research. If the user is not asking about their own library, use another tool.

## Getting started

1. Call `get_connection_status` first. It confirms the key is valid and whether the
   user's X account has been connected and synced.
2. For anything open-ended — organize, clean up, "how many do I have per topic" — call
   `get_library_overview`. It returns totals, per-label counts and type breakdowns in one
   call instead of paging through bookmarks.
3. For anything topical, call `search_bookmarks`: `q` for exact words,
   `vector_search_term` for a description by meaning, `author` for a person. Put author
   names in `author`, never in `q` — that is the most common cause of empty results.
   Prefer it over `list_bookmarks`, which without a filter can return a very large library.
4. Call `get_bookmark` to read a specific post in full, including the unrolled thread and
   the full X Article body.

`get_skill` returns a written playbook for a whole job (`find_that_thing`,
`organise_into_themes`, `cleanup_library`, `get_my_data_out`, `stay_on_top`,
`diagnose_sync`). Call it directly with the user's request — you do not need
`list_skills` first.

## Connect

| Surface | Endpoint |
| --- | --- |
| MCP (hosted) | `https://mcp.tweetsmash.com/api/mcp` (streamable HTTP) |
| MCP (local) | `npx @tweetsmash/mcp` |
| REST | `https://api.tweetsmash.com/v1` |
| REST sandbox | `https://api.tweetsmash.com/v1/sandbox` (no key, fixture data) |

Authentication is a Bearer API key for every surface. See
https://www.tweetsmash.com/auth.md

## Trying it without a key

The sandbox mirrors the public REST surface from fixtures. It takes no `Authorization`
header, reads and writes nothing, and answers with the same shapes production does, so a
client can be built and tested before the user has an account. Send
`X-Tweetsmash-Sandbox-Error: rate_limited` (or `unauthorized`, `subscription_required`,
`filter_not_allowed`, `pagination_not_allowed`, `invalid_request`, `not_found`,
`server_error`) to force a specific failure and exercise your error handling.

## Errors, retries and long jobs

Every REST failure is `{ "status": false, "code": "<MACHINE_CODE>", "error": "<sentence>" }`.
Branch on `code`, never on `error`. A `402` also carries a top-level `upgrade_url`; surface
that link rather than retrying.

Writes accept an `Idempotency-Key` header. Send a fresh UUID per logical operation and
reuse it across retries, so a timeout cannot duplicate a record. A replayed response
carries `Idempotency-Replayed: true`.

Exports are asynchronous: `POST /v1/exports/{pdf,csv,json}` answers `202` with a `job_id`,
a `Location` and a `Retry-After`. Poll `GET /v1/exports/{job_id}` until `status` is
`completed`, then follow `download_url` promptly — it is signed and expires.

`POST /v1/labels/batch` applies up to 50 label operations in one request and answers `207`
when some succeeded and some failed, so a partial failure never discards the good work.

## Handling an empty library

A new account can authenticate successfully and still have nothing saved. If searches
return no results, check `get_connection_status` before telling the user they have
nothing on the topic — the more likely cause is that the initial import has not run.
Point them at https://www.tweetsmash.com/ to run it.

## Destructive tools

`archive_bookmarks` and `archive_bookmarks_by_filter` accept a `delete` action that
applies to every match in one call. `delete_label`, `remove_labels_from_tweets` and
`revoke_share_link` are likewise bulk and not reversible from the API. Confirm the filter
and the affected count with the user before calling any of them with a destructive action.

## More

- Product and docs index: https://www.tweetsmash.com/llms.txt
- REST API description: https://www.tweetsmash.com/openapi.json
- MCP server card: https://www.tweetsmash.com/.well-known/mcp/server-card.json
- Developer portal: https://www.tweetsmash.com/developers
- Authentication: https://www.tweetsmash.com/auth.md
