← SurferCONTENT HISTORYWHAT CHANGED · RULE-BASED ANALYSIS
Update to Surfer
Snapshot Oct 7, 2026 · 18:03 UTC · version 0.1.0
Collection source: downloaded plugin package.
First saved snapshot
No earlier snapshot is available to establish a change.
Compare saved observations
Download comparison JSONFull technical diff · 0 changed fields
Full snapshot data
{
"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.",
"included_files": [
{
"relative_path": "LICENSE",
"size_in_bytes": 1079
},
{
"relative_path": "agents/openai.yaml",
"size_in_bytes": 453
}
],
"name": "surfer-optimize-content",
"skill_md_contents": "---\nname: surfer-optimize-content\ndescription: >-\n Use when the user has existing content, a URL or a draft, and wants to improve its Surfer SEO\n Score, AI Search Score, or both. Triggers include \"optimize my article\", \"improve this page's\n content score\", \"auto-optimize this\", \"make this rank better\", \"optimize for SEO and AI search\",\n and \"improve my AI or LLM visibility\". For writing a new article from scratch, use\n surfer-write-article instead.\nlicense: MIT\n---\n\n# Surfer: Optimize Existing Content\n\n## Overview\n\nRaise the Surfer score dimensions the user selected for a page or draft, working through a Content\nEditor. Treat the unified Content Score as a diagnostic snapshot. Optimize against the explicit SEO\nor AI Search targets the user cares about.\n\n## Prerequisites\n\n- Require connected Surfer MCP tools. For setup or connection failures, use `surfer-connect`;\n ask to install it if missing. If a required tool is unavailable, name it and stop.\n- Resolve an active `workspace_id` with `workspace__list`. If several workspaces are active, ask\n the caller which `workspace_id` to use rather than guessing.\n- Require a target keyword and either an import URL or raw HTML or Markdown. Ask for a missing\n keyword rather than guessing it from the page alone.\n- Ask which dimensions matter: SEO, AI Search, or both. If the user says only \"optimize\", default to\n SEO 70+. If they ask for both and give no targets, default to 70+ for each and say so. A missing\n AI Search score does not mean zero.\n- Treat brand knowledge, content type or template, custom instructions, and competitor selection as\n Content Editor setup, collected before the create: the brand profile is applied through the\n `use_brand_knowledge` toggle and cannot be inspected or edited from here, the content type is one\n `custom_template_id` or `surfer_template` (mutually exclusive), instructions go in\n `custom_instructions`, and competitors are read and changed through `seo_guidelines__get` and\n `seo_guidelines__update_competitors`. When both template fields are omitted, Surfer picks a\n template itself during analysis. It may pick the workspace default, an AI-chosen preset or custom\n template, or none, so a request for no template cannot be guaranteed. Verify which template took\n effect and swap it only when the user asks. A template, once set, can be swapped but not removed.\n `content_editor__update` rejects an update that clears `custom_template_id` without supplying a\n `surfer_template`. Omitting `custom_voice_id` applies the workspace default voice. To honor a\n request for no voice, send `custom_voice_id: null`.\n\nUse bounded waits only. On an explicit failure, an unavailable score, or a timeout, report the id\nand state. Never poll indefinitely.\n\n## Playbook\n\n1. **Create or reuse a Content Editor.** Reuse a matching editor through `content_editor__list` when\n the user supplies one or asks to continue it. Omit `workspace_id` on that list call for an\n org-wide search. Otherwise call `content_editor__create` once with `main_keyword`, location,\n device, the full initial setup, and `import_content_url` for a live page. Default the location to\n United States and the device to mobile. For pasted text, omit the import URL and load the body\n after initialization. A create consumes a credit, so pass an `idempotency_key`. Retry a timeout\n or an ambiguous failure with the same key. Surfer then returns the original editor instead of\n creating a duplicate.\n\n2. **Wait and verify the setup.** Await the completion signal or poll `content_editor__get` until\n `state` is `completed`. Read `content_editor__get`. If the user asked to review competitors,\n read the `competitors` block of `seo_guidelines__get`. Report the effective brand toggle,\n template or voice, instructions, and competitors. Apply changes only after user approval, with\n `content_editor__update` or `seo_guidelines__update_competitors`, then re-read the affected\n guidelines.\n\n3. **Load content and establish the baseline.** For a pasted draft, call `content__update`, then\n re-fetch with `content__get`. Read `content_score__get` for the unified `total` plus the `seo`\n and `ai_search` subscores. A `loading` or `calculating` status means the score is still\n settling, so keep waiting until each selected subscore's `status` is `ready`. An `ai_search`\n status of `error` or `unavailable` is terminal. Report it and stop waiting. Before the next\n mutation, record the `calculated_at` of the `seo` and `ai_search` subscores. The `total` has no\n `calculated_at`.\n\n4. **Read only the guidance needed.** For SEO, read `seo_guidelines__get`, one brief that carries the\n structure targets, terms, topics, questions, and competitors. For AI Search, read the facts with\n `ai_search_guidelines__list_facts`. Check the analysis readiness reported by the MCP tool: wait\n with a bound while analysis runs, and report failure or a timeout instead of treating incomplete\n facts as final. The separate `ai_search` score reaching `ready` does not establish facts analysis\n completion. `ai_search_guidelines__get` returns the facts plus the score, its status, and the fact\n count. Retain every fact's source URL and `cited_by` context.\n\n5. **Choose an optimization path**, and ask when the user has no preference.\n - Call `auto_optimize__run` once per requested pass; it edits the document directly. Poll\n `auto_optimize__get` by the returned job id, or resume polling when continuing a known run.\n Each accepted start spends a credit and can cancel an earlier run, so do not automatically\n repeat a start whose response was lost. If no job id is available, report the outcome as unknown\n and stop. A `completed` job has a result of `optimized` or `nothing_to_optimize`. Stop on a\n `failed` state or a quota error.\n - A guided edit revises the draft against the selected guidelines, without keyword stuffing or\n unsupported claims, then calls `content__update`. Preserve source attribution for AI Search\n facts, and re-fetch the canonical stored body with `content__get` because Surfer sanitizes it.\n\n6. **Recalculate and compare.** After either path, re-read the stored content and all selected scores\n with `content_score__get`. After a direct content update, trust a subscore only once its `status`\n is `ready` and its `calculated_at` has advanced past the pre-mutation value. A `loading` or\n `calculating` status may still carry the stale score. The `total` has no `calculated_at`, so\n gate it on `status` alone. If AI Search reports `error` or `unavailable`, report why and do not\n claim the combined target was reached.\n\n7. **Iterate with a stopping rule.** Address the largest remaining SEO or AI Search gap, then repeat\n steps 4 to 6. Stop when every selected target is met, when auto-optimize reports\n `nothing_to_optimize`, when the last useful gain is under about one point, or after 3 to 4 rounds.\n Report the baseline and final values for the SEO, AI Search, and unified Content Score separately.\n"
}SHA-256 of public snapshot: 2b55e41f8b22f6c5ac4123b8adafc2f6c06fe65764c6f7e8c87877aafa633729