← Plugin catalog
Productivity

Surfer

Surfer v0.1.0

Publisher description

From the marketplace listing

Track traditional and AI search visibility, create and optimize content, and act on daily recommendations from Surfer directly in ChatGPT and Codex. Automate your content workflow: find your best opportunities to fix content gaps, get an outreach list of sources most cited by LLMs, generate content briefs and full pages in your brand voice, auto-optimize existing content, and run custom reports. All of Surfer’s live data in one conversation, just a few simple prompts away.

Language: English · Automatically detected from descriptions.

Publisher keywords

Search terms declared by the publisher.

Files & skills

File archives

Plugin package28 files · 30.2 KBBrowse files →
Skill instructions
surfer-connect2.19 KB

View saved version →

---
name: surfer-connect
description: >-
  Use when Surfer MCP tools are unavailable or the user asks to connect, install, or set up Surfer
  in their AI assistant. Triggers include "connect the Surfer MCP server", "add Surfer to this
  client", "install Surfer MCP", and "how do I sign in to Surfer". It follows the current client
  setup guide, verifies the connection, and returns to the interrupted surfer-* workflow.
license: MIT
---

# Surfer: Connect MCP

Connect Surfer MCP in the current client, verify it, and return to the interrupted workflow.

## MCP setup

Use the [Surfer MCP overview](https://devs.surferseo.com/mcp/overview) and
[quickstart](https://devs.surferseo.com/mcp/quickstart) as the source of truth for requirements.
Detect the current client and read its guide before configuring it; ask which client only when
it cannot be determined. Follow that guide's current endpoint, sign-in, and verification steps.

| Client | Setup guide |
|---|---|
| Claude Code | https://devs.surferseo.com/mcp/connect/claude-code |
| Claude web or desktop | https://devs.surferseo.com/mcp/connect/claude |
| ChatGPT web | https://devs.surferseo.com/mcp/connect/chatgpt-web |
| ChatGPT desktop (Work) | https://devs.surferseo.com/mcp/connect/chatgpt-desktop |
| Codex CLI or IDE | https://devs.surferseo.com/mcp/connect/codex |
| Cursor | https://devs.surferseo.com/mcp/connect/cursor |
| VS Code | https://devs.surferseo.com/mcp/connect/vs-code |
| Other clients | https://devs.surferseo.com/mcp/connect/other |

Use the client's normal connector settings or CLI. Show a manual configuration edit before
applying it. The user completes OAuth in their browser; never request their sign-in credentials.

## Verify and return

Confirm that Surfer tools are available and `workspace__list` succeeds. Registration
alone is not success; if a restart is required, report setup as pending until the tools are usable.

For connection errors, follow [troubleshooting](https://devs.surferseo.com/mcp/troubleshooting);
for access or quota issues, consult [credits and limits](https://devs.surferseo.com/mcp/credits-and-limits).

After verification, resume the interrupted workflow. If the user only
asked to connect, report what is usable and stop.

Referenced files: 2

surfer-content-recommendations4.4 KB

View saved version →

---
name: surfer-content-recommendations
description: >-
  Use when the user wants to act on Surfer's site recommendations. Triggers include "what should I
  optimize next", "turn my Surfer recommendations into articles", "find a content opportunity and
  act on it", and "run the write or optimize workflow from my workspace". It selects
  recommendation-led Optimize or Write work and delegates drafting and optimization to the focused
  Surfer skills.
license: MIT
---

# Surfer: Act on Content Recommendations

## Overview

Turn a chosen, site-level recommendation into one Content Editor workflow without creating the same
work twice.

## Prerequisites

- Require connected Surfer MCP tools. For setup or connection failures, use `surfer-connect`;
  ask to install it if missing. If a required tool is unavailable, name it and stop.

## Playbook

1. **Establish scope.** Resolve an active `workspace_id` with `workspace__list`; recommendations
   are read per workspace. If several workspaces are active, ask the caller which one to use rather
   than guessing. If none is active, stop and report. Offer a brand review before optimizing:
   editors opened by `recommendation__optimize` always apply the workspace's brand profile, with no
   per-editor toggle, so read it with `brand__get` and write it with `brand__update` only with an
   approved replacement. Write recommendations are also generated from that profile, so an update
   shapes future generation runs, not the current list. Do not confuse "enabled for this editor"
   with inspecting the profile.

2. **List, explain, and select a recommendation.** Call `recommendation__list`, filtered with
   `type` when the user already chose `optimize` or `write` work. Present each candidate's page URL
   or keyword and its `score`. Scores order items within one type and are not comparable across
   types; the default ordering lists optimize items before write items, each block score-descending.
   An item whose `content_editor_id` is set is already being worked on, so offer to continue it
   rather than start over. An empty list may mean no source is configured:
   `meta.content_audit_configured` and `meta.topical_maps_configured` name which of Content Audit
   or Topical Maps is missing, so report that rather than a bare "no recommendations". Let the user
   choose. Auto-select only when the user states a clear rule, such as "highest-score optimize
   recommendation", and rank within one type only.

3. **Run the focused workflow.** The recommendation carries everything needed to act, and its
   `content_editor_id` marks the editor already covering it — never create a second editor for a
   covered item.
   - For an *optimize* item, hand its editor to `surfer-optimize-content`, skipping that skill's
     create step. Use `content_editor_id` when set. Otherwise confirm the spend, then call
     `recommendation__optimize` — the product's Optimize button. It opens the page's own Content
     Editor, connected to Content Audit so optimization progress tracks in the product, charges one
     Content Editor credit unless the page's editor was already paid for, and returns the refreshed
     item with `content_editor_id` set. Never import the page URL into a fresh editor instead; that
     disconnects the tracking. On an already-open conflict, re-list and use its editor id. If the
     tool explicitly says the editor is not ready yet, wait and retry `recommendation__optimize`
     with the same workspace and recommendation ids, bounded; re-listing alone will not open it.
     Stop on quota or other reported failures. After a lost or unclear response, re-list first and
     reuse the editor id if present. If bounded reads cannot establish the outcome, report it as
     indeterminate and stop instead of repeating the action.
   - For a *write* item, pass its `content_editor_id`, `workspace_id`, `main_keyword`, and `location`
     to `surfer-write-article` when the id is set. The writer verifies and reuses that editor before
     considering generation. Without an editor id, pass the workspace id, keyword, and location;
     the writer checks for existing work before creating an editor.

4. **Report the lifecycle.** Return the recommendation selected, the workspace and editor ids, the
   baseline and final score snapshot, and the changes made. An optimize item's progress also shows
   in the product: its `optimization_status` and the linked draft's `content_score` update on
   `recommendation__list`.

Referenced files: 2

surfer-create-content-brief5.8 KB

View saved version →

---
name: surfer-create-content-brief
description: >-
  Use when the user wants a writer-ready content brief grounded in Surfer's SEO and AI Search
  guidance. Triggers include "make a content brief", "brief a writer for this keyword", "what should
  an article cover", and "give me an SEO and AI Search brief". Also use it for SERP or competitor
  research with no draft, such as "analyze the SERP for this keyword" or "what do the top-ranking
  pages cover". It reports the SERP-derived competitors, structure, terms, and questions without
  writing anything. It creates or reuses a manual Content Editor and assembles its outline, SEO
  guidelines, and source-attributed AI Search facts into a concise brief. For an outline alone, use
  surfer-create-outline. For an article draft, use surfer-write-article.
license: MIT
---

# Surfer: Create a Content Brief

## Overview

Turn a keyword into an evidence-aware writing specification. The output is a brief for a human or
agent writer. Do not produce a generic article, and do not imply that an empty editor already scores
well.

## Inputs and setup

- Require `main_keyword` and ask for it when missing. Use the user's `location` and `device`,
  otherwise default to United States and mobile. Accept a `workspace_id` or call `workspace__list`
  and choose the sole active workspace. If several are active, ask the caller which one to use;
  if none is active, stop and report that resource operations are unavailable.
- Reuse an existing `content_editor_id` when it matches the intended keyword and scope. Otherwise
  create one. A `content_editor__create` call with only a keyword yields a manual editor. AI
  drafting starts only when `ai_article__generate` is called. A create consumes a credit, so pass
  an `idempotency_key`. Retry a timeout or an ambiguous failure with the same key. Surfer then
  returns the original editor instead of creating a duplicate.
- Before creation, collect brand knowledge, content type or template, voice, custom instructions,
  and competitor choices whenever they must shape the initial outline. They map to the
  `content_editor__create` inputs: `use_brand_knowledge`, one `custom_template_id` or
  `surfer_template` (mutually exclusive), and `custom_instructions`. When both template fields are
  omitted, Surfer picks a template itself during analysis. It may pick the workspace default, an
  AI-chosen preset or custom template, or none, so a request for no template cannot be guaranteed.
  Verify which template took effect and swap it only when the user asks. A template, once set, can
  be swapped but not removed. `content_editor__update` rejects an update that clears
  `custom_template_id` without supplying a `surfer_template`. Omitting `custom_voice_id` applies
  the workspace default voice. To honor a request for no voice, send `custom_voice_id: null`.
  Competitors change through `seo_guidelines__update_competitors` after initialization.
- Require connected Surfer MCP tools. For setup or connection failures, use `surfer-connect`;
  ask to install it if missing. If a required tool is unavailable, name it and stop.

## Playbook

1. **Initialize the Content Editor.** Call `content_editor__create` with the complete initial setup
   when no suitable editor exists. Await the completion signal or poll `content_editor__get` until
   `completed`. On failure or timeout, report the editor id and stop.

2. **Inspect the effective setup.** Read `content_editor__get`. Read the `competitors` block of
   `seo_guidelines__get` only when competitor selection matters. State the effective brand toggle,
   template or voice, instructions, and competitor set. Change a setting only on an explicit user
   request, using `content_editor__update` or `seo_guidelines__update_competitors`.

3. **Collect the brief inputs:**
   - `outline__get`, always returned as Markdown.
   - `seo_guidelines__get`, the SEO brief with structure targets, terms, topics, and questions.
   - `ai_search_guidelines__list_facts` for the source-attributed facts. Check the analysis readiness
     reported by the MCP tool: wait with a bound while analysis runs, use the facts once complete,
     and report failure or a timeout without inventing facts. The separate AI Search score may be
     read when needed, but its `ready` status does not establish facts analysis completion; do not
     use a score to grade an empty draft.

   If the outline is pending, wait on `outline.status`. `outline__regenerate` rebuilds it from the
   SERP competitors with the current template, instructions, and brand knowledge. Use it after an
   approved setup change or to recover a failed outline, then re-read `outline__get`.

4. **Write the brief as structured sections.** Organize it into:
   - search intent, the primary keyword, location and device, and audience and brand constraints
   - a proposed title and the Surfer-derived outline
   - word-count and structural targets, given as ranges rather than hard quotas
   - priority terms, marking which belong in headings and which in body coverage
   - the required subtopics and questions
   - AI Search facts as candidate claims, each keeping its source URL and `cited_by` context
   - explicit constraints, open questions, and the Content Editor link and id

5. **Preserve evidence boundaries.** Do not call an AI Search fact true merely because an engine
   suggested or cited it. Attribute it, ask the writer to verify material claims, and call out
   unavailable or incomplete AI Search analysis rather than fabricating facts.

6. **Hand off deliberately.** Stop after the brief unless the user also asks for drafting. Pass the
   `content_editor_id`, `workspace_id`, keyword, accepted outline, and brief to
   `surfer-write-article` so it reuses the analyzed editor. The outline is planning context; the
   writer's optional AI outline review is a separate step. Do not automatically start
   `ai_article__generate`.

Referenced files: 2

surfer-create-outline5.23 KB

View saved version →

---
name: surfer-create-outline
description: >-
  Use when the user wants a Surfer-derived, SERP-informed article outline without a full draft.
  Triggers include "create an outline for X", "plan headings for this keyword", "make a Surfer
  outline", and "outline an article before writing". It creates or reuses a Content Editor in
  manual-writing mode, returns its SEO-oriented outline, and can verify the requested brand,
  template, instructions, and competitor choices. For a writer-ready plan that also includes AI
  Search facts, or for SERP or competitor research with no deliverable, use
  surfer-create-content-brief. For a complete AI-written draft, use surfer-write-article.
license: MIT
---

# Surfer: Create an Optimized Outline

## Overview

Produce the structural plan for a new article. The outline is SERP-derived. To add AI Search facts
to the writer's plan, use the content-brief workflow. A manual Content Editor is the source of
truth. Do not invoke `ai_article__generate` unless the user changes the request to a draft.

## Inputs

- Require `main_keyword`. Ask for it if it is missing.
- Use the user's `location` and `device`. Otherwise default to United States and mobile. Location and
  device are inputs to `content_editor__create`.
- Accept a `workspace_id` or resolve one with `workspace__list`. If several workspaces are active,
  ask the caller which `workspace_id` to use rather than guessing.
- Accept an existing `content_editor_id` to avoid spending another Content Editor credit.
- Treat brand knowledge, content type, custom instructions, template, voice, and competitor
  selection as setup choices collected before the create: `use_brand_knowledge`, one
  `custom_template_id` or `surfer_template` (mutually exclusive), and `custom_instructions` are
  `content_editor__create` inputs. When both template fields are omitted, Surfer picks a template
  itself during analysis. It may pick the workspace default, an AI-chosen preset or custom
  template, or none, so a request for no template cannot be guaranteed. Verify which template took
  effect and swap it only when the user asks. A template, once set, can be swapped but not removed.
  `content_editor__update` rejects an update that clears `custom_template_id` without supplying a
  `surfer_template`. Omitting `custom_voice_id` applies the workspace default voice. To honor a
  request for no voice, send `custom_voice_id: null`. Competitors are changed with
  `seo_guidelines__update_competitors` after initialization.
- Require connected Surfer MCP tools. For setup or connection failures, use `surfer-connect`;
  ask to install it if missing. If a required tool is unavailable, name it and stop.

## Playbook

1. **Create or reuse the editor.** Reuse the supplied `content_editor_id` after confirming it targets
   the requested keyword and workspace. Otherwise call `content_editor__create` once with the
   complete initial setup: the keyword, location, device, `use_brand_knowledge`, any selected
   template or voice, and `custom_instructions`. A create consumes a credit, so pass an
   `idempotency_key`. Retry a timeout or an ambiguous failure with the same key. Surfer then
   returns the original editor instead of creating a duplicate.

2. **Wait for analysis.** Await the completion signal or poll `content_editor__get` until `state` is
   `completed`. On a `failed` state or a bounded timeout, report the editor id and its terminal or
   indeterminate state instead of retrying forever.

3. **Verify setup without silently changing it.** Read `content_editor__get`. For a requested
   competitor review, read the `competitors` block of `seo_guidelines__get`. Report the effective
   brand toggle, template or voice, instructions, and included competitors. Apply a change only when
   the user requested it. Use `content_editor__update` for editor settings and
   `seo_guidelines__update_competitors` for an explicit competitor selection.

4. **Retrieve the outline.** Call `outline__get`. It always returns Markdown and is generated
   during editor creation. If it is still pending, wait on the editor's `outline.status` from
   `content_editor__get`, then re-read it.

5. **Regenerate after a setup change when needed.** `outline__regenerate` rebuilds the outline from
   the SERP competitors and applies the editor's current template, custom instructions, and brand
   knowledge. Use it after an approved template, instruction, or competitor change, or to recover a
   failed outline. It returns a conflict when a regeneration is already running. Wait on
   `outline.status` and re-read with `outline__get` once it settles. It does not consume a Content
   Editor credit.

6. **Deliver a usable plan.** Return the Markdown outline, the Content Editor id, an edit or share
   link if available, the target keyword and location, and the setup choices that shaped it. Do not
   fill missing sections with generic headings. Call out an empty or unavailable outline instead.

## Handoff

Use `surfer-create-content-brief` when the writer also needs terms, structural targets, questions,
and AI Search facts. Pass the `content_editor_id`, `workspace_id`, keyword, and accepted outline to
the next skill so it reuses the analyzed editor. Use `surfer-write-article` only after the outline
has been accepted or when the user explicitly asks for a draft.

Referenced files: 2

surfer-manage-content-templates3.74 KB

View saved version →

---
name: surfer-manage-content-templates
description: >-
  Use when the user wants to create, inspect, update, choose, or delete a reusable Surfer content
  template. Triggers include "create a custom template", "turn this article into a Surfer template",
  "list our templates", "set a default template", and "update or delete a content template". For a
  writing style or tone profile, use custom voices. For one article's direction, use the custom
  instructions in surfer-write-article.
license: MIT
---

# Surfer: Manage Content Templates

## Overview

Manage reusable structural examples safely. A template is a reference text that future Content
Editors reuse for structure. The Boundaries section separates it from a voice profile and a one-off
prompt.

## Boundaries

- A template is the reusable organization, sections, formatting, and recurring document shape.
- A custom voice is the reusable tone and style. Manage it with `custom_voice__*` when that is the
  actual request.
- Custom instructions are one editor's editorial or factual direction. Pass them through
  `content_editor__create` or `content_editor__update`.
- A Surfer template is a read-only predefined template from `surfer_content_template__list`. Never
  try to update or delete it.

## Prerequisites

- Resolve the workspace with `workspace__list`. If several workspaces are active, ask the caller
  which `workspace_id` to use rather than guessing.
- Require connected Surfer MCP tools. For setup or connection failures, use `surfer-connect`;
  ask to install it if missing. If a required tool is unavailable, name it and stop.
- Do not create a template until the user supplies or approves its name and reference text.

## Playbook

1. **Inspect before mutating.** Use `content_template__list` to find a similarly named custom
   template. Use `content_template__get` before changing a specific template. List predefined options
   with `surfer_content_template__list` when the user wants to compare rather than create a duplicate.

2. **Prepare a high-signal reference.** Keep stable structure, heading hierarchy, formatting, and
   representative phrasing. Remove stale facts, client secrets, and accidental product claims.
   Preserve only material the user is authorized to reuse. Do not bury changing campaign details in a
   shared template. Create and update both require a `reference_text` of 1 to 25,000 characters and
   at least 200 words. When the reference falls short of 200 words, ask the user for more material
   or for approval to expand it. Never pad the reference silently to clear the floor.

3. **Create safely.** Call `content_template__create` with `name`, `reference_text`, and
   `default: false` unless the user explicitly requests a workspace default. Pass an
   `idempotency_key`. Retry a timeout or an ambiguous failure with the same key. Surfer then
   returns the original template instead of creating a duplicate. Read the created template
   afterward to confirm its id and stored reference text.

4. **Update intentionally.** Read the target first, show the proposed changes to name, reference, and
   default, then call `content_template__update`. Treat changing the default as a workspace-wide
   behavior change, and require explicit user confirmation immediately before it.

5. **Delete only with confirmation.** Identify the exact template by id and name, explain that
   deletion is destructive, and call `content_template__delete` only after the user confirms that
   exact target. Never infer a deletion from a request to "clean up templates."

6. **Make selection explicit.** Return the template id and workspace. To apply it to a new article,
   pass the chosen `custom_template_id` to `content_editor__create`. Do not combine it with
   `surfer_template`, because the two are mutually exclusive.

Referenced files: 2

surfer-optimize-content6.91 KB

View saved version →

---
name: surfer-optimize-content
description: >-
  Use when the user has existing content, a URL or a draft, and wants to improve its Surfer SEO
  Score, AI Search Score, or both. Triggers include "optimize my article", "improve this page's
  content score", "auto-optimize this", "make this rank better", "optimize for SEO and AI search",
  and "improve my AI or LLM visibility". For writing a new article from scratch, use
  surfer-write-article instead.
license: MIT
---

# Surfer: Optimize Existing Content

## Overview

Raise the Surfer score dimensions the user selected for a page or draft, working through a Content
Editor. Treat the unified Content Score as a diagnostic snapshot. Optimize against the explicit SEO
or AI Search targets the user cares about.

## Prerequisites

- Require connected Surfer MCP tools. For setup or connection failures, use `surfer-connect`;
  ask to install it if missing. If a required tool is unavailable, name it and stop.
- Resolve an active `workspace_id` with `workspace__list`. If several workspaces are active, ask
  the caller which `workspace_id` to use rather than guessing.
- Require a target keyword and either an import URL or raw HTML or Markdown. Ask for a missing
  keyword rather than guessing it from the page alone.
- Ask which dimensions matter: SEO, AI Search, or both. If the user says only "optimize", default to
  SEO 70+. If they ask for both and give no targets, default to 70+ for each and say so. A missing
  AI Search score does not mean zero.
- Treat brand knowledge, content type or template, custom instructions, and competitor selection as
  Content Editor setup, collected before the create: the brand profile is applied through the
  `use_brand_knowledge` toggle and cannot be inspected or edited from here, the content type is one
  `custom_template_id` or `surfer_template` (mutually exclusive), instructions go in
  `custom_instructions`, and competitors are read and changed through `seo_guidelines__get` and
  `seo_guidelines__update_competitors`. When both template fields are omitted, Surfer picks a
  template itself during analysis. It may pick the workspace default, an AI-chosen preset or custom
  template, or none, so a request for no template cannot be guaranteed. Verify which template took
  effect and swap it only when the user asks. A template, once set, can be swapped but not removed.
  `content_editor__update` rejects an update that clears `custom_template_id` without supplying a
  `surfer_template`. Omitting `custom_voice_id` applies the workspace default voice. To honor a
  request for no voice, send `custom_voice_id: null`.

Use bounded waits only. On an explicit failure, an unavailable score, or a timeout, report the id
and state. Never poll indefinitely.

## Playbook

1. **Create or reuse a Content Editor.** Reuse a matching editor through `content_editor__list` when
   the user supplies one or asks to continue it. Omit `workspace_id` on that list call for an
   org-wide search. Otherwise call `content_editor__create` once with `main_keyword`, location,
   device, the full initial setup, and `import_content_url` for a live page. Default the location to
   United States and the device to mobile. For pasted text, omit the import URL and load the body
   after initialization. A create consumes a credit, so pass an `idempotency_key`. Retry a timeout
   or an ambiguous failure with the same key. Surfer then returns the original editor instead of
   creating a duplicate.

2. **Wait and verify the setup.** Await the completion signal or poll `content_editor__get` until
   `state` is `completed`. Read `content_editor__get`. If the user asked to review competitors,
   read the `competitors` block of `seo_guidelines__get`. Report the effective brand toggle,
   template or voice, instructions, and competitors. Apply changes only after user approval, with
   `content_editor__update` or `seo_guidelines__update_competitors`, then re-read the affected
   guidelines.

3. **Load content and establish the baseline.** For a pasted draft, call `content__update`, then
   re-fetch with `content__get`. Read `content_score__get` for the unified `total` plus the `seo`
   and `ai_search` subscores. A `loading` or `calculating` status means the score is still
   settling, so keep waiting until each selected subscore's `status` is `ready`. An `ai_search`
   status of `error` or `unavailable` is terminal. Report it and stop waiting. Before the next
   mutation, record the `calculated_at` of the `seo` and `ai_search` subscores. The `total` has no
   `calculated_at`.

4. **Read only the guidance needed.** For SEO, read `seo_guidelines__get`, one brief that carries the
   structure targets, terms, topics, questions, and competitors. For AI Search, read the facts with
   `ai_search_guidelines__list_facts`. Check the analysis readiness reported by the MCP tool: wait
   with a bound while analysis runs, and report failure or a timeout instead of treating incomplete
   facts as final. The separate `ai_search` score reaching `ready` does not establish facts analysis
   completion. `ai_search_guidelines__get` returns the facts plus the score, its status, and the fact
   count. Retain every fact's source URL and `cited_by` context.

5. **Choose an optimization path**, and ask when the user has no preference.
   - Call `auto_optimize__run` once per requested pass; it edits the document directly. Poll
     `auto_optimize__get` by the returned job id, or resume polling when continuing a known run.
     Each accepted start spends a credit and can cancel an earlier run, so do not automatically
     repeat a start whose response was lost. If no job id is available, report the outcome as unknown
     and stop. A `completed` job has a result of `optimized` or `nothing_to_optimize`. Stop on a
     `failed` state or a quota error.
   - A guided edit revises the draft against the selected guidelines, without keyword stuffing or
     unsupported claims, then calls `content__update`. Preserve source attribution for AI Search
     facts, and re-fetch the canonical stored body with `content__get` because Surfer sanitizes it.

6. **Recalculate and compare.** After either path, re-read the stored content and all selected scores
   with `content_score__get`. After a direct content update, trust a subscore only once its `status`
   is `ready` and its `calculated_at` has advanced past the pre-mutation value. A `loading` or
   `calculating` status may still carry the stale score. The `total` has no `calculated_at`, so
   gate it on `status` alone. If AI Search reports `error` or `unavailable`, report why and do not
   claim the combined target was reached.

7. **Iterate with a stopping rule.** Address the largest remaining SEO or AI Search gap, then repeat
   steps 4 to 6. Stop when every selected target is met, when auto-optimize reports
   `nothing_to_optimize`, when the last useful gain is under about one point, or after 3 to 4 rounds.
   Report the baseline and final values for the SEO, AI Search, and unified Content Score separately.

Referenced files: 2

surfer-write-article6.65 KB

View saved version →

---
name: surfer-write-article
description: >-
  Use when the user wants Surfer to produce a brand-new article or blog post from a keyword or topic.
  Triggers include "write an SEO article about X", "draft optimized content for this keyword",
  "generate a Surfer AI article", and "write for SEO and AI Search". To improve content that already
  exists, use surfer-optimize-content. For a writer brief without a draft, use
  surfer-create-content-brief.
license: MIT
---

# Surfer: Write an Optimized Article

## Overview

Turn a keyword into a new, AI-authored draft grounded in Surfer's SEO and AI Search analysis. When
the user wants only an outline or a brief, create a manual Content Editor and stop before
`ai_article__generate`.

## Prerequisites

- Require connected Surfer MCP tools. For setup or connection failures, use `surfer-connect`;
  ask to install it if missing. If a required tool is unavailable, name it and stop.
- Use the `workspace_id` supplied by the user or the handoff, and verify it is active with
  `workspace__list`. If none was supplied, use the sole active workspace or ask the caller to
  choose when several are active.
- Accept an existing `content_editor_id` as a first-class input, especially from a recommendation,
  outline, or brief handoff. Require `main_keyword` for a new editor; for an existing editor, read
  its keyword and accept up to 19 secondary keywords. Default the location to United States and the
  device to mobile only when creating. Location and device are inputs to `content_editor__create`.
- Before creation, collect the optional `target_word_count`, any SEO or AI Search score targets,
  and `manual_outline`, which is an `ai_article__generate` input. Collect the full editor setup as
  well: the `use_brand_knowledge` toggle (it applies the workspace's brand profile, which cannot be
  inspected or edited from here), one `custom_template_id` or `surfer_template` as the content type
  (mutually exclusive), and `custom_instructions`. When both template fields are omitted, Surfer
  picks a template itself during analysis, so a request for no template cannot be guaranteed.
  Omitting `custom_voice_id` applies the workspace default voice. To honor a request for no voice,
  send `custom_voice_id: null`. Competitors are read from the `competitors` block of
  `seo_guidelines__get` and changed with `seo_guidelines__update_competitors` after initialization.
- Treat "AI writing mode" as the `ai_article__generate` call rather than a `content_editor__create`
  field. Leave it out for manual work.

## Playbook

1. **Reuse or create the Content Editor.** When `content_editor_id` is supplied, read it with
   `content_editor__get` in the selected workspace. Verify the keyword and any location, device, or
   setup constraints the user supplied; report a mismatch before generating. Keep its existing
   settings unless the user requested a change. Reuse it for a continuation or a first draft from
   an outline or brief. An explicit request for another, separate article takes priority: create a
   fresh editor with the requested setup. Otherwise, if no id was supplied, look for a matching
   editor the user asked to continue and call `content_editor__create` only if none applies.
   Include the keyword, location, device, selected brand toggle, template or voice, and custom
   instructions. A create consumes a credit, so use one `idempotency_key` for that logical create
   and reuse it after an ambiguous response. If no template is selected, keep the one Surfer chooses
   during analysis.

2. **Wait for initialization.** Await the completion signal or poll `content_editor__get` until
   `state` is `completed`. Report a failure or a bounded timeout with the editor id.

3. **Review the content plan before drafting.** Read `seo_guidelines__get`, one brief with the terms,
   structure targets, topics, questions, and competitors. Read `ai_search_guidelines__list_facts`
   when AI Search is a goal. Read `content_editor__get` to verify the brand toggle, template or
   voice, and instructions. If the user asks to change competitors, inspect the `competitors` block
   of `seo_guidelines__get`, apply an approved `seo_guidelines__update_competitors`, then re-read the
   affected guidelines before generating.

4. **Choose outline behavior.** `outline__get` returns the read-only SERP outline.
   `outline__regenerate` rebuilds it from the SERP competitors with the editor's template,
   instructions, and brand knowledge. Use it after a setup change or a failed outline. For a
   reviewable AI outline, set `manual_outline: true` when calling `ai_article__generate`. That
   outline is separate from the SERP outline and pauses before prose is written.

5. **Generate or continue the requested article.** Call `ai_article__generate` for a new draft.
   For a continuation, use `ai_article__get` with the known article id, or `ai_article__list` to find
   it. If generation reports an existing-article conflict, use the returned article id to continue
   that work. Surfer rejects another generation in an editor with an in-progress or completed
   article; an explicit request for a separate article uses a fresh editor as in step 1. After a
   lost response, use `ai_article__list` to recover the article; if the outcome remains unclear,
   report it and stop without an automatic retry. On `waiting_for_user_input`, fetch
   `ai_article__get_outline`, present it, and submit only the user-approved version with
   `ai_article__submit_outline`. While it is `new`, `generating_outline`, or `writing`, wait. On
   `failed`, report and stop.

6. **Read the canonical draft and score snapshot.** Await the completion signal or poll
   `ai_article__get` until `completed`. Fetch `content__get`, then read `content_score__get` for the
   unified `total` plus the `seo` and `ai_search` subscores. Trust an individual score only when its
   `status` is `ready`. A `loading` or `calculating` status is still settling. An `error` or
   `unavailable` AI Search score is terminal. Call it out rather than treating it as a pass or
   polling for `ready`.

7. **Iterate only toward user-selected targets.** If a target is set and unmet, improve the draft
   with the relevant SEO guidance and the sourced AI Search facts, write it with `content__update`,
   re-fetch the sanitized stored version with `content__get`, and wait for the selected score
   timestamps to advance. Stop after 3 to 5 rounds or after a plateau. Do not chase a unified Content
   Score target.

8. **Deliver and hand off.** Return the canonical content, the SEO, AI Search, and unified scores
   separately, the Content Editor id, and an edit or share link from `permalink__list`. For a
   recommendation-led workflow, hand control back to `surfer-content-recommendations`.

Referenced files: 2

Publisher release notes

Initial Surfer plugin release for ChatGPT and Codex, combining the hosted Surfer MCP connection with seven skills for connection setup, article writing, content optimization, outlines, content briefs, reusable templates, and content recommendations.

Declared in the saved package. Remote tools may change independently.

Package details

Publisher declarations from the archived package. These are separate from our research and the live service's terms.

Package license
MIT
Package author
Surfer
Keywords
See publisher keywords
Declared availability
No country restrictions declaredPublication setting in this package; live availability may differ. This is not the publisher's country.
Commerce declaration
Does not support commerceThis does not establish whether access is free or paid.
Publisher review scenarios
5 positive · 3 negativeDeclared scenarios, not independently verified test results.

Declared capabilities

  • Read
  • Write

Package observed Oct 7, 2026.

Technical details
First seen
Oct 7, 2026 · 18:00 UTC
Last seen
Oct 7, 2026 · 18:00 UTC
Collection status
Collected

plugin_asdk_app_6ac4ec4eec288191b37184706855fbc4

Download plugin data (JSON)

Before you connect Surfer

How do I connect it?

Open the publisher's marketplace listing to check current availability and follow its connection instructions. This directory does not install plugins. Check the requested access and any account requirements before connecting.

Check marketplace availability ↗

Does it require paid access?

We have not established the pricing or subscription requirements for this plugin. An absent price does not mean free access.

Compare researched pricing and access models →

How can I evaluate it?

Check the declared skills and available files, then try a small task whose result you can verify. Our archived descriptions and instructions establish publisher claims, not tested runtime quality. Review sources and coverage limits.