# Apple Ads agent (/agents/apple_ads) ## What it does [#what-it-does] The Apple Ads agent tunes the campaigns of your app in the connected ad account: keyword bids, daily budgets, an ad group's default bid, pauses and re-enables of campaigns, ad groups and keywords, negative keywords and keyword additions. It never proposes creating a campaign. Its instructions keep a bid or a budget move within 20 % of the value it found, and a bigger step says why in its reason. Campaigns start in a chat. Once Apple Ads is connected, ask the chat to start your campaigns: the [apple-search-ads](https://kwern.app/skills/apple-search-ads) skill asks your monthly budget, lays out Brand, Category, Competitor and Discovery campaigns with a target cost per acquisition for each, and leaves each campaign as one **campaign** proposal, with its ad groups, keywords and ad. Nothing reaches Apple until you press **Publish** on it: Kwern then creates the campaign, its ad groups, their keywords and its ad through the connection, and the campaign starts enabled. A write Apple refuses fails the proposal with Apple's reason, and **Retry** picks up from what was already created. To change a campaign proposal, ask its chat again. The agent tunes the campaigns from its next run. Only the campaigns of this product's app are in scope. Nothing it decides touches the account on its own: every change waits in the approval feed until you approve it. ## When it runs [#when-it-runs] Weekly, so a change has time to show in the campaigns before the next one. It is off when the product is created, because an agent that spends money is opted into rather than out of, so you turn it on from its page when you want it working. The cadence comes from the agent and is not editable, and it carries no weekly cap: how often it looks is its own ceiling. ## What it needs [#what-it-needs] The [Apple Ads](https://kwern.app/connectors/apple-ads) connector, and an App Store surface — it works on the app your listing points at. Without the connection the agent is unavailable and does not run. ## What it reads [#what-it-reads] Before anything else, what Kwern knows about the product: the foundation doc, the growth plan and the product memory. Then the channel itself. * The campaigns of your app in the connected account, read live at the moment the run starts. Only those are in scope. * Their Apple Ads report over the last 30 days, synced the same day. * The search terms report, which is where a negative keyword has to come from. * Their ad groups, with status, Search Match, bid strategy and default bid, and the share of impressions on each search term, per country. * Apple's keyword and target cost per acquisition suggestions, and how often a term is searched, on request. * The listing's keyword field, when App Store Connect is connected too. * The monthly budget set on the agent's page, or the fact that none is set, next to what the month has spent so far. It is context, not a limit: a proposal may ask for more and says so in its reason, and your approval is the only gate. A campaign outside the scope is still refused, and so is an amount that is not above zero. ## What it leaves you [#what-it-leaves-you] Proposals in four categories: **bid**, **budget**, **keyword** and **pause**, which covers re-enabling as well as pausing. Apple Ads is a channel Kwern can write to, so each one ends on approval: you approve it in the feed and Kwern applies the change to the account itself. Editing an amount before approving is part of the flow, and the figure the agent first proposed is kept. ## The skills it runs [#the-skills-it-runs] It enters through [apple-search-ads](https://kwern.app/skills/apple-search-ads), and may activate [ads](https://kwern.app/skills/ads) and [analytics](https://kwern.app/skills/analytics) along the way. ## Editing its instructions [#editing-its-instructions] The agent's page in the app carries the instructions it is given at the start of every run, and you rewrite them there — narrower campaigns, a different bar for a pause, whatever you want it to weigh. The cadence is not editable. The switch reads on, off or paused, where paused means Kwern stopped it for a reason and will resume it when that reason clears. [Apple Ads connector](https://kwern.app/connectors/apple-ads) · [Apple Ads Agent](https://kwern.app/agents/apple_ads) · [All agents](https://kwern.app/agents) · [All connectors](https://kwern.app/connectors) # ASO agent (/agents/aso) ## What it does [#what-it-does] The ASO agent audits your App Store listing against the keywords, the reviews and the analytics of the week, and proposes the metadata changes and the review replies worth making. It argues with the listing you have rather than rewriting it wholesale. The private keyword field, the description, the promotional text and the release notes are all in front of it, next to what the App Store did that week. What it decides waits in the approval feed. ## When it runs [#when-it-runs] Weekly. It is on as soon as the product has an app surface, on the App Store or on Google Play, because auditing a listing spends nothing and publishes nothing on its own. It runs on the first day too, with whatever the product holds. The cadence comes from the agent and is not editable, and it has no weekly cap: once a week is the ceiling. ## What it needs [#what-it-needs] An app surface, on the App Store or on Google Play, and nothing else: without a connection it works from the public listing. The [App Store Connect](https://kwern.app/connectors/app-store) connector adds what only you can see, and a broken connection narrows what it reads without pausing it. ## What it reads [#what-it-reads] The foundation doc, the growth plan and the product memory first. Then the App Store listing. * The App Store Connect metadata of the latest version, read live: the title and subtitle in the app's primary language, the keyword field, the description, the promotional text, the release notes. * The App Store analytics synced that day: impressions, product page views and downloads, day by day and as far back as Apple's reports reach, with the page views, downloads and downloads made from a page summed overall and for each source of traffic. The agent reads the page conversion from those counts. When Apple has produced no report files yet, the agent is told so rather than handed zeros. * The most recent customer reviews, read live. * The public listing, which stands in whenever App Store Connect has nothing to say. * With [Apple Ads](https://kwern.app/connectors/apple-ads) connected, the search terms the ads turned into installs, and how often a term is searched. ## What it leaves you [#what-it-leaves-you] Proposals in two categories, **reply** and **listing**, and how each ends depends on what it touches. A review reply is posted from your developer account on approval. A change to the promotional text is written to App Store Connect on approval, the one field Apple lets a live version change without a review. Any other listing change that belongs in a file of the [connected repository](https://kwern.app/connectors/github) is delivered as a draft pull request on approval. A listing change with no file behind it has no approve: you apply it yourself and mark it as done. On Google Play, a listing change names the field it is for: the title (30 characters at most), the short description (80), the full description (4,000), or a picture slot (the icon, the feature graphic, the screenshots). Kwern never writes your Google Play listing: you paste the change into Play Console and mark it as done, or, when the connected repository keeps the listing files under `fastlane/metadata/android/`, approving it opens a pull request. Every run also saves the week's **App growth report** as an output, readable on the agent's page and by any later chat. It covers the organic figures (impressions, page views, downloads, and the downloads made from a page, from which the agent reads the page conversion); with Apple Ads connected, the week's spend against the monthly budget, installs, cost per tap and cost per install; the proposals you approved that week on the ASO and Apple Ads agents, and the Apple Ads proposals of your chats, campaigns included; and, with [RevenueCat](https://kwern.app/connectors/revenuecat) connected, revenue and ROAS for each Apple Ads campaign. When RevenueCat cannot name the campaigns yet, the report points you to the walkthrough that turns on its Apple Ads attribution. The week that closes a month also recaps that month. ## The skills it runs [#the-skills-it-runs] It enters through [aso](https://kwern.app/skills/aso), and may activate [metadata-optimization](https://kwern.app/skills/metadata-optimization), [review-management](https://kwern.app/skills/review-management) and [competitor-profiling](https://kwern.app/skills/competitor-profiling). ## Editing its instructions [#editing-its-instructions] The agent's page in the app carries the instructions it is given at the start of every run, and you rewrite them there — the tone of a review reply, the fields it should leave alone. The cadence is not editable. The switch reads on, off or paused, where paused means Kwern stopped it for a reason and will resume it when that reason clears. [App Store Connect connector](https://kwern.app/connectors/app-store) · [ASO Agent](https://kwern.app/agents/aso) · [All agents](https://kwern.app/agents) · [All connectors](https://kwern.app/connectors) # Competitors agent (/agents/competitors) ## What it does [#what-it-does] The Competitors agent re-reads the pages of every competitor your product lists and compares them with the versions before them. It then judges each change: a new price, a new plan, a repositioned home page or a shipped feature is worth your week, a reworded button is not. What survives that judgement becomes one digest, competitor by competitor, each entry saying what changed, what it means for your product and what to do about it. A week where nothing substantive moved is written up as nothing at all. ## When it runs [#when-it-runs] Weekly. It is on as soon as the product has a Site surface, because it only reads public pages and never proposes anything. The cadence comes from the agent and is not editable, and it has no weekly cap. ## What it needs [#what-it-needs] Nothing to connect. It reads what Kwern gathers itself. It does need a Site surface, and at least one competitor. A competitor is added by its URL — its home page, or its App Store or Google Play listing — and Kwern names it from that page. Without one there is no page to watch, and the run says which ones would be worth adding. ## What it reads [#what-it-reads] The foundation doc, the growth plan and the product memory first. Then the competitor watch: each competitor's homepage, plus the pricing, changelog, features, integrations and customers pages its home page links to, re-read whenever the site snapshot is rebuilt and kept alongside the version before them. A change is put in front of the agent once, so news it already read does not come round again. It can also search Hacker News for what people said about a competitor somewhere other than its own pages: a launch, a pricing thread, a comparison. That search is bounded to three queries a day for the product, and nothing behind a login or a paywall is read. ## What it leaves you [#what-it-leaves-you] Nothing in the approval feed. This agent only informs: it is never given the tool that proposes, so no approval is ever waiting because of it. What it leaves instead is one saved output, the week's digest, readable on the agent's page and by any later chat that asks what a competitor has been doing. A quiet week leaves a journal line and no digest. ## The skills it runs [#the-skills-it-runs] It enters through [competitor-profiling](https://kwern.app/skills/competitor-profiling), and may activate [competitors](https://kwern.app/skills/competitors) and [product-marketing](https://kwern.app/skills/product-marketing). ## Editing its instructions [#editing-its-instructions] The agent's page in the app carries the instructions it is given at the start of every run, and you rewrite them there — what counts as substantive for your market, which competitor deserves a closer read. The cadence is not editable. The switch reads on, off or paused, where paused means Kwern stopped it for a reason and will resume it when that reason clears. [Competitors Agent](https://kwern.app/agents/competitors) · [All agents](https://kwern.app/agents) · [All connectors](https://kwern.app/connectors) # GEO agent (/agents/geo) ## What it does [#what-it-does] The GEO agent audits how your product reads to the engines that answer questions. Every two weeks it asks your own model a fixed set of prompts and records whether you or a competitor came up, then names the page that should have earned the citation and says why it did not. Nothing it finds is a proposal. A site fix is a recommendation with a pull request behind it, so the audit writes the recommendation and a separate fix run writes the code. ## When it runs [#when-it-runs] Every 2 weeks. It is on as soon as the product has a Site surface, since auditing publishes nothing. One reading of what the engines answer means little on its own, so each audit waits for two weeks of it. The cadence comes from the agent and is not editable, and it has no weekly cap. After each audit, up to five fix runs start on the most urgent open recommendations that have no pull request yet. ## What it needs [#what-it-needs] The [GitHub](https://kwern.app/connectors/github) connector, and a Site surface. The reason is plain: a page is fixed by a pull request on the repository that serves it, so without the repository connected the agent has nothing to leave you and does not run. ## What it reads [#what-it-reads] The foundation doc, the growth plan and the product memory first. Then the site as an answer engine reads it. * The site snapshot, rebuilt that day: robots.txt, the sitemaps, the pages with their titles, meta, headings, canonicals, structured data and links, plus the files crawlers look for at the root such as `llms.txt`. * The week's visibility probe: up to fifteen prompts, derived from the foundation doc and editable by you, asked of your own model on your own provider key. When the probe cannot run, the audit runs on the site alone and says so. * The recommendations already open, so it weighs them instead of writing them twice. * The market-index reads of a Site surface, for what happens outside your own traffic. ## What it leaves you [#what-it-leaves-you] No proposals at all. It leaves **recommendations**: one per page and problem, rated critical or warning, kept from week to week. The fix runs that follow open one draft pull request each, and you approve a recommendation by merging that pull request or dismiss it for good. A later probe or crawl is what resolves one. ## The skills it runs [#the-skills-it-runs] It enters through [ai-seo](https://kwern.app/skills/ai-seo), and may activate [schema](https://kwern.app/skills/schema) and [competitors](https://kwern.app/skills/competitors). ## Editing its instructions [#editing-its-instructions] The agent's page in the app carries the instructions it is given at the start of every run, and you rewrite them there; the probe prompts are edited from the same place. The cadence is not editable. The switch reads on, off or paused, where paused means Kwern stopped it for a reason and will resume it when that reason clears. [GitHub connector](https://kwern.app/connectors/github) · [GEO Agent](https://kwern.app/agents/geo) · [All agents](https://kwern.app/agents) · [All connectors](https://kwern.app/connectors) # Google Ads agent (/agents/google_ads) ## What it does [#what-it-does] The Google Ads agent tunes the campaigns in scope on your account: daily budgets, CPA and ROAS targets, keyword bids, pauses, negative keywords and keyword additions. It never proposes creating a campaign or an ad group. Its instructions keep a budget, a target or a bid move within 20 % of the value it found, and a bigger step says why in its reason. Its skill tunes an App campaign through its budget and target, since an App campaign has no keywords, and takes a negative keyword from the search-terms report. A change Google refuses fails the proposal with Google's reason. Nothing reaches the account without your approval. Campaigns start in a chat. When the product has a site and Google Ads is connected, ask the chat to start your campaigns: the [google-ads](https://kwern.app/skills/google-ads) skill asks your monthly budget, lays out the Search campaigns, and leaves each campaign as one **campaign** proposal, with its budget, ad groups, keywords and responsive search ads. Nothing reaches Google until you press **Publish** on it: Kwern then creates the budget, the campaign, its ad groups, their keywords and its ads through the connection, and the campaign starts enabled. A write Google refuses fails the proposal with Google's reason, and **Retry** picks up from what was already created. To change a campaign proposal, ask its chat again. The agent tunes the campaigns from its next run. ## When it runs [#when-it-runs] Weekly, so a bid strategy is not pushed back into learning before it has read its conversions. It is off when the product is created, because an agent that spends money is opted into rather than out of, so you turn it on from its page when you want it working. The cadence comes from the agent and is not editable, and it carries no weekly cap. ## What it needs [#what-it-needs] The [Google Ads](https://kwern.app/connectors/google-ads) connector. Nothing else: this agent works on the whole product rather than on one surface, so an app and a website are both fair game for it. Without the connection it is unavailable and does not run. ## What it reads [#what-it-reads] The foundation doc, the growth plan and the product memory first. Then the account. * The campaigns in scope in the connected Google Ads account, read live at the moment the run starts. Only those may be touched. * Their Google Ads report over the last 30 days, synced the same day. * The search-terms report, which is where a negative keyword comes from. * The monthly budget set on the agent's page, or the fact that none is set, next to what the month has spent so far. It is context, not a limit: a proposal may ask for more and says so in its reason, and your approval is the only gate. A campaign outside the scope is still refused, and so is an amount that is not above zero. ## What it leaves you [#what-it-leaves-you] Proposals in five categories: **bid**, **budget**, **target**, **keyword** and **pause**. Google Ads is a channel Kwern can write to, so each one ends on approval: you approve it in the feed and Kwern applies the change to the account itself. You can edit an amount before approving, and the figure the agent first proposed is kept. ## The skills it runs [#the-skills-it-runs] It enters through [google-ads](https://kwern.app/skills/google-ads), and may activate [ads](https://kwern.app/skills/ads) and [analytics](https://kwern.app/skills/analytics). ## Editing its instructions [#editing-its-instructions] The agent's page in the app carries the instructions it is given at the start of every run, and you rewrite them there — which campaigns to leave alone, what a pause has to clear first. The cadence is not editable. The switch reads on, off or paused, where paused means Kwern stopped it for a reason and will resume it when that reason clears. [Google Ads connector](https://kwern.app/connectors/google-ads) · [Google Ads Agent](https://kwern.app/agents/google_ads) · [All agents](https://kwern.app/agents) · [All connectors](https://kwern.app/connectors) # Hacker News agent (/agents/hacker_news) ## What it does [#what-it-does] The Hacker News agent listens for the threads where your product genuinely belongs and drafts one reply per thread. Each reply answers what was asked first; the product is mentioned only when it is the answer, and never as a pitch. It also drafts the Show HN pitch, but only when there is something finished enough for people to try — three angles on the same launch for you to pick from. It runs every two days, so the threads it reads are the ones posted since it last looked. ## When it runs [#when-it-runs] Every 2 days. It is on when the product is created: it reads a public index, spends nothing and posts nothing by itself. The cadence comes from the agent and is not editable, and it carries no weekly cap. Most days hold no thread worth answering, which is why it looks every other day rather than every day; a thread that lives and dies between two runs is missed. ## What it needs [#what-it-needs] Nothing to connect. Hacker News is read through its public index, so this agent works on any product from the first day. ## What it reads [#what-it-reads] The foundation doc, the growth plan and the product memory first, which is what a thread is scored against. Then the public index of Hacker News stories and Ask HN and Show HN threads, five queries a day for the product — the endpoint is free, which is exactly why Kwern holds itself to a handful of searches. Nothing behind a login is read. It also remembers the threads it has already answered: one reply per thread, ever. ## What it leaves you [#what-it-leaves-you] Proposals in two categories. A **reply** carries the thread it answers, so you can read the room before you use it. A **post** is the Show HN pitch, with its three angles side by side. Kwern cannot write to Hacker News, so neither of them has an approve. You copy the text, post it from your own account and mark the proposal as done — or reject it, which is the same click it always is. ## The skills it runs [#the-skills-it-runs] It enters through [community-marketing](https://kwern.app/skills/community-marketing), and may activate [social](https://kwern.app/skills/social). ## Editing its instructions [#editing-its-instructions] The agent's page in the app carries the instructions it is given at the start of every run, and you rewrite them there — the kind of thread that is worth answering, how close to the launch a Show HN should be. The cadence is not editable. The switch reads on, off or paused, where paused means Kwern stopped it for a reason and will resume it when that reason clears. [Hacker News Agent](https://kwern.app/agents/hacker_news) · [All agents](https://kwern.app/agents) · [All connectors](https://kwern.app/connectors) # Influencers agent (/agents/influencers) ## What it does [#what-it-does] The Influencers agent finds the people on X whose posts already reach your audience and drafts the message you send each of them. It searches the words the audience itself uses, and sends one search after your product's name for the people already mentioning it. Size is a filter, not the point: it keeps authors with 1,000 to 50,000 followers who posted in the last fourteen days, keeps people over brands, and drops anyone it cannot write one true personalised sentence for. Five a run, fewer when fewer are worth it. ## When it runs [#when-it-runs] Weekly. It is off when the product is created: every run spends Kwern's own search key looking at people you may never want to write to, so this one is opted into rather than out of. The cadence comes from the agent and is not editable, and it carries no weekly cap beyond the five people a run. ## What it needs [#what-it-needs] The [X](https://kwern.app/connectors/x) connector. Without it the agent is unavailable and does not run, and a deployment holding no search key finds nobody and proposes nothing. ## What it reads [#what-it-reads] The foundation doc, the growth plan and the product memory first, which is what fit is judged against. Then X: up to ten searches a run, original posts only, from the last fourteen days, grouped by author with the followers, the profile and the account age a shortlist is judged on. Your own handle is left out, and so is everyone this agent has already proposed — a handle is proposed once, ever. It is also told which words its past runs already searched, so a run goes somewhere new. ## What it leaves you [#what-it-leaves-you] Proposals in one category, **outreach**: one person each, carrying their handle, their bio, their followers, the post that surfaced them and why they fit. The message is in your brand voice, in the language that person posts in, under 500 characters, with no link in the body and anything only you know left in brackets. Kwern never contacts, pays or tracks anyone. There is no approve on these: you send the message yourself and mark the proposal as done. Where the offer is early access, an affiliate share or a paid mention, the draft ends on its disclosure sentence, because all three are paid partnerships. ## The skills it runs [#the-skills-it-runs] It enters through [community-marketing](https://kwern.app/skills/community-marketing), and may activate [social](https://kwern.app/skills/social) and [copywriting](https://kwern.app/skills/copywriting). ## Editing its instructions [#editing-its-instructions] The agent's page in the app carries the instructions it is given at the start of every run, the approach and the offer and the follower band among them, and you rewrite them there. The cadence is not editable. The switch reads on, off or paused, where paused means Kwern stopped it for a reason and will resume it when that reason clears. [X connector](https://kwern.app/connectors/x) · [Influencers Agent](https://kwern.app/agents/influencers) · [All agents](https://kwern.app/agents) · [All connectors](https://kwern.app/connectors) # LinkedIn agent (/agents/linkedin) ## What it does [#what-it-does] The LinkedIn agent keeps your posts planned a week ahead, in the maker's own voice. It reads the Calendar first and drafts a post for each coming day that has none on LinkedIn, each on its own day and hour and on the angle its rotation hands it. The rotation has five: behind-the-scenes, lessons, a contrarian take, a milestone and a customer story. Each post takes the next one in order, and the rotation moves on by as many posts as the run proposed, so a week of posts does not say the same thing five times. The agent keeps the link out of the body. It writes the link as the first comment and attaches it to the proposal, where it waits with the post. ## When it runs [#when-it-runs] It runs as a Loop, on from the moment the connection exists, since nothing leaves without your approval. Each run fills the days of the coming week the Calendar leaves empty, so the channel still posts every day while the agent runs only every few days; a run that finds the week covered ends with no proposal. The cadence comes from the agent, shows on its page and is not editable, and it carries no weekly cap: rejecting the posts you do not want is the throttle. ## What it needs [#what-it-needs] The [LinkedIn](https://kwern.app/connectors/linkedin) connector. Without it the agent is unavailable and does not run. ## What it reads [#what-it-reads] The foundation doc, the growth plan and the product memory — the positioning, the brand voice and what past approvals taught this product. LinkedIn gives Kwern nothing to read back, so the rotation's angles and the Calendar are the only things the channel itself puts in front of the model, together with the 3,000-character limit a post has to fit. That is the whole briefing. It is also why this agent leans harder on the foundation doc than any of the listening ones. ## What it leaves you [#what-it-leaves-you] Proposals in the **post** category. LinkedIn is a channel Kwern can write to, so the proposal ends on approval: you edit the text if you want to, and the post arrives planned for a day and an hour, so **Approve for Tue 09:00** agrees to that hour and Kwern publishes it from your account then and links you to it. **Publish**, in the schedule menu beside the button, sends it at once. The first comment is the exception. LinkedIn's API grants Kwern no comment write, so the link stays with the proposal for you to paste under the post yourself. ## The skills it runs [#the-skills-it-runs] It enters through [jab-hook](https://kwern.app/skills/jab-hook), and may activate [social](https://kwern.app/skills/social) and [copywriting](https://kwern.app/skills/copywriting). ## Editing its instructions [#editing-its-instructions] The agent's page in the app carries the instructions it is given at the start of every run, and you rewrite them there — how long a post should be, which of the five angles matter for your audience, what never to write about. The cadence is not editable. The switch reads on, off or paused, where paused means Kwern stopped it for a reason, an expired LinkedIn token among them, and will resume it when that reason clears. [LinkedIn connector](https://kwern.app/connectors/linkedin) · [LinkedIn Agent](https://kwern.app/agents/linkedin) · [All agents](https://kwern.app/agents) · [All connectors](https://kwern.app/connectors) # Reddit agent (/agents/reddit) ## What it does [#what-it-does] The Reddit agent finds the threads where your product genuinely belongs and drafts one or two replies a run, one per thread, on the threads where a reply adds the most, in the maker's own voice. The reply adds what the best comments have not said yet, and mentions the product only when it is the answer. Reddit is posted by hand, and the agent is built around that: every proposal carries the thread URL, so the draft and the place it belongs travel together. ## When it runs [#when-it-runs] Daily. It is on when the product is created: there is nothing to connect, and nothing can leave without you. The cadence comes from the agent and is not editable, and it carries no weekly cap. A day's threads are what a day's run works from. ## What it needs [#what-it-needs] Nothing to connect. Kwern reads the public threads, so this agent works on any product from the first day. Your Reddit account only comes in when you post a reply. ## What it reads [#what-it-reads] The foundation doc, the growth plan and the product memory first: the positioning and the brand voice are what a thread is judged against and what the reply sounds like. Then Reddit, in two steps: 1. **It finds the threads.** It searches recent public threads, across Reddit or inside one subreddit you name in the instructions, in the words your audience uses rather than your product's name. 2. **It reads each thread before it drafts.** For a thread worth a reply, it reads the opening post, the best comments and the subreddit's rules. A subreddit whose rules leave no room for a maker's reply gets none. Each search and each thread read is paid out of your plan's usage, at the price the [pricing page](https://kwern.app/pricing) lists. It also remembers the threads it has already proposed, so the same thread does not come back a second time. ## What it leaves you [#what-it-leaves-you] Proposals in one category, **reply**, each with the thread it answers. Kwern cannot write to Reddit, so there is no approve on them: you open the thread, post the reply from your own account and mark the proposal as done. Rejecting one is the same click it always is, and you can edit the text before you copy it. ## The skills it runs [#the-skills-it-runs] It enters through [community-marketing](https://kwern.app/skills/community-marketing), and may activate [social](https://kwern.app/skills/social). ## Editing its instructions [#editing-its-instructions] The agent's page in the app carries the instructions it is given at the start of every run, and you rewrite them there: the subreddits worth reading, the kind of question worth answering, the words that never belong in a reply. The cadence is not editable. The switch reads on, off or paused, where paused means Kwern stopped it for a reason and will resume it when that reason clears. [Reddit Agent](https://kwern.app/agents/reddit) · [Reddit connector](https://kwern.app/connectors/reddit) · [All agents](https://kwern.app/agents) · [All connectors](https://kwern.app/connectors) # SEO agent (/agents/seo) ## What it does [#what-it-does] The SEO agent rebuilds your site snapshot every week and audits the site against it: what the crawl found, what Search Console says, what the link profile says, and what moved since last week. It does not write the fixes itself. The crawl leaves recommendations, and separate fix runs turn the most urgent ones into draft pull requests on the repository that serves the pages. ## When it runs [#when-it-runs] Weekly. It is on as soon as the product has a Site surface, since an audit publishes nothing. The cadence comes from the agent and is not editable, and it has no weekly cap. After each audit, up to five fix runs start on the most urgent open recommendations that have no pull request yet. ## What it needs [#what-it-needs] The [GitHub](https://kwern.app/connectors/github) connector, and a Site surface. The reason is plain: a page is fixed by a pull request on the repository that serves it, so without the repository connected the agent has nothing to leave you and does not run. [Search Console](https://kwern.app/connectors/search-console) is not required — the audit runs with or without Google, and reads it when the property is bound. ## What it reads [#what-it-reads] The foundation doc, the growth plan and the product memory first. Then the site. * The site snapshot, rebuilt that day: robots.txt, the sitemaps, the pages with their titles, meta descriptions, headings, canonicals, Open Graph, structured data and links, plus the files at the root of the site. * The recommendations already open, so a page that no longer has the problem is closed rather than reported again. * Search Console over the last 30 days when the property is bound, ranking drops included. * The link profile, refreshed the same week from the market index: the referring domains, what was gained and lost over thirty days, and the anchor text those links say. ## What it leaves you [#what-it-leaves-you] No proposals. It leaves **recommendations**: one per problem, on a page or on the site itself, rated critical or warning and kept from one crawl to the next. The fix runs that follow open one draft pull request each; you approve a recommendation by merging its pull request, or dismiss it for good. Core Web Vitals go to the journal rather than into the queue. ## The skills it runs [#the-skills-it-runs] It enters through [seo-audit](https://kwern.app/skills/seo-audit), and may activate [schema](https://kwern.app/skills/schema), [site-architecture](https://kwern.app/skills/site-architecture) and [competitors](https://kwern.app/skills/competitors). ## Editing its instructions [#editing-its-instructions] The agent's page in the app carries the instructions it is given at the start of every run, and you rewrite them there — the pages that matter, the problems you would rather it left alone. The cadence is not editable. The switch reads on, off or paused, where paused means Kwern stopped it for a reason and will resume it when that reason clears. [GitHub connector](https://kwern.app/connectors/github) · [SEO Agent](https://kwern.app/agents/seo) · [All agents](https://kwern.app/agents) · [All connectors](https://kwern.app/connectors) # Writer agent (/agents/writer) ## What it does [#what-it-does] The Writer agent writes the day's article from your content roadmap, one keyword at a time. It takes the first entry still planned and writes it whole: 800 to 2,000 words of Markdown in your brand voice, on that entry's target keyword and in its article type, with the title, meta description, slug and image prompt that go with it. The roadmap itself is the agent's work too. The first run of the month plans the next twelve to thirty articles, in the order they get written, from the evidence Kwern already holds. A run that finds no planned entry plans the next ones, then writes the first. ## When it runs [#when-it-runs] It is off when the product is created: not every site has a blog, and an article nobody publishes is a day of your model's time for nothing. Its weekly cap is yours: three articles a week as it ships, anywhere from one to seven on the agent's page. The agent runs on that many days of the week, spread from Monday, one article a run. ## What it needs [#what-it-needs] Nothing to connect, and a Site surface. Publishing is yours either way, so the agent works from what Kwern already reads. ## What it reads [#what-it-reads] The foundation doc, the growth plan and the product memory first — the brand voice is what the article has to sound like. Then the content roadmap, the article types to choose from, how many articles the cap leaves this week, and the keywords it has written on in the last ninety days, which are refused a second time. When it is planning rather than writing, it reads the month's evidence instead: the queries the site nearly ranks for, the keywords a competitor takes, the prompts an answer engine gave a competitor, the questions the community agents found, and the competitors digest. ## What it leaves you [#what-it-leaves-you] Proposals in one category, **article**, with the body and the front matter side by side. Kwern does not publish to a blog: there is no approve, so you publish the piece yourself and mark the proposal as done. The Run checks the body against the copywriting Skill's AI tells before the proposal is filed. ## The skills it runs [#the-skills-it-runs] It enters through [content-strategy](https://kwern.app/skills/content-strategy), and may activate [copywriting](https://kwern.app/skills/copywriting), [copy-editing](https://kwern.app/skills/copy-editing), [seo-audit](https://kwern.app/skills/seo-audit), [ai-seo](https://kwern.app/skills/ai-seo) and [competitors](https://kwern.app/skills/competitors). ## Editing its instructions [#editing-its-instructions] The agent's page in the app carries the instructions it is given at the start of every run, and you rewrite them there; the roadmap is edited from the same place, with its version history. The cadence is not editable. The switch reads on, off or paused, where paused means Kwern stopped it for a reason and will resume it when that reason clears. [Writer Agent](https://kwern.app/agents/writer) · [All agents](https://kwern.app/agents) · [All connectors](https://kwern.app/connectors) # X posts agent (/agents/x) ## What it does [#what-it-does] The X posts agent keeps your own posts planned a week ahead. It reads the Calendar first, what is already scheduled or waiting on X and on LinkedIn, then listens before it writes: a handful of searches for what your audience is talking about, then a post in your brand voice for each coming day that has none on X, each on its own day and hour. The week is spread across your product's three to five content pillars, the topics it owns, each post on one of them, with promotion kept to the small share the [social](https://kwern.app/skills/social) skill gives it. On the skill's thread days the post is a thread, built on the key takeaways of one of your published articles when the Calendar lists one. Every draft follows the agent's X playbook: the hooks, formats and calls to action that work for the high-engagement accounts of your niche. Links stay out of the body — they belong in a first reply. A post that quotes somebody else's post is built from what the search returned, never from text the model retyped, so what you read on the proposal is what X served. ## When it runs [#when-it-runs] It runs as a Loop, on from the moment the connection exists, since nothing is posted without your approval. Each run fills the days of the coming week the Calendar leaves empty, so the channel still posts every day while the agent runs only every few days; a run that finds the week covered ends with no proposal and says through which day it is covered. The cadence comes from the agent, shows on its page and is not editable, and it carries no weekly cap: rejecting the posts you do not want is the throttle. ## What it needs [#what-it-needs] The [X](https://kwern.app/connectors/x) connector. Without it the agent is unavailable and does not run. Replying to other people's posts is a separate agent, [X replies](https://kwern.app/agents/x_replies), on its own switch. ## What it reads [#what-it-reads] The foundation doc, the growth plan and the product memory first. Then X. * Your own posts and what they did, synced into a connector snapshot at the start of the run, so the agent writes against its own results rather than in the dark. * Its X playbook, kept as a data output. When it is missing, or your best posts contradict it, the agent rebuilds it before drafting from the top posts of 10 to 20 high-engagement accounts of your niche, the accounts the X replies agent engages with first, and saves it again. * The day's search, up to five queries for this agent: the threads worth learning from, the angles a post could take. Kwern reads through its search service and falls back to the official API only when that refuses, and a day where X cannot be read at all is written from the product alone. ## What it leaves you [#what-it-leaves-you] Proposals in the **post** category — your own post, or a quote of a post one of the searches returned. X is a channel Kwern can write to, so a proposal ends on approval: you edit the text if you want to, and the post arrives planned for a day and an hour, so **Approve for Tue 09:00** agrees to that hour and Kwern posts it from your account then and links you to it. **Publish**, in the schedule menu beside the button, sends it at once. A publish that fails can be retried, or marked as done if you posted it yourself in the meantime. A quote has no approve: X's API no longer takes quotes, so you copy the text, open the quoted post from its link, quote it from your account and mark the proposal as done. ## The skills it runs [#the-skills-it-runs] It enters through [jab-hook](https://kwern.app/skills/jab-hook), and may activate [social](https://kwern.app/skills/social) and [copywriting](https://kwern.app/skills/copywriting). ## Editing its instructions [#editing-its-instructions] The agent's page in the app carries the instructions it is given at the start of every run, and you rewrite them there — what to listen for, how long a post should be, the subjects that are yours and the ones that are not. The cadence is not editable. The switch reads on, off or paused, where paused means Kwern stopped it for a reason and will resume it when that reason clears. [X connector](https://kwern.app/connectors/x) · [X Post Agent](https://kwern.app/agents/x) · [All agents](https://kwern.app/agents) · [All connectors](https://kwern.app/connectors) # X Communities agent (/agents/x_communities) ## What it does [#what-it-does] The X Communities agent finds the X Communities where your audience gathers, tells you which ones to join and why, and drafts a post for each Community your account joined. Each post is written for that Community's members, in the shape of the posts they already answer, and gives them something before it mentions what you build. A post inside a Community is shown to its members whether or not they follow you, so for a new account it is one of the few posts seen from the first day. Kwern also shares it with your followers, as the "Also share with followers" box does on x.com. ## When it runs [#when-it-runs] It runs as a Loop every few days, off until you turn it on: its posts only go out from an account that joined each Community, and X lets no app join one. Join the Communities it names in X's app, then turn it on. ## What it needs [#what-it-needs] The [X](https://kwern.app/connectors/x) connector. Without it the agent is unavailable and does not run. It shares the connection with [X posts](https://kwern.app/agents/x) and [X replies](https://kwern.app/agents/x_replies). ## What it reads [#what-it-reads] The foundation doc, the growth plan and the product memory first, then X's Communities, searched by what your audience talks about. X bills each Community a search returns, and Kwern takes it from your plan's Usage. For each Community worth a post, it reads the Community's page through Kwern's search service: its rules and its latest posts, with the replies each drew. X's own API serves neither. When the rules cannot be read, the draft says so. A Community whose rules ask members to post from their own personal account gets no post from your Product's account, and stays out of the list of Communities to join. It also reads its own past proposals: a Community it already posted into is one your account joined, and a post that failed carries X's reason. ## What it leaves you [#what-it-leaves-you] Proposals in one category, **post**, each aimed at one Community and planned for an hour your X calendar leaves free. Approving agrees to that hour; Kwern then posts it inside the Community from your account. A post into a Community your account has not joined fails with X's own reason, and nothing else goes out. Each run also saves a short report naming the Communities worth joining that you have not joined yet, each with its link and why it fits. ## The skills it runs [#the-skills-it-runs] It enters through [community-marketing](https://kwern.app/skills/community-marketing), and may activate [social](https://kwern.app/skills/social) and [copywriting](https://kwern.app/skills/copywriting). ## Editing its instructions [#editing-its-instructions] The agent's page in the app carries the instructions it is given at the start of every run, and you rewrite them there: the Communities to stay out of, the kind of post a Community should get. The cadence is not editable. The switch reads on, off or paused, where paused means Kwern stopped it for a reason and will resume it when that reason clears. [X connector](https://kwern.app/connectors/x) · [X Community Agent](https://kwern.app/agents/x_communities) · [All agents](https://kwern.app/agents) · [All connectors](https://kwern.app/connectors) # X replies agent (/agents/x_replies) ## What it does [#what-it-does] The X replies agent works the daily engagement routine of the [social](https://kwern.app/skills/social) skill. It answers the replies and mentions under your own posts first, then the accounts you engage with, then the day's posts where your product genuinely belongs, and drafts one reply to each. A reply answers what was said first; the product is mentioned only when it is the answer, and never as a pitch. Each draft comes with one sentence saying why that post is worth answering. The post itself is carried as X served it, with its author, its text, its date, its numbers and its link, rather than as the model retyped it. ## When it runs [#when-it-runs] It runs as a daily Loop, off until you turn it on: its reads of X are billed to your plan's Usage. The cadence comes from the agent and is not editable, and it carries no weekly cap; what bounds a day is the search budget and the rule that a thread is answered once, ever. ## What it needs [#what-it-needs] The [X](https://kwern.app/connectors/x) connector. Without it the agent is unavailable and does not run. Writing your own posts is a separate agent, [X posts](https://kwern.app/agents/x), on its own switch, and the two share the same connection. ## What it reads [#what-it-reads] The foundation doc, the growth plan and the product memory first: the positioning is what decides whether a post is one you belong under, and the brand voice is what the reply sounds like. Then the replies and mentions of your X account, read from X's own list for it: X's search leaves out much of what new accounts write, so this is how the agent sees who answered you. X bills each post and author that read returns, and Kwern takes it from your plan's Usage. Then the circle: the accounts your product engages with, which the agent keeps as a data output and rereads every run, so it builds on yesterday's list rather than starting over. Then X, searched up to five times a day for this agent. Kwern reads through its search service and falls back to the official API only when that refuses; a day where X cannot be read leaves the agent nothing to answer. Every post a search returns is kept for the length of the run, and a reply can only be drafted for a post the run actually read. ## What it leaves you [#what-it-leaves-you] Proposals in one category, **reply**. Each reads in three parts: what the post said and what Kwern proposes beneath it, who wrote it, and why this post. X's API no longer lets Kwern reply to most posts, so there is no approve on them: you edit the reply if you want to, copy it, open the post from its link, post the reply from your own account and mark the proposal as done. Kwern reads no metrics back for a reply it did not post. Beside the replies, proposals in two more categories, paced by the skill's daily routine: **engagement**, a like or a repost of a post, or a follow of its author, and **outreach**, a direct message to a new connection, written ready to paste. Kwern's X access cannot make any of them, so they carry no approve either: you open the post, or the author's profile for a follow or a message, do it from your own account and mark the proposal as done. ## The skills it runs [#the-skills-it-runs] It enters through [community-marketing](https://kwern.app/skills/community-marketing), and may activate [social](https://kwern.app/skills/social). ## Editing its instructions [#editing-its-instructions] The agent's page in the app carries the instructions it is given at the start of every run, and you rewrite them there — what a post has to say before it deserves an answer, how long a reply should be, the conversations to stay out of. The cadence is not editable. The switch reads on, off or paused, where paused means Kwern stopped it for a reason and will resume it when that reason clears. [X connector](https://kwern.app/connectors/x) · [X Reply Agent](https://kwern.app/agents/x_replies) · [All agents](https://kwern.app/agents) · [All connectors](https://kwern.app/connectors) # App Store Connect (/connectors/app-store) ## What you need [#what-you-need] An App Store Connect account with the right to create a team API key, and a product in Kwern whose App Store surface points at the app. App Store Connect reads the app of that surface, so a product with no App Store surface cannot bind it. ## Connect it [#connect-it] 1. **Open App Store Connect** — Kwern needs a team API key. Apple issues them under Users and Access · Integrations · Team Keys. [Open App Store Connect](https://appstoreconnect.apple.com/access/integrations/api) 2. **Generate a key** — Click Generate API Key, name it Kwern and pick the role App Manager. Sales and Reports would read the sales figures only. 3. **Issuer ID** — Copy the Issuer ID shown at the top of the page. 4. **Key ID** — Copy the Key ID of the row you just created. 5. **The .p8 file** — Download the API key. Apple offers the download once; drop the file here. It is stored encrypted and never shown again. 6. **Check** — Asking App Store Connect which apps this key can read… An account connected from **Settings › Accounts** is not linked to any product yet: open the product's **Apps** page to link it. ## What Kwern reads [#what-kwern-reads] A snapshot a day, from Apple's own analytics reports: impressions, product page views and downloads. The first sync loads as much history as Apple still holds; each later one adds the days since and overwrites any day Apple restated. Those three numbers accumulate as the connector's series, so an agent can ask for a range a year from now and get an answer. Two more reads happen live, at the moment an agent looks: the listing metadata it argues with — keywords, description, release notes — and the customer reviews. ## What Kwern can change [#what-kwern-can-change] Two fields, and only after you approve: * a **reply to a review**, posted from your developer account * the **promotional text** of the live version, the one App Store field Apple allows without a review Every other listing change is delivered as a pull request on the [connected repository](https://kwern.app/connectors/github) instead, so the words land in the file you keep them in. ## The agents that use it [#the-agents-that-use-it] The [ASO agent](https://kwern.app/agents/aso) reads through it: the private metadata, the analytics and the reviews you can answer. Without the connection it still runs, on the public listing. ## When it breaks [#when-it-breaks] A key whose role is read-only is refused on a write and keeps reading; the connection stays healthy and the proposal is marked failed with the reason. A revoked or expired key marks the account as needing attention, and the ASO agent reads the public listing until you reconnect. Reconnecting repairs it. [App Store Connect connector](https://kwern.app/connectors/app-store) · [All connectors](https://kwern.app/connectors) · [ASO agent](https://kwern.app/agents/aso) # Apple Ads (/connectors/apple-ads) ## What you need [#what-you-need] An Apple Ads account where you can add an API user, under **Account Settings · API**. Apple grants no third-party OAuth here, so the connection is a key pair rather than a login. ## Connect it [#connect-it] 1. **Open Apple Ads** — Kwern reads campaigns through an API user. Apple Ads creates them under Account Settings · API. [Open Apple Ads](https://ui.ads.apple.com/settings/apicertificates) 2. **Generate a key pair** — Kwern creates the pair and keeps the private half. You upload the public half in Apple Ads. The public key stays valid 60 minutes. Generate it when Apple Ads is open and ready. I already have an API user: - **The private key** — Drop the private key that already signs for the API user, or paste it. Nothing is uploaded to Apple, so its other integrations keep working. It is stored encrypted and never shown again. 3. **Create the API user** — Add an API user, paste the public key and give it a role that reads and writes campaigns on at least one ad account. 4. **Client ID, Team ID, Key ID** — Apple Ads shows the three ids together once the API user exists. 5. **Check** — Asking Apple Ads which ad accounts this user can act on… An account connected from **Settings › Accounts** is not linked to any product yet: open the product's **Apps** page to link it. ## What Kwern reads [#what-kwern-reads] A 30-day report a day: the campaigns in scope with their impressions, taps, spend and installs, their ad groups with status, Search Match and default bid, the keywords of those campaigns with their match type and current bid, the search terms that actually triggered an ad, and the share of impressions on each search term. Impressions, taps, spend and installs accumulate as the connector's series. One ad account may serve several apps. The report is reduced to the campaigns in scope before anything reads it, so another app's spend never enters a snapshot or a run. ## What Kwern can change [#what-kwern-can-change] Keyword bids, daily budgets, an ad group's default bid, pauses and re-enables, negative keywords and keyword additions, each as a proposal you approve. The agent never creates a campaign, and its instructions keep a bid or a budget move within 20 % of its current value unless it says why. Campaigns are created from a chat instead: ask the chat to start your campaigns, and it lays out the campaigns from your monthly budget and proposes each one whole, as one proposal. Publishing it creates the campaign, its ad groups, keywords and ad through this connection, and the campaign starts enabled. Because approving spends money, the scope is checked again at the moment you approve, not only when the draft was written: a campaign outside the scope you set is refused whatever the agent decided. The monthly budget on the agent's page is context for its runs, not a limit Kwern enforces. ## The agents that use it [#the-agents-that-use-it] The [Apple Ads agent](https://kwern.app/agents/apple_ads) needs it. It is off by default, because turning it on is a decision to let something move live spend. ## When it breaks [#when-it-breaks] An API user without a write role reads fine and is refused on a write; the proposal is marked failed with Apple's reason. A revoked key marks the account as needing attention and pauses the agent. [Apple Ads connector](https://kwern.app/connectors/apple-ads) · [All connectors](https://kwern.app/connectors) · [Apple Ads agent](https://kwern.app/agents/apple_ads) # GitHub (/connectors/github) ## What you need [#what-you-need] A repository you can install a GitHub App on. The repository should be the one that actually serves the site, because that is where a site fix has to land. ## Connect it [#connect-it] Open **Settings · Add an account** and press **Connect GitHub**. GitHub asks you to install Kwern's App and to pick the repositories it may see. Kwern stores the installation id and nothing else: every call mints a fresh token from it, and you revoke the whole thing from your GitHub settings in one click. A personal access token would have carried everything you can see. The App carries what you picked. Then open the product's **Apps** page, press **Choose what Kwern reads** and choose the **GitHub repository**. You can add a **root path** inside it, so one repository can back several products. ## What Kwern reads [#what-kwern-reads] A repo snapshot pinned to one commit of the default branch: * the files that describe the product: README, docs, changelog, store metadata, translations and pricing * the open issues * the latest releases Secrets and binaries are never read. The paths are a curated list, not the whole tree. ## What Kwern can change [#what-kwern-can-change] One thing: a pull request. A branch cut from the head of the default branch, one commit carrying the change, and a pull request left open for you. **Merges happen on GitHub, never in Kwern.** A proposal's pull request is never merged automatically; you read it, change it and merge it like any other. Two things arrive that way: a site fix from an SEO or GEO recommendation, and a listing change that belongs in a file of the repository rather than in the App Store itself. ## The agents that use it [#the-agents-that-use-it] The [SEO agent](https://kwern.app/agents/seo) and the [GEO agent](https://kwern.app/agents/geo) both need it. Both fix pages, and a page is fixed by a pull request on the repository that serves it: without one they audit and have nothing to propose. ## When it breaks [#when-it-breaks] Uninstalling the App marks the account as needing attention and pauses the agents that depend on it. Recommendations only exist while a repository backs the product, and go with it. [GitHub connector](https://kwern.app/connectors/github) · [All connectors](https://kwern.app/connectors) · [SEO agent](https://kwern.app/agents/seo) # Google Ads (/connectors/google-ads) ## What you need [#what-you-need] A Google account with access to the Google Ads customer account, and the manager account above it when you reach it that way. ## Connect it [#connect-it] Open **Settings · Add an account** and press **Connect Google Ads**. It is a **separate grant** from [Search Console and Analytics](/connectors/search-console), even on the same Google account: revoking one leaves the other working. Then open the product's **Apps** page, press **Choose what Kwern reads** and choose the **Google Ads account**. You can narrow the scope to specific campaigns; left empty, the scope is every campaign of the account. ## What Kwern reads [#what-kwern-reads] A 30-day report a day: * the **campaigns** and **ad groups** in scope, with their impressions, clicks, spend and conversions * the **keywords** of the manual-bidding campaigns, with their match type, status and bid — the others carry no bid to set * the **search terms** that actually triggered an ad Impressions, clicks, spend and conversions accumulate as the connector's series. Google attributes conversions late, so each sync re-reads a week of overlap. ## What Kwern can change [#what-kwern-can-change] Bids, daily budgets, CPA and ROAS targets, pauses, negative keywords and keyword additions, each as a proposal you approve. The agent never creates a campaign or an ad group, and its instructions keep a change within 20 % of its current value unless it says why. When the product has a site, campaigns are created from a chat instead: ask the chat to start your campaigns, and it lays out Search campaigns from your monthly budget and proposes each one whole, as one proposal. Publishing it creates the budget, the campaign, its ad groups, keywords and ads through this connection, and the campaign starts enabled. Because approving spends money, the scope is checked again at the moment you approve: a campaign outside the scope you set is refused. The monthly budget on the agent's page is context for its runs, not a limit Kwern enforces. ## The agents that use it [#the-agents-that-use-it] The [Google Ads agent](https://kwern.app/agents/google_ads) needs it. It is off by default, because turning it on is a decision to let something move live spend. ## When it breaks [#when-it-breaks] Kwern's daily Google Ads quota is shared by every Kwern account, so a run reads what the question needs in one query rather than paging through the account. A revoked grant marks the account as needing attention and pauses the agent until you reconnect. [Google Ads connector](https://kwern.app/connectors/google-ads) · [All connectors](https://kwern.app/connectors) · [Google Ads agent](https://kwern.app/agents/google_ads) # Google Analytics 4 (/connectors/google-analytics) ## What you need [#what-you-need] A Google account with read access to the GA4 property, and a product whose Site surface points at the site the property measures. ## Connect it [#connect-it] The same authorization as [Search Console](/connectors/search-console): one **Connect Google** in **Settings · Add an account** asks for both read-only scopes. If the Google account is already connected, you do not authorize anything again. Open the product's **Apps** page and choose the **GA4 property**. It is its own connector: you can bind the property without binding a Search Console site, or the other way round. ## What Kwern reads [#what-kwern-reads] A snapshot a day: * **sessions**, **users**, **new users**, **page views** and the **engagement rate** of the window * the **traffic channels** and the **landing pages** behind them Sessions, users, new users, page views and conversions accumulate as the connector's series, day by day and never windowed. ## What Kwern can change [#what-kwern-can-change] Nothing. The scope is `analytics.readonly`: every read answers and every change comes back refused. Kwern cannot create a property, an audience or a conversion, and reads no individual — the reports come back as counts by channel and by landing page. ## The agents that use it [#the-agents-that-use-it] No agent needs it to run. Search Console stops at the click; Analytics is what happened after it, and it is how the [SEO](https://kwern.app/agents/seo) and [GEO](https://kwern.app/agents/geo) agents tell a page that ranks from a page that works. It is what the **Traffic** tab of Analytics charts. ## When it breaks [#when-it-breaks] A GA4 property spends a token quota shared by everyone reading it, hourly and daily, and a broad report costs thousands of them. Kwern asks for the dimensions the question needs and reads the quota the response carries, rather than paging through the property. If the quota is exhausted by another tool, the sync fails for the day and the previous snapshot stays latest; the series is extended only once the source answered. [Google Analytics connector](https://kwern.app/connectors/google-analytics) · [All connectors](https://kwern.app/connectors) · [SEO agent](https://kwern.app/agents/seo) # Google Play (/connectors/google-play) ## What you need [#what-you-need] A Play Console account with the right to invite users, and a product in Kwern whose Google Play surface points at the app. Google Play reads the package of that surface. Connect it during onboarding, from **Finish setup**, from the product's **Apps** page, or from **Settings › Accounts**, which connects every product whose Google Play app is not connected yet. There is no key to create and nothing to paste but one id. Kwern makes a Google service account for you, with no key, and you invite it into Play Console like a colleague. ## Connect it [#connect-it] 1. **Copy the email** — Kwern made a Google service account for you, with no key. Copy its email: it is the user you invite in Play Console. 2. **Invite it** — In Play Console, open Users and permissions, click Invite new users and paste the email. [Open Play Console](https://play.google.com/console/users-and-permissions) 3. **Tick two permissions** — Under Account permissions, tick Reply to reviews, and View app information and download bulk reports. Leave the access expiry date empty, then send the invitation. 4. **Bucket id** — In Play Console, open Download reports, then Statistics, and click Copy Cloud Storage URI next to the heading. Paste it here as it is. [Open Statistics reports](https://play.google.com/console/download-reports/statistics) 5. **Wait for Google** — Asking Google Play whether Kwern is let in… Google can take up to 48 hours to pass the invitation on. Kwern checks again every hour for 48 hours and starts reading as soon as it is let in. Nothing else to do. One Play developer account is one connection. Invite Kwern once: each product with an app in that account connects to the same account and reads its own package only. ## What Kwern reads [#what-kwern-reads] * **Reviews**, every one, synced daily, with the reply already posted if there is one. On the first sync Kwern also fills the history from Google's monthly review files, rating-only reviews included. * **Visitors and installs**, day by day, from Google's bulk reports: visitors, installs, conversion by country and by traffic source, and ratings. Google publishes a day three to seven days late, so the **Google Play** tab of Analytics shows the latest day Google has published, and a day not published yet is missing rather than zero. * **Search terms**, the ones that brought visitors to your listing, which the ASO agent's weekly briefing starts from. The invitation reaches every app of the developer account. Kwern reads only the files named after the packages your products are bound to. ## What Kwern can change [#what-kwern-can-change] One thing, and only after you approve: a **reply to a review**, posted to Google Play from the service account. Google refuses a reply over 350 characters, so Kwern refuses it before it reaches you. Kwern never writes your listing. A listing change is copied into Play Console by you and marked as done, or delivered as a pull request when the [connected repository](https://kwern.app/connectors/github) holds the listing files (`fastlane/metadata/android/`). ## The agents that use it [#the-agents-that-use-it] The [ASO agent](https://kwern.app/agents/aso) reads through it: the reviews worth answering, the visitors and installs, and the search terms. Without the connection it still runs, on the public listing. ## When it breaks [#when-it-breaks] Google can take up to 48 hours to pass an invitation on. Until it does, the account reads **Waiting for Google** and Kwern checks again every hour. If 48 hours pass without access, the account is marked as needing attention and **Reconnect** reopens the steps on the invitation: check the email, the two permissions and the bucket id, then send it again. When Google blocks a step on Kwern's side (an account it could not create, a quota reached), Kwern says so and asks you to try again later: there is nothing to fix on yours. Deleting your Kwern account deletes the service account Kwern made for you, so no identity you invited outlives it. Remove it from **Users and permissions** in Play Console too if you want the invitation gone. [Google Play connector](https://kwern.app/connectors/google-play) · [All connectors](https://kwern.app/connectors) · [ASO agent](https://kwern.app/agents/aso) # LinkedIn (/connectors/linkedin) ## What you need [#what-you-need] The LinkedIn profile you want to post from. Kwern posts from a member profile, not from a company page. ## Connect it [#connect-it] Open **Settings · Add an account** and press **Connect LinkedIn**. LinkedIn asks you to authorize three scopes: your identity, your basic profile, and the right to post on your behalf. Your email address is never asked for, because nothing in Kwern reads it. Then open the product's **Apps** page and press **Choose what Kwern reads**. The member is the resource; there is nothing to pick: check it and press **Confirm**. ## What Kwern reads [#what-kwern-reads] Your name, once, to label the account. That is all. LinkedIn's self-service products grant no analytics, so Kwern cannot read a post's impressions, your followers or a company page. It says so rather than pretending the numbers are on their way. ## What Kwern can change [#what-kwern-can-change] A post arrives planned for a day and an hour, and on approval Kwern publishes it from your profile at that hour; **Publish** sends it at once. A post over three thousand characters, the cap LinkedIn sets, is refused before it is sent. LinkedIn grants Kwern no right to comment, so the **first comment stays with the proposal** for you to paste once the post is up. That is where the link goes. ## The agents that use it [#the-agents-that-use-it] The [LinkedIn agent](https://kwern.app/agents/linkedin) needs it. It plans a post for each coming day of the week that has none, rotating through five angles — behind the scenes, lessons, a contrarian take, a milestone, a customer story — so a channel that posts every day does not say the same thing five days running. ## When it breaks [#when-it-breaks] The grant lasts **sixty days** and LinkedIn issues no refresh token. Kwern shows the expiry on the account in Settings, marks it as expiring, and pauses the agent when it runs out. Press **Reconnect** and everything the breakage paused goes back on. [LinkedIn connector](https://kwern.app/connectors/linkedin) · [All connectors](https://kwern.app/connectors) · [LinkedIn agent](https://kwern.app/agents/linkedin) # PostHog (/connectors/posthog) ## What you need [#what-you-need] A PostHog account with a project, on either region. Kwern connects as a public client with no secret: its client id is the address of a metadata document Kwern publishes, which is what PostHog reads to identify it. ## Connect it [#connect-it] Open **Settings · Add an account** and press **Connect PostHog**. PostHog asks you to authorize four read scopes: your user, the organization, the projects and the query engine. Nothing that could create a dashboard, an insight, a feature flag or an event. Kwern remembers which region your grant lives on and goes back to that host on every refresh, so a project in the EU is never queried against the US host. Then open the product's **Apps** page, press **Choose what Kwern reads** and choose the **PostHog project**. ## What Kwern reads [#what-kwern-reads] Three HogQL queries per sync, whatever the range. The snapshot itself holds only the host, the project id and its name; the numbers live in the connector's series: * **active users**, **new users**, **sessions**, **events** * **paywall views** and **paywall viewers** * one line per **event name** your app sends, so nothing PostHog counts is left behind The first sync reads the whole life of the project. Every later one re-reads the days since the last sync plus a week of overlap, because events arrive after the day they belong to. ## What Kwern can change [#what-kwern-can-change] Nothing. The grant is read-only and no proposal targets PostHog. The queries return counts; no person is read. ## The agents that use it [#the-agents-that-use-it] No agent needs PostHog to run. It is where a marketing claim meets what people actually did, and what the **Usage** tab of Analytics charts. A product can bind a different PostHog project per product, and one account may hold several. ## When it breaks [#when-it-breaks] A revoked grant marks the account as needing attention. Reconnecting repairs it and puts back whatever the breakage paused. If your PostHog account moves region, reconnect: the host is part of the stored grant. [PostHog connector](https://kwern.app/connectors/posthog) · [All connectors](https://kwern.app/connectors) · [How a product is set up](/products) # RevenueCat (/connectors/revenuecat) ## What you need [#what-you-need] A RevenueCat account with at least one project. The grant RevenueCat issues is developer-level and covers every project of the account, so one account is one connection in Kwern. ## Connect it [#connect-it] Open **Settings · Add an account** and press **Connect RevenueCat**. RevenueCat asks you to authorize Kwern; the scopes it asks for are the overview metrics, the charts, the projects and the apps, all read-only. Then open the product's **Apps** page, press **Choose what Kwern reads** and choose the **RevenueCat project**. ## What Kwern reads [#what-kwern-reads] The project's overview metrics, each with the period RevenueCat gives it: a live figure, or a 28-day window. From those, five lines accumulate day by day as the connector's series: * **MRR**, **active subscriptions** and **active trials** — the standing figure of each day * **revenue** and **new customers** — what that day brought Every figure is read in US dollars. Left to the account's display currency, a series would change denomination the day somebody switched the dashboard. Every day ever seen is kept and never windowed, so a range you ask for a year from now still answers. A sync re-reads the days since the last one plus a week of overlap, because payments settle late. ## Apple Ads revenue per campaign [#apple-ads-revenue-per-campaign] With Apple Ads connected to the same product, the ASO agent's weekly App growth report puts the revenue RevenueCat attributes to each Apple Ads campaign next to that campaign's spend, as ROAS per campaign. RevenueCat names the campaign only on its Advanced Apple AdServices integration. Until it does, the **Revenue** page offers **Turn on attribution**, which walks these steps: 1. **Collect the AdServices token** — Apple mints the attribution token on the device, so only your app can hand it to RevenueCat. Call enableAdServicesAttributionTokenCollection() right after Purchases.configure, in the build your users run (iOS 14.3 or later). [Open RevenueCat's guide](https://www.revenuecat.com/docs/integrations/attribution/apple-search-ads) 2. **Choose Advanced** — In RevenueCat, open the project's Integrations, then Apple AdServices, and choose Advanced. Basic ties revenue to Apple Ads but never to a campaign name. [Open RevenueCat](https://app.revenuecat.com) 3. **Sign in with Apple** — Advanced asks you to Sign in with Apple. Use an Apple Ads user who is Account Admin or Campaign Group Manager, and pick Read Only: RevenueCat only reads the names. 4. **Expect data within 7 days** — RevenueCat can take up to 7 days to name campaigns, and names only what comes after. Kwern's daily syncs pick the names up, and the weekly App growth report then gives ROAS per campaign. Apple attributes no install from an ad group that targets by age or gender, so its revenue never reaches a campaign. Nothing is stored along the way: Kwern's daily syncs are the check, and the page stops offering the steps once campaign names appear. ## What Kwern can change [#what-kwern-can-change] Nothing. There is no RevenueCat proposal and no RevenueCat publisher: the grant Kwern holds reads and cannot write. No customer identifier, no email and no receipt is read either — the overview metrics and the project list, and nothing per person. ## The agents that use it [#the-agents-that-use-it] No agent needs RevenueCat to run. Its numbers are what every agent reads as the product's reality — whether a listing change is worth making, whether an ad budget is worth defending — and what the **Revenue** tab of Analytics charts. ## When it breaks [#when-it-breaks] RevenueCat allows 25 charts and metrics calls a minute per key, so Kwern caches the overview for fifteen minutes: a dashboard render, an agent run and the daily sync never race each other into a rate limit. Refresh tokens live thirty days and rotate on use; Kwern renews an idle grant before it dies. A revoked grant marks the account as needing attention until you reconnect. [RevenueCat connector](https://kwern.app/connectors/revenuecat) · [All connectors](https://kwern.app/connectors) · [How a product is set up](/products) # Google Search Console (/connectors/search-console) ## What you need [#what-you-need] A Google account that owns the Search Console property for your site, and a product whose Site surface points at that site. ## Connect it [#connect-it] Open **Settings · Add an account** and press **Connect Google**. Google asks for two read-only scopes at once: Search Console and Analytics. Kwern keeps the refresh token, so the grant survives the hour-long access token without sending you back to Google every morning. Then open the product's **Apps** page and bind what you want read. One Google account gives two connectors, bound independently: * the **Search Console site** * the **GA4 property**, documented in [Google Analytics 4](/connectors/google-analytics) Binding one does not oblige you to bind the other. ## What Kwern reads [#what-kwern-reads] A snapshot a day for the site: * **clicks**, **impressions**, **CTR** and **average position** for the window * the **queries** and the **pages** behind them, head first, twenty-five rows of each * the **drops**: the queries with at least fifty impressions that fell three places or more since the window before, with what they used to rank and what they lost Clicks, impressions, CTR and position accumulate as the connector's series. A total over a range sums the clicks and the impressions and takes CTR and position as the mean of the days weighted by impressions, which is the only honest way to average a rate. ## What Kwern can change [#what-kwern-can-change] Nothing. The scope is `webmasters.readonly`: submitting a sitemap, adding a property or deleting one all come back refused from Google, whatever an agent decides. ## The agents that use it [#the-agents-that-use-it] The [SEO agent](https://kwern.app/agents/seo) reads it every week, against what its own crawl found. That comparison is the difference between a page that is broken and a page that is simply losing. The agent does not need the connection to run — it needs a [repository](https://kwern.app/connectors/github) for that — but its audit is thin without it. ## When it breaks [#when-it-breaks] Revoking Kwern in your Google account revokes Search Console and Analytics together, and marks the account as needing attention. [Google Ads](/connectors/google-ads) is a separate grant and keeps working. [Search Console connector](https://kwern.app/connectors/search-console) · [All connectors](https://kwern.app/connectors) · [SEO agent](https://kwern.app/agents/seo) # Stripe (/connectors/stripe) ## What you need [#what-you-need] A Stripe account. One Stripe account is one connection in Kwern, and the account is what a product reads. ## Connect it [#connect-it] Open **Settings · Add an account** and press **Connect Stripe**. Stripe opens the install screen of Kwern's Stripe App, shows the permissions it asks for, and asks you to accept them on the account you choose. An install made on a Sandbox or in test mode reads and writes test data only; its connection is labelled **(test)**. Then open the product's **Apps** page and press **Choose what Kwern reads**, check the account and press **Confirm**. ## What Kwern reads [#what-kwern-reads] The app reads subscriptions, invoices, charges, balance transactions, products, prices, coupons and promotion codes. From them, these lines accumulate day by day as the connector's series: * **MRR**, **active subscriptions** and **active trials** — the standing figure at the end of each day * **new subscriptions**, **cancellations** and **gross revenue** — what that day brought * **referred customers**, **conversions**, **referred revenue**, **commissions earned** and **commissions paid** — what the creators' codes brought that day (see [Affiliate commissions](#affiliate-commissions)) Stripe has no MRR figure of its own, so Kwern computes it from the subscriptions active at the end of the day: each price times its quantity, brought to a month. Discounts are left out, so MRR is the list price of what is subscribed to. Gross revenue is the charges that succeeded that day, before refunds and fees. Every figure is in one currency: the one most of your subscriptions are priced in, picked on the first sync and kept. A price or a charge in another currency stays out of MRR and revenue. The **Revenue** tab of Analytics charts these, the affiliate lines included, beside RevenueCat's when the product has both, each under its own name and never added together. ## What Kwern can change [#what-kwern-can-change] Coupons and promotion codes, and nothing else: no payment, refund, payout, subscription or customer. Stripe refuses any other write, whoever asks. In practice Kwern writes one thing on its own: a **promotion code for an influencer offer**. 1. On the Influencers agent's settings, list the offers you are ready to make. A Stripe offer names a coupon you created in Stripe (the terms: a percentage off, for how long), how many times each code may be redeemed, and how many days it lives. 2. Each message the agent drafts picks one of your offers and names a code for that person, such as `MAYA-GYMUP`. 3. When you mark the message as sent, Kwern makes that promotion code on your coupon, with the cap, the expiry and first-time customers only. A code is made once, whatever retries happen. 4. Each daily sync reads back how often every such code was redeemed, and the next run of the agent reads it. If Stripe refuses the code (another active code already has that name, the coupon was deleted), the proposal fails with Stripe's own reason. A creator redeems the code wherever your checkout accepts promotion codes: Checkout with promotion codes allowed, a Payment Link, or the customer portal. ## Affiliate commissions [#affiliate-commissions] Kwern works out each creator's affiliate commission from what their code brought, on your own invoices. 1. An **affiliate offer** names a Stripe coupon and a commission: a percentage, for so many months from each customer's first payment. 2. When you mark the message as sent, Kwern makes the creator's code on that coupon, as for any Stripe offer. 3. Each daily sync reads the paid invoices and the refunds on their charges. A customer whose first discounted invoice carries a code Kwern made is that creator's referred customer. Every invoice that customer pays within the offer's months, counted from their first payment, earns the creator its percentage, net of refunds. 4. Once a month the Influencers agent proposes the payouts due: one per creator owed, with how much, where to pay and the commissions it covers. A commission that fails its fraud check comes as a proposal to remove it. 5. You pay outside Kwern, by PayPal or bank transfer, then mark the payout as done. Its commissions count as paid from then on. Kwern moves no money. Two things are left out. A credit note that credits the customer's balance, or an amount settled outside Stripe, is not netted from a commission. A code redeemed in a one-time Checkout payment that makes no invoice is not counted. ## The agents that use it [#the-agents-that-use-it] The Influencers agent mints its offer codes here and proposes the affiliate payouts they earn. Every other agent reads the revenue as the product's reality. ## When it breaks [#when-it-breaks] Access tokens last an hour and are renewed on use; the refresh token behind them lives a year from its last use, so a connection the daily sync reads never expires. Uninstalling the app in Stripe marks the account as needing attention until you connect it again. [Stripe connector](https://kwern.app/connectors/stripe) · [All connectors](https://kwern.app/connectors) · [How a product is set up](/products) # X (/connectors/x) ## What you need [#what-you-need] The X account you want to post from. The account is the resource, so there is nothing to pick after the authorization. ## Connect it [#connect-it] Open **Settings · Add an account** and press **Connect X**. X asks you to authorize four scopes: read a post, write a post, read your profile, and stay connected. The last one is the refresh, without which the grant would die every two hours. Then open the product's **Apps** page and press **Choose what Kwern reads**, check the account and press **Confirm**. ## What Kwern reads [#what-kwern-reads] Two different things, by two different routes. **The day's conversation.** The listening agents search X for the posts where the product genuinely belongs, and read each one with the author behind it: the handle, the bio, the follower count, when the account was created, and what the post itself said. A product may make **twenty-five X reads a day**. X bills every post its API returns, and a chat has no run to count against, so the budget sits on the product. **Your own numbers.** Impressions and clicks on the posts Kwern itself published, for as long as X serves them, which is thirty days. Nothing else is read back: X grants no private metric for an account that is not yours. ## What Kwern can change [#what-kwern-can-change] On approval, Kwern posts your own posts and Threads from your account. A post arrives planned for a day and an hour, so approving it sends it at that hour rather than on the click; **Publish** sends it at once. Nothing goes out unapproved. A reply to somebody else's post, and a quote of one, you post yourself: X's API no longer lets Kwern reply to most posts or quote any. The proposal carries the post's link, so you copy the text, open the post, post it from your account and mark the proposal as done. A link in the body of a post costs reach, so the agents keep it out and put it in a first reply. ## The agents that use it [#the-agents-that-use-it] Three, all of them needing this connection: * [X posts](https://kwern.app/agents/x) plans your own posts a week ahead * [X replies](https://kwern.app/agents/x_replies) answers other people's threads * [Influencers](https://kwern.app/agents/influencers) finds the people whose posts already reach your audience ## When it breaks [#when-it-breaks] A revoked grant marks the account as needing attention and pauses the three agents. Reconnecting repairs them. If the daily read budget is spent, a run answers from what it already has rather than failing. [X connector](https://kwern.app/connectors/x) · [All connectors](https://kwern.app/connectors) · [X posts agent](https://kwern.app/agents/x) # Image generation (/image-generation) ## What it is [#what-it-is] The model Kwern draws a post's picture with, and the key that pays for it. It is its own setup, apart from the Provider key your runs cost on: changing the model your runs use never changes who draws your pictures, and deleting the Provider key leaves it as it is. Pictures are drawn by Google, OpenAI or xAI. A key from that provider is all it takes. ## Set it up [#set-it-up] 1. **Pick the image model** — Pick the model that draws your pictures. Each sits under the provider that serves it, and the key comes from that provider. - Google: gemini-3.1-flash-image, gemini-3-pro-image - OpenAI: gpt-image-2, gpt-image-2.5-flare, gpt-image-2.5-sunburst - xAI (Grok): grok-imagine-image-2.0 2. For the provider of the model picked: - Google AI Studio: **Open Google AI Studio** — Kwern runs on a key of yours. Google AI Studio issues them in Google AI Studio, under Get API key. [Open Google AI Studio](https://aistudio.google.com/apikey) - OpenAI: **Open OpenAI** — Kwern runs on a key of yours. OpenAI issues them in the OpenAI platform, under API keys. [Open OpenAI](https://platform.openai.com/api-keys) - xAI: **Open xAI** — Kwern runs on a key of yours. xAI issues them in the xAI Console, under API Keys. [Open xAI](https://console.x.ai) 3. **Choose the key** — Use a key Kwern already holds for this provider, or create one and paste it here. A pasted key is stored encrypted and never shown again. 4. For the provider of the model picked: - Google AI Studio: **Check** — Asking Google AI Studio whether this key can draw… - OpenAI: **Check** — Asking OpenAI whether this key can draw… - xAI: **Check** — Asking xAI whether this key can draw… Only the models listed can be picked, so Kwern knows what each picture costs. When Kwern already holds a key for the provider you picked, the key step offers it: your Provider key, or the key your image setup already uses. Reusing it copies the key into the image setup, so replacing your Provider key later does not change it. ## Chat models that draw are not offered [#chat-models-that-draw-are-not-offered] OpenAI's chat models that draw pictures themselves, such as gpt-6-luna, are not among the choices: an images endpoint takes an image model and turns a chat model down, so their pictures would be drawn on gpt-image-2 anyway. An image setup already stored on one keeps drawing on gpt-image-2 with the same key, and editing it starts on gpt-image-2. ## Turning it off [#turning-it-off] Image generation can be switched off in **Settings** without forgetting the model or the key, so switching it back on asks for nothing. # Kwern documentation (/) The handbook: one page per connector, one per agent, plus the MCP server and how a product is set up. * Start with [Products and surfaces](/products): one URL becomes a product, and its surfaces decide which agents and connectors exist. * [The MCP server](/mcp) exposes your products, their foundation doc, the Proposals and the skills library to any MCP client. * **Connectors** explain how to connect each service, screen by screen. * **Agents** explain what each Loop reads, what it proposes, how often it runs and how to edit its instructions. Every page is also served as Markdown at the same address with `.md` appended, and the whole handbook is one file at [/llms-full.txt](/llms-full.txt). # The MCP server (/mcp) ## What it is [#what-it-is] A remote MCP server at `https://api.kwern.app/mcp`. It reads and writes Kwern's data: your products, their foundation doc, growth plan and memory, their connector snapshots, their approval feed, their recommendations and their journal, plus the open skills library. It also calls your connectors' own APIs for your agent, signed by Kwern, so your credentials stay in Kwern. It never runs a skill, never starts an agent, and never spends a token on Kwern's side. The model on the other end is yours. ## Add it to a client [#add-it-to-a-client] In Claude Code: ``` claude mcp add --transport http kwern https://api.kwern.app/mcp ``` Any MCP client that speaks streamable HTTP and OAuth works the same way: point it at the same URL. The first call opens Kwern's consent screen in your browser, where you pick the account and whether the client may write. A read token gets the resources and the read tools, which read your connectors through Kwern; a write token also gets approve, mark as done, reject and the foundation doc, puts your own posts on the calendar, where they go out at their hour without another click in Kwern, and writes to your connectors. Everything is bound to the account the token was issued for. Another account's products are not reachable, not even by id. ## What it exposes [#what-it-exposes] The library resources: * `kwern://products` — every product this account owns, with the id every tool takes * `kwern://skills` — the marketing skills Kwern hosts, read-only The resources of a product, at `kwern://products/{id}/{name}`: `foundation`, `growth-plan`, `memory`, `launch`, `snapshots`, `outputs`, `feed`, `recommendations`, `journal`. The read tools: * `list_products` — the products this account owns * `state` — where one product stands in a single call: its surfaces, its connectors and their health, its agents and what paused them, what waits in the approval feed, how current its docs are, which repository backs it * `list_proposals` — the approval feed, filtered by category, channel or state * `get_proposal` — one proposal and the state it is in * `read_connector_api` — calls an endpoint that reads on the API of one of the product's connectors, signed by Kwern The write tools, on a write token only: `approve_proposal`, `mark_proposal_done`, `record_reply`, `reject_proposal`, `write_foundation_doc`, `edit_loop`, `upload_media`, `create_post`, `edit_post`, `move_post`, `write_connector_api`. ## Publishing the Writer agent's articles [#publishing-the-writer-agents-articles] Kwern never publishes to a blog itself, so an article ends where you put it: 1. `list_proposals` with `category: ["article"]` and `state: "pending"` — the articles waiting for you 2. `get_proposal` — the Markdown body as `content`, and `frontMatter` with the title, slug, target keyword, meta description, article type and the prompt for an open-graph image 3. publish it on your side 4. `mark_proposal_done` — this is what ends an article `approve_proposal` never ends one: Kwern cannot publish to a blog, so there is nothing to approve. Kwern's own blog is published exactly this way, by a scheduled client with a token like yours: it writes each article into the repository that serves kwern.app, opens a pull request, and calls `mark_proposal_done` once the pull request merged. ## Approving from a client [#approving-from-a-client] On a channel Kwern can write to — a post or a Thread on X, LinkedIn, Apple Ads, Google Ads, an App Store review reply, a pull request — `approve_proposal` publishes. A post is the exception: it arrives planned for a day and an hour, `approve_proposal` agrees to that hour and Kwern publishes it then, unless you pass `publishNow: true` to send it at once. It hands back the proposal in the state it reached and its id, so you read it back with `get_proposal` to see whether the publish landed. ## Posting from a client [#posting-from-a-client] `create_post` puts your own post on the calendar of a product, on X or LinkedIn. It takes the product, the channel, a title, the posts in order (two or more make a thread on X) and an optional `hour`, written `2026-10-08T09:00:00Z`. The post is born approved: the call is your click, so it never waits in the approval feed. With an hour ahead it is scheduled and Kwern publishes it then; with no hour, or one already behind, it goes out on the call. The answer is the post in the state it reached, the channel's reason in `error` when the channel refused it, and its id to read it back with `get_proposal`. The same call made twice puts one post on the calendar. Any post that has not gone out, yours or an agent's, can change afterwards. `edit_post` takes the proposal id and the whole new list of posts; a scheduled post keeps its hour. `move_post` takes the proposal id and a new `hour`; on a post an agent left pending, it is the approval for that hour. `reject_proposal` cancels a scheduled post, and `approve_proposal` on one sends it now. ### With pictures or a video [#with-pictures-or-a-video] A post carries up to four pictures, or one video, on X and LinkedIn. The bytes go from your disk straight to Kwern's storage, never through the client's context: 1. `upload_media` with the file's `name`, `contentType` and `byteSize` — the answer holds the file's `id`, an `uploadUrl`, and when it expires an hour later 2. `PUT` the file to `uploadUrl`, with `Content-Type` set to the answered `contentType` and exactly `byteSize` bytes: `curl -X PUT -H "Content-Type: image/png" --data-binary @launch.png "$uploadUrl"` 3. `create_post`, or `edit_post`, with the `id` and an alt in the post's `media`: `{ "text": "Gymup 2.0 is out.", "media": [{ "id": "…", "alt": "The set log, one tap from the home screen." }] }` 4. `get_proposal` with the answered id, to see whether the publish landed A post naming a file whose bytes have not arrived is refused with that reason: send them, then call again. A file over 500 MB is refused at `upload_media`, and one no post carries is deleted a day later. ## Calling your connectors through Kwern [#calling-your-connectors-through-kwern] Your agent reaches the API of every connector the product holds without connecting that service a second time. Kwern keeps the credentials and signs each call with your connection, so no token reaches your agent, its transcripts or its logs. 1. `state` — lists the product's connectors and their health 2. `read_connector_api` with `productId`, `service`, `method`, `path` and, if the endpoint takes them, `query` and `body` — Kwern adds the service's base URL and answers with the service's status and body as the service wrote them, its refusals included 3. `write_connector_api` with the same arguments, on a write token — the change is sent at once, with no approval in Kwern The tool descriptions list each service with its base URL and its API reference. A change sent to `read_connector_api` comes back as `skipped`, naming `write_connector_api`. A refusal from the service, such as a 403 on a grant that does not cover the change, comes back as the service wrote it. A post created through `write_connector_api` goes out at once and stays off your calendar; `create_post` schedules one. Each call is written in the product's journal. [MCP page](https://kwern.app/mcp) · [Writer agent](https://kwern.app/agents/writer) · [All docs](/) # Products and surfaces (/products) ## A product starts from one URL [#a-product-starts-from-one-url] You give Kwern the address of what you built. An App Store listing makes an **App Store** surface, a Google Play listing (`play.google.com/store/apps/details?id=…`) a **Google Play** surface, and anything else a **Site** surface. An Android app needs nothing more than its Google Play URL: Kwern reads its name and icon off the public listing page. That URL is kept as the product's origin and nothing more: what a product can do is decided by its surfaces, not by where it came from. Everything in Kwern is scoped to one product. One account may have several. ## Surfaces [#surfaces] A product has one to three surfaces, one of each kind: * **App Store** — an App Store id and a storefront * **Google Play** — a package name and a storefront * **Site** — a URL What the product unlocks is the union of what its surfaces allow: which agents exist, which Analytics tabs appear, which tools a run may read with. A maker with an iPhone app, an Android app and a landing page keeps **one** foundation doc, one growth plan and one memory across all three. Missing surfaces are proposed from what your product already says about itself, and each is added only once you confirm it. An App Store or Google Play listing proposes the site it names for its developer. A site proposes the App Store app of its Smart App Banner, and the Google Play app it declares: its `/.well-known/assetlinks.json` first, then its web manifest's `related_applications`, then a Google Play badge link. Kwern never guesses one store's app from the other's name. Removing a surface takes its agents, their proposals, its connectors and its snapshots with it, keeps the accounts you connected, and never rewrites the foundation doc. The last surface stays. ## The foundation doc [#the-foundation-doc] The stable description of the product: positioning, who it is for, the voice, the competitors. Every skill reads it before acting, which is what keeps a LinkedIn post and an App Store subtitle sounding like the same company. Kwern writes the first version from the URL — the site or the listing — and you edit it directly, with version history. It can also be replaced over the [MCP server](/mcp). ## The growth plan [#the-growth-plan] The goals, bets and channels the product is currently executing, written right after the foundation doc and refreshed monthly. Every agent reads it whole alongside the foundation doc, and runs without it if it is missing. Agents never write to it. ## Product memory [#product-memory] The dated lessons the product has learned: what to do, what to avoid, what was observed. It is what stops an agent proposing again the thing you rejected last month. ## Connectors [#connectors] A connector is the product's binding to one resource inside an account you connected: an app, a project, a repository, a property, a handle. The account lives in **Settings**; the binding lives on the product's **Apps** page, and one account can serve several products. Each connector syncs once a day. The sync leaves a snapshot — the last data the service returned — and extends the connector's **series**, the day-by-day metrics that are never windowed: every day ever seen is kept, and a day the source restates is overwritten. [All connectors](https://kwern.app/connectors) · [All agents](https://kwern.app/agents) · [The MCP server](/mcp)