# Sonket > Be first to reply when someone posts about you, and grow an account worth following. Read-only over X, Hacker News, YouTube and Bluesky. It never posts for you. Sonket watches the platforms you choose for posts worth replying to and tells you within minutes, with a draft written in your own voice. It then works on the account those readers land on: the profile, what to post next, and the shapes that work for people like you. It is read-only: it has no write access to any account, it never posts, likes, follows or messages, and it never will. You read the draft and post it yourself. ## What it does - Watches three kinds of channel: topics you want to be found in, mentions of you or your product, and specific accounts whose posts you want to be early on. - Checks as often as you set per project, every 5 to 60 minutes, only inside the hours you choose. - Judges every post with a small model before it reaches you, so the feed holds posts worth a reply rather than everything that matched. - Drafts a reply in your voice from a memory you write and own: lines about how you sound, what you build and what to keep away from, put whole in front of every draft rather than retrieved in pieces. You can start it from a CV, a page or pasted text, and a reply you actually sent adds a line when you ask it to. - Enforces a deboost guard before you post: limits the platforms are known to penalise, such as replies per hour, replies per day, replies to any one account, links, and near-duplicate replies. - Emails an alert from the run that found the post, for anything above the score you set. Telegram is next. ## Growing the account Replying is half of it. The other half works on the account people land on, off the same memory. - Checks your X profile row by row against what works there, scores it, and links every fix to the place you change it yourself. Sonket never edits your profile, and a check can be filled from the browser extension instead of from X, at no cost. - Writes post ideas from that memory, your profile and the posts that did best this week. Any figure it cannot source comes back as a blank for you to fill before the text can be copied. - Runs a named series: a brief in your own words, and the next post written from the brief and the ones already published. - Keeps examples, posts whose shape is worth copying, yours or anyone's. They are read at run time as shapes and never quoted back into anything you write. - Studies an account: one read of their last 50 posts becomes a pattern of how they open, how long they run and how often they post. Their shapes, never their sentences. - Plans a post on a calendar and emails you the draft that morning. It is a reminder, never a scheduler. ## Browser extension Free to download from the site for Chrome, Edge, Firefox and Opera, and in no store yet. It needs a Sonket API key; nothing in it works signed out. - One click sends the post you are reading with its text, link, author, date and counts, read off the page the browser has already drawn. No platform API call, and no charge for the read. - On a profile it saves the posts on screen as examples, notes how often that account posts from the dates alone, adds them as a peer, or starts watching them. - On your own profile it refreshes the profile check for free, with no read from X. - It never scrolls to stitch a page together, never calls a platform's own API, never reads your cookies or your login, and does nothing you did not click. ## Platforms - Live: X, Hacker News, YouTube and Bluesky. - Planned: Reddit. ## Pricing There is no free plan and no trial. You top up a balance and pay per blip, a post read and judged for you. Rates come from the site's own pricing config: - X: $0.015 a blip, $0.012 after 2,000 in a month - Hacker News, YouTube and Bluesky: $0.005 a blip - Top up by card from $10 to $100, or in crypto from $5. - Spend limits per day and per month are yours to set; reads pause at zero balance. - Bring your own keys: $9 a month to run Sonket on your own platform and model API keys, paying each provider directly, with no per-blip charge from Sonket. - An unspent top-up is refunded in full if you ask within 14 days; first use ends that. Full rules on the refunds page. ## Pages - [Home](https://sonket.com/): what Sonket watches, a live feed of what it found, and the pricing estimator. - [Privacy](https://sonket.com/privacy): what is stored, for how long, and who processes it. - [Terms](https://sonket.com/terms): the service terms. - [Refunds](https://sonket.com/refunds): the refund policy. ## MCP Sonket runs a tools-only MCP server at https://sonket.com/api/mcp, so an editor or a terminal can work a project without opening the dashboard. It authenticates with a bearer key made at https://sonket.com/mcp, read scope or write scope, and speaks one stateless JSON-RPC POST: no OAuth, no session, no stream. ```json { "mcpServers": { "sonket": { "type": "http", "url": "https://sonket.com/api/mcp", "headers": { "Authorization": "Bearer YOUR_KEY" } } } } ``` ### Capability groups - projects: list_projects, get_project, create_project, update_project, exclude_account, include_account, archive_project, restore_project - feed: list_blips, get_blip, draft_reply, save_draft, discuss_blip, mark_replied, dismiss_blip, favorite_blip, unfavorite_blip - watches: list_watches, get_watch, add_watch, update_watch, toggle_watch, delete_watch, list_groups, add_group, rename_group, delete_group, set_watch_group - people: list_people, get_person, watch_person, unwatch_person, note_rhythm - ideas: list_ideas, get_idea, suggest_posts, edit_idea, fill_idea, plan_idea, mark_posted, unmark_posted, dismiss_idea, discuss_idea, use_proposal, file_pasted_post, reply_to_pasted_post - calendar: get_calendar - series: list_series, get_series, create_series, update_series, archive_series, add_published_post, delete_series_post, learn_from_series - examples: save_example, list_examples, move_example, note_example, delete_example, complete_example, learn_from_examples - memory: list_memories, add_memory, edit_memory, toggle_memory, release_memory, remove_memory, note_memory, import_memory_text, import_memory_url, merge_memories, save_memory_lines, discard_memory_proposal - profile: get_profile, set_grow_platforms, set_grow_handle, set_peers, note_profile, sync_own_profile, skip_check, unskip_check, draft_bios, list_studies, set_study_posts_per_day, stop_study - notifications: get_notifications, update_notifications - usage: get_balance, get_limits, set_limits, topup_link - billing: billing_portal_link - byok: get_byok - account: get_account, list_sessions, sign_out_everywhere ### Constraints - Read-only against every platform. No tool posts, likes, follows or messages, here or anywhere else. - A tool that changes a row needs a write key, and is refused for the read-only demo account. - Nothing here reaches admin, the system keys or your own provider keys. - A tool that spends money or an AI action says so in its own description. - Email, password, sign-in links and account deletion are dashboard-only, at /settings?tab=signin; a key can never take over the account. - Your own platform and model keys are set at /byok and never over MCP: a key in a chat client is a key in a model's context. - Nothing that reads X runs over MCP yet: a profile refresh, a study scan and re-reading one blip's counts are dashboard actions with a price on the button. Starting a watch is here, and the polls after it are what it costs. - Every operation, with its inputs, its returns and its safety flags: https://sonket.com/docs/api. How to connect: https://sonket.com/docs/mcp. The model-readable summary of the same registry is https://sonket.com/llms-full.txt ## Contact - Support: support@sonket.com ## MCP reference How to reach the server and what it answers with, written out of the same registry the server answers `tools/list` from. The whole tool list, with the inputs of each, is a page rather than a file: https://sonket.com/docs/api. How to connect, in full: https://sonket.com/docs/mcp. ### Transport - POST https://sonket.com/api/mcp and nothing else. GET and DELETE answer 405 with `Allow: POST`. - Stateless JSON-RPC 2.0: one request in, one response out. A notification is answered 202 with no body. - Methods: `initialize`, `tools/list`, `tools/call`, `ping`. Batched requests are refused, since MCP dropped them in the 2025-06-18 revision. - Protocol versions spoken: 2025-06-18, 2025-03-26, 2024-11-05. Anything else negotiates to the newest. ### Auth - `Authorization: Bearer snk_sk_…`, a key made at https://sonket.com/mcp. There is no OAuth and no cookie. - A missing, unknown or revoked key is 401 with `WWW-Authenticate: Bearer realm="sonket"` and a JSON-RPC error body whose message names https://sonket.com/mcp. - A read key is never shown a write tool by `tools/list`, and is refused it if it calls one anyway. ### Results - A tool answers with one plain sentence, then the same facts as JSON in the same text block, and again in `structuredContent` for clients that read it. - A refusal is `isError: true` carrying the dashboard's own sentence for that refusal, never an invented one. A JSON-RPC error code is kept for what the transport got wrong: bad JSON, an unknown method. ### Key operations The few worth knowing before a call is made. Every other operation is named below and written out on https://sonket.com/docs/api. #### list_projects Purpose: List the caller's projects, live and archived, with the timezone, active hours and check interval of each. Scope: read Safety: readOnly true, destructive false, spends false Inputs: - include_archived (boolean, optional): Archived projects too. Off by default. Returns: Every project with its id, name, `handle` (the X handle Grow checks), timezone, active hours, check interval, never-show list, archived and showcase flags, and which one is the default. #### update_project Purpose: Change any of a project's settings: its name, timezone, active hours, check interval, whether X watches keep reposts and read quoted posts, or the accounts it never wants posts from. Send only the fields that change. Scope: write Safety: readOnly false, destructive false, spends false Inputs: - project_id (uuid, required) - name (string, optional) - timezone (string, optional): An IANA name, or UTC. - active_from_hour (integer, optional) - active_to_hour (integer, optional): 0 and 24 together mean every hour. The two hours may never be equal. - poll_every_minutes (number, optional): One of 5, 10, 20, 30 or 60 minutes. - include_reposts (boolean, optional): Keep reposts on an X account watch. A repost is filed as the post it points to, marked with who reposted it. Two post reads, so about double on those rows. - include_quotes (boolean, optional): Read the post an X post quotes. The quoted post's text comes along under it. One more post read on those rows. - exclude_accounts (array of { platform, handle }, optional): Replaces the whole never-show list. Send an empty array to clear it. Returns: The project as saved, every field, so a caller sees what the merge left. #### list_blips Purpose: List this project's blips: the posts worth replying to, best first. The defaults are the feed's own, the ones still waiting for a reply in the last 30 minutes. Scope: read Safety: readOnly true, destructive false, spends false Inputs: - project_id (uuid, required): The project. list_projects names them and marks the default. - status (new | notified | replied | dismissed, optional): One state. Left out, it lists the new and notified ones together, as the feed does. - group_id (uuid, optional): One of the project's watch folders. - min_score (integer, optional): Only blips scoring at least this. - platform (x | hn | youtube | bluesky | reddit, optional): Only blips from this platform. - replied (boolean, optional): True for the ones already answered, false for the rest. - favorited (boolean, optional): True for the starred ones, which ignore the state unless one is named. - since (string, optional): How far back to look. A window (30m, 2h, 6h, 24h, 7d, 30d) or an ISO time. - limit (integer, optional): How many rows, up to 100. 30 by default. - studied_only (boolean, optional): Only blips from an account this project studies, the feed's Studying mark. Returns: Each blip with its id, score and reasons, its state, the post itself with its author and counts, the watch it came from, its folder label, whether it is starred or studied, and the reply drafted for it when there is one. #### draft_reply Purpose: Write the reply draft for one blip, in this project's voice and memory. You copy it out and send it yourself: Sonket never posts. A blip that already has a draft gives it back and spends nothing. One AI action. Scope: write Safety: readOnly false, destructive false, spends true Inputs: - project_id (uuid, required): The project. list_projects names them and marks the default. - blip_id (uuid, required): The blip. list_blips names them. Returns: The draft, which save_draft edits and mark_replied records once it has been sent. #### list_watches Purpose: List a project's watches: what each looks for, the platforms it runs on with when each was last checked, whether it is on, its group and what it found this week. Scope: read Safety: readOnly true, destructive false, spends false Inputs: - project_id (uuid, required) Returns: One row a watch: id, kind, label, query and its terms, each platform with its last check and last error, enabled, group, reply notes, posts a day, and blips in the last 7 days; then the project's groups and the page's own summary line. #### list_people Purpose: Who showed up in this project's blips of the last 7 days, busiest first: what they posted, the watches they turned up in, whether you already watch them and whether you study them. Scope: read Safety: readOnly true, destructive false, spends false Inputs: - project_id (uuid, required) - limit (integer, optional): How many to return. 50 by default, as on the page, up to 500. - platform (x | hn | youtube | bluesky | reddit, optional): Only the people who posted on this platform. Returns: The people, each with their platform, handle, name, avatar, followers, profile link, label (Asker, Broadcaster, Sharer), the row's own summary line, posts and likes in the window, the watches they appeared in, how many times you replied to them, when they last posted, whether a watch is on them alone or shared with others, and whether they are studied; plus the total the window holds. #### suggest_posts Purpose: Write post ideas for this project from its memory, its profile, the week's best blips and the replies it sent. A figure no input carries comes back as a [N] blank to fill. One AI action. Scope: write Safety: readOnly false, destructive false, spends true Inputs: - project_id (uuid, required): The project. list_projects names them and marks the default. - platform (x | bluesky | hn, optional): Which platform to write for. Left out, the project's first live one. - count (integer, optional): How many, 1 to 5. One by default. - about ({ watch_id } | { series_id } | { study_id } | { examples } | { other }, optional): What the posts should be about, one of {"watch_id"}, {"series_id"}, {"study_id"}, {"examples": true} for the posts saved as examples, or {"other": "a topic in your own words"}. Left out, it is the whole week. Returns: The ideas written, each the shape list_ideas gives, and how many runs are left today. #### get_calendar Purpose: Read a month of this project's calendar: the posts planned on each day and the ones already published. To put a post on a day or move it to another, call plan_idea with the new day; plan_idea with null takes it off; unmark_posted puts a published one back as a draft. Sonket emails a reminder the morning of and never posts. Scope: read Safety: readOnly true, destructive false, spends false Inputs: - project_id (uuid, required): The project. list_projects names them and marks the default. - month (string, optional): YYYY-MM. Left out, the project's current month. Returns: The month, the project's own today, the window a post may be planned in, every day of the grid with its posts (id, hook, kind, platform and whether it is planned or posted), how many of each the month holds, and the ideas with no day on them yet. #### get_series Purpose: Read one series in full: the brief, the posts already published in it oldest first, the drafts waiting on it, and the memory lines learned from it. Editing those lines is the memory group's job, not this one's. Scope: read Safety: readOnly true, destructive false, spends false Inputs: - project_id (uuid, required) - series_id (uuid, required) Returns: The series row, its published posts oldest first with their number, hook, date and link, the new or planned drafts written for it, and its own memory lines with their kind and whether each is enabled. #### save_example Purpose: Keep a post someone else wrote as an example of a shape worth copying: the link, the text and whatever the page showed beside it. A run reads examples as shapes and never as sentences, so nothing here is ever quoted back. Nothing is fetched, no model runs, and it costs nothing. Scope: write Safety: readOnly false, destructive false, spends false Inputs: - project_id (uuid, required) - link (string, required): A link to the post on X, Bluesky or Hacker News, whose platform and author are read off it, or any https link when platform and author_handle are sent too. - text (string, required): The post as it reads, up to 2000 characters. Nothing is fetched to find it. - series_id (uuid, optional): Keep it for one series rather than the project's own pool. Left out is the pool. - note (string, optional): One line in the person's own words about why the post works, up to 280 characters. "The hook is a number, the last line is a question." - platform (string, optional): Where it was posted. Only read when the link is not one Sonket's parser knows. - author_handle (string, optional): Who posted it. Only read when the link does not name them. - author_name (string, optional): Their display name, as the page drew it. - avatar_url (string, optional): A link to their picture, https. - posted_at (string, optional): When it went out: an ISO instant, or YYYY-MM-DD in the project's timezone. - replies (integer, optional): How many replies the post had when you read it. - reposts (integer, optional): How many reposts the post had when you read it. - likes (integer, optional): How many likes the post had when you read it. - views (integer, optional): How many views the post had when you read it. - cut (boolean, optional): The page showed the post truncated, so the text is short of it. complete_example finishes it with one X read. - media (array of { type, url, poster }, optional): The pictures on the post, at most four kept. A video's url is its poster frame. - quoted ({ handle, name, text, url }, optional): The post it quotes, kept as a card under it and never a row of its own. - source (extension | paste | screenshot, optional): Which door it came through: the browser extension, or a paste. Paste by default. Returns: The example's id, whether the same link was already saved in this project, whether that second save raised its counts or filled a blank, and a link to the page it is listed on. #### list_memories Purpose: Read a project's written memory: the lines the drafter is told about what this person builds, who they talk to, how they write and what they never say. Scope: read Safety: readOnly true, destructive false, spends false Inputs: - project_id (uuid, required) - series_id (uuid, optional): List one series' own learned lines instead of the project's. - kind (product | audience | style | avoid | fact, optional): Only this kind: product (What you build), audience (Who you talk to), style (How you write), avoid (Never say), fact (Other). Returns: Every line with its id, kind, body, scope, whether it is enabled, who wrote it, its series and its position, plus how many lines and characters the project has used of the two caps. #### note_memory Purpose: Tell the project something about yourself or the product in a sentence, and get back the memory lines it becomes. Nothing is saved yet. One AI action. Scope: write Safety: readOnly false, destructive false, spends true Inputs: - project_id (uuid, required) - text (string, required): A sentence or two in your own words, up to 20000 characters. Returns: The proposed lines with the proposal_id to save them under. The proposed lines are not saved until save_memory_lines takes them. #### get_profile Purpose: Read a project's Grow profile: the platforms, the handle, the last profile read, the nine check rows with the score, the named peers and the studied accounts. The read is the stored one; refreshing it from X is a dashboard action. Scope: read Safety: readOnly true, destructive false, spends false Inputs: - project_id (uuid, required) Returns: The platforms and which are live, the handle, the stored snapshot with when it was read and whether that is a day old, the nine check rows with their state, reason, suggestion and whether they are skipped, the score, the bio drafts, the peers with their followers and whether each is watched or studied, and the studies with their pattern. #### update_notifications Purpose: Change what a project emails its owner: the daily recap, the hour it lands, and the alert that does not wait for it. Send only the fields that change. Scope: write Safety: readOnly false, destructive false, spends false Inputs: - project_id (uuid, required) - recap_enabled (boolean, optional): One email a day, what the watches found. - recap_hour (integer, optional): The hour it lands, 0 to 23, in the project's own timezone. - recap_skip_empty (boolean, optional): On a day the watches found nothing worth replying to, send nothing at all. - alert_min_score (null | 70 | 80, optional): Email the hour a blip scores this or higher: 70 or 80. Null is off. - alert_max_per_day (1 | 2 | 3 | 5, optional): A hard cap on those alerts: 1, 2, 3, 5. The rest wait for the recap. Returns: The settings as saved, every field, so a caller sees what the merge left. #### get_balance Purpose: Read the prepaid balance: what is left, what was spent this month, how many posts were read, and how many free AI actions are still going today. Scope: read Safety: readOnly true, destructive false, spends false Inputs: none Returns: The balance and the month's spend, each as a formatted string and as integer micros, the month's blips, AI actions used today with the free allowance and how many of it is left, whether the own-keys add-on is paid up, and whether the account is paused. #### set_limits Purpose: Change the caps that pause reading. Send only the ones that change. A spend limit is always on and cannot be zero; a blip limit is off when it is null. Scope: write Safety: readOnly false, destructive false, spends false Inputs: - daily_spend_usd (number, optional): Dollars a day, up to two decimals. Never off. - monthly_spend_usd (number, optional): Dollars a calendar month, at least the daily one. Never off. - daily_blips (null | integer, optional): Posts read a day. Null turns this one off. - monthly_blips (null | integer, optional): Posts read a calendar month, at least the daily one. Null turns this one off. Returns: The four caps as saved, with what is used under each. #### billing_portal_link Purpose: Return a link to the card provider's customer dashboard, where invoices, the card on file and any subscription are managed. It charges nothing and moves no money. Scope: read Safety: readOnly true, destructive false, spends false Inputs: none Returns: A single-use url into the provider's own hosted page, or the reason there is none. #### get_byok Purpose: Read whether the bring-your-own-keys add-on is on, when it lapses, what it costs, and which of the project's own X, YouTube and model keys are set. Keys and the subscription are set on the dashboard, never over MCP. Scope: read Safety: readOnly true, destructive false, spends false Inputs: none Returns: Whether the add-on is active and until when, its price and term, the project the keys belong to, and per key whether it is set with its last four characters. Never a key value. #### get_account Purpose: Read the Sonket account this key belongs to: the address on it, whether it has a password, which sign-in doors are connected and how many devices hold a session. No secrets, no tokens. Scope: read Safety: readOnly true, destructive false, spends false Inputs: none Returns: The handle and email, whether a password is set, the connected sign-in methods, the number of live sessions, and whether the address unsubscribed or its mail bounced. ### Every operation - projects: list_projects, get_project, create_project, update_project, exclude_account, include_account, archive_project, restore_project - feed: list_blips, get_blip, draft_reply, save_draft, discuss_blip, mark_replied, dismiss_blip, favorite_blip, unfavorite_blip - watches: list_watches, get_watch, add_watch, update_watch, toggle_watch, delete_watch, list_groups, add_group, rename_group, delete_group, set_watch_group - people: list_people, get_person, watch_person, unwatch_person, note_rhythm - ideas: list_ideas, get_idea, suggest_posts, edit_idea, fill_idea, plan_idea, mark_posted, unmark_posted, dismiss_idea, discuss_idea, use_proposal, file_pasted_post, reply_to_pasted_post - calendar: get_calendar - series: list_series, get_series, create_series, update_series, archive_series, add_published_post, delete_series_post, learn_from_series - examples: save_example, list_examples, move_example, note_example, delete_example, complete_example, learn_from_examples - memory: list_memories, add_memory, edit_memory, toggle_memory, release_memory, remove_memory, note_memory, import_memory_text, import_memory_url, merge_memories, save_memory_lines, discard_memory_proposal - profile: get_profile, set_grow_platforms, set_grow_handle, set_peers, note_profile, sync_own_profile, skip_check, unskip_check, draft_bios, list_studies, set_study_posts_per_day, stop_study - notifications: get_notifications, update_notifications - usage: get_balance, get_limits, set_limits, topup_link - billing: billing_portal_link - byok: get_byok - account: get_account, list_sessions, sign_out_everywhere Inputs, returns and safety flags for each: https://sonket.com/docs/api