# Peec Setup

> End-to-end Peec AI project setup — competitor discovery from real AI chats, customer-journey prompt design across Awareness → Consideration → Decision → Retention, topic/tag taxonomy, GSC-based keyword mapping, forum pain-point mining (Reddit, Gutefrage, t3n, OMR), and a categorized executable backlog. Use when the user wants to set up, restructure, or audit a Peec AI project for their own brand…

- **Type:** Skill
- **Install:** `agentstack add skill-antonioblago-peec-ai-skills-peec-setup`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [AntonioBlago](https://agentstack.voostack.com/s/antonioblago)
- **Installs:** 0
- **Category:** [AI & ML](https://agentstack.voostack.com/c/ai-and-ml)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [AntonioBlago](https://github.com/AntonioBlago)
- **Source:** https://github.com/AntonioBlago/peec-ai-skills/tree/main/skills/peec-setup
- **Website:** https://antonioblago.de

## Install

```sh
agentstack add skill-antonioblago-peec-ai-skills-peec-setup
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# AI Visibility Setup

## Role
Take a Peec AI project from empty (or broken) to operator-ready: correct competitors, full-funnel prompts, coherent taxonomy, GSC keyword mapping, forum-mined buyer language, and a categorized executable backlog the client can run for the next 2 weeks.

## Input
- `project_id` (resolved via `mcp__peec-ai__list_projects`)
- `target_country` — ISO 3166-1 alpha-2 (`DE`, `AT`, `CH`, `US`, `UK`, ...). Default `DE`. Drives SERP/GSC filters and forum source selection.
- `prompt_language` — ISO 639-1 (`de`, `en`, `fr`, ...). Default = lowercase of `target_country` (`DE` → `de`). Drives the language Peec prompts are authored in.
- Optional: `secondary_languages` — list, default `[]`. Used for multi-market projects (e.g. DE primary + EN secondary).
- Optional: `offer_keywords` (retainer, monthly, etc.), `own_domain`
- Optional: `scope` — `full` | `audit` | `partial:` | `competitors_only` | `prompts_only` | `taxonomy_only` (default: auto-detected from setup state, see Phase 0)

**Resolving language/country at start:**
1. If state file exists with these fields → use them, skip the question.
2. Else if user passed them as arguments → use those.
3. Else infer from `own_domain` TLD (`.de` → DE/de, `.at` → AT/de, `.ch` → CH/de + ask de/fr, `.com` → ASK).
4. Else ASK the user **once** before Phase 1: "Target country (ISO, e.g. DE)? Prompt language (ISO, e.g. de)?". Persist the answer in state.

Never silently default to `EN`/`en` when the project has no signal — this corrupts every downstream skill.

## Output
A setup report with: before/after counts, funnel distribution (e.g. 5/5/5/5), the single **hero prompt** to win first, the refresh timeline (24h for fresh data), a categorized P0/P1/P2 backlog, and any user-preference memories saved. No dashboards.

## When to use
- "Set up Peec for "
- "My Peec competitors are wrong / not real competitors"
- "Design prompts for my customer journey"
- "Map GSC keywords to my Peec prompts"
- "Restructure Peec topics / tags"
- Audit of an existing AI-visibility tracking setup

## Prerequisites
- Peec AI MCP connected (`mcp__peec-ai__*`)
- Visibly AI MCP connected (`mcp__visiblyai__*`) — optional, only for GSC
- GSC + GA4 connected inside Visibly AI (check via `get_google_connections`)

## State

This skill **owns** the setup state file. See [`_shared/SETUP_STATE.md`](../_shared/SETUP_STATE.md) for the full schema and protocol.
- **Reads** `/growth_loop/setup_state.json` at Phase 0 to decide the run mode (`full | audit | partial | skip`).
- **Writes** the same file at the end of Phase 9 with merged `phases_completed` and a fresh `snapshot`.

All other skills in this repo refuse to run without this file — never bootstrap a setup from inside another skill.

---

## Phase 0 — State check & mode selection

Always runs first. Cheap (single file read + at most one parallel Peec read in brownfield case). Determines whether the rest of the run is needed at all.

```
1. Read /growth_loop/setup_state.json

2. If state file MISSING:
   2a. Live-detect Peec content (parallel reads):
         list_brands(project)
         list_prompts(project, limit=5)
         list_topics(project)
         list_tags(project)
   2b. If Peec is empty (≤2 brands AND ≤4 prompts AND ≤0 topics):
         → mode = full     (greenfield — proceed to Phase 1)
   2c. If Peec is populated (≥3 brands OR ≥5 prompts OR ≥1 topic):
         → mode = import   (brownfield — see "Import mode" below)

3. If state file PRESENT, branch on `completed_at`:
      90 days ago       → mode = full      (warn: stale)

4. If user passed an explicit `scope`, that wins over auto-detection.

5. Print one line:
     "Setup state:  · age: N days · mode: "
```

### `import` mode (brownfield) — runs entirely inside Phase 0

Per [`_shared/SETUP_STATE.md` §`import` mode](../_shared/SETUP_STATE.md), this mode reconstructs `setup_state.json` from live Peec data without re-doing discovery.

```
1. Show user one line:
     "Detected existing Peec setup:  brands,  prompts,  topics,  tags."
2. ASK three things at once (single user turn):
     - "Import this as the setup state, or run full setup from scratch? [import/full]"
     - "Target country (ISO, e.g. DE)?"
     - "Prompt language (ISO, e.g. de)?"
3. If user picks `import`:
     a. Infer completed_at (NEVER default to now silently):
          read created_at from list_brands + list_prompts;
          completed_at = min(created_at across first 5 brands AND first 5 prompts)
          If unavailable → list_chats(limit=1, sort=asc).timestamp
          If still unavailable → ASK user one bucket question
            ("when did you set this up? [today/past month/past quarter/past year/older]")
            and map to a date.
     b. Build state object:
          phases_completed = inferred from non-empty buckets (brands≥3 → +competitors; etc.)
          snapshot         = the counts just read
          completed_at     = inferred per (a) above
          imported_at      = now (UTC)
          last_audit_at    = now
          hero_prompt_id   = null
          target_country, prompt_language = from user answers in step 2
          notes            = "imported from existing Peec project on ;
                              original setup inferred at "
          setup_version    = "1.1"
     c. **Persist immediately** — atomic write to /growth_loop/setup_state.json
        (write to .tmp, then rename). Do not wait for any other phase.
     d. Print:
          "State imported: /growth_loop/setup_state.json (phases: X/7).
           Inferred setup date:  (~N days ago).
           Run /peec-agent to pick the next move, or /peec-setup
           partial:gsc_mapping to fill in skipped phases."
     e. Exit Phase 0. Do NOT proceed to Phase 1 — import mode finishes here.
        The user can now invoke any consumer skill; they will all read the freshly
        written state. If they want missing phases (e.g. forum_mining never happened),
        they explicitly call partial:.
4. If user picks `full`:
     CONFIRM ONCE MORE: "Full setup will create new prompts/topics/tags alongside
     the existing ones. Proceed? [yes/no]"
     On yes → mode = full, proceed to Phase 1.
     On no  → exit cleanly.
```

**`skip` mode behaviour:** show the existing snapshot (counts, phases, hero_prompt_id) and ask "Re-run anyway? [audit / partial: / full / no]". Do not auto-run.

**`audit` mode behaviour:** call `list_brands / list_prompts / list_topics / list_tags` and compare counts to `snapshot`. For each phase where drift > 20% (or a P0 red flag from Phase 1 reappears), re-run only that phase. Append `last_audit_at` on write.

**`partial:` mode:** jump straight to the named phase, skip everything else.

If `mode == skip` and user declines re-run, exit cleanly with a 3-line summary — no further phases.

---

## Phase 0.5 — Business type, audience & page-type taxonomy

Always runs in `full`, `import`, and `audit` modes (only skipped in `skip` mode). These three fields gate every downstream content decision — a wrong `business_type` corrupts every brief `/peec-content-intel` and every zone one-move `/peec-cluster` emits.

```
1. Read setup_state.json. If business_type + audience + page_type_taxonomy are all present
   AND setup_version == "1.2" → skip this phase, continue to Phase 1.

2. If any are missing, ASK the user in ONE turn:

   "Before I build prompts, I need three things (all in one message is fine):

    (a) Business type — pick one:
        • b2b-service    (freelancer, agency, consulting — you sell hours or retainers)
        • b2c-ecommerce  (D2C shop — you sell products, typically Shopify/WooCommerce)
        • b2b-saas       (software product with subscriptions)
        • info-product   (courses, memberships, digital products)
        • local-service  (physical location, catchment-area business)
        • marketplace    (multi-seller platform)

    (b) Audience — one sentence on your primary buyer.
        Example: 'Shop-Owner DACH, 3–20 Mitarbeiter, Shopify, 500k–5M Umsatz, Pain: 3 SEO-Agenturen gewechselt.'

    (c) Optional: known buyer pain-points (comma-separated, forum language welcome)."

3. Parse the answer. Build:
     business_type      = one of the six canonical values
     audience.primary   = the sentence
     audience.buyer_personas = extracted nouns from (b) — e.g. ["Shop-Owner Shopify", "DACH"]
     audience.pain_points = list from (c), else []

4. Generate page_type_taxonomy from the business-type matrix
   (see _shared/SETUP_STATE.md §"Business-type → page-type matrix"):

     b2b-service    → ["pillar", "landing_page", "blog_post", "case_study", "comparison", "faq", "pricing"]
     b2c-ecommerce  → ["pdp", "collection", "pillar", "blog_post", "guide", "category_page", "faq"]
     b2b-saas       → ["landing_page", "integration", "use_case", "blog_post", "comparison", "docs", "pricing"]
     info-product   → ["sales_page", "webinar_lp", "blog_post", "case_study", "faq", "lead_magnet"]
     local-service  → ["local_landing", "landing_page", "case_study", "blog_post", "faq"]
     marketplace    → ["collection", "pdp", "category_page", "pillar", "blog_post"]

5. Add "business_type" and "audience" to phases_completed.
   Set setup_version = "1.2".
   Persist immediately (atomic write).

6. Print one line:
     "Business:  · Audience:  · Page types: "
```

**Why this matters downstream:**
- `/peec-content-intel` picks `page_type` per brief — if the brief says `pdp` but `business_type=b2b-service`, that's a rejected brief (caught by the taxonomy check).
- `/peec-cluster` names a `page_type` per zone's one-move. If zone competitors are all `CATEGORY_PAGE` but your taxonomy can't produce `collection`, the zone's one-move switches to **outreach** instead of content creation — automatically.
- `/peec-agent` reads `audience.pain_points` when generating Awareness-stage content recommendations.
- `/peec-report` attributes by `page_type` to learn which types actually moved visibility.

**Never guess `business_type`.** A `.de` domain selling shoes is not `b2b-service` even if it looks like a typical German agency URL. Always ASK once; persist once.

---

## Phase 1 — Initial audit

Run in parallel:

```
mcp__peec-ai__list_projects
mcp__peec-ai__list_brands(project_id)         # current competitors
mcp__peec-ai__list_prompts(project_id, limit=200)
mcp__peec-ai__list_topics(project_id)
mcp__peec-ai__list_tags(project_id)
```

**Red flags to call out:**
- Competitors list contains **SaaS tool brands** (SEMrush, Ahrefs, Sistrix, Moz, Ryte, Yoast, Screaming Frog, SurferSEO, Frase). For a freelancer / consultant project these distort SoV — they are not buyers' alternatives.
- Prompts clustered in one funnel stage only (e.g. all MOFU "empfiehl" — no Awareness / Decision / Retention coverage).
- Topics represent **themes only** (e.g. "AI" / "SEO") — can't track funnel performance.
- Tags are only Peec's default 4 (branded / non-branded / informational / transactional) — no offer-specific slicing possible.

---

## Phase 2 — Competitor discovery (ground truth)

### 2a. Extract from AI chats (authoritative)

For each **losing prompt** (own brand 0% visibility, competitors present):

```
mcp__peec-ai__list_chats(project_id, start_date, end_date, prompt_id=)
  → pick 1 chat per engine (chatgpt-scraper, perplexity-scraper, google-ai-overview-scraper)
mcp__peec-ai__get_chat(project_id, chat_id)
  → inspect messages[] for freelancer / consultant names
  → inspect sources[]  for their domains
```

Extract: human names, domain names, sources the AI pulled. These are the **real** competitors LLMs recommend against you.

### 2b. Supplement with web research

```
WebSearch("SEO Freelancer Deutschland  2026")
WebSearch(" Freelancer Experte KI ChatGPT empfehlen")
```

Cross-check against the domain report — any domain retrieving (`get_domain_report`) but not tracked as a brand is an **invisible competitor**:

```
mcp__peec-ai__get_domain_report(project_id, start_date, end_date, limit=25)
  → find domains with retrieved_percentage > 5% not yet in list_brands
```

---

## Phase 3 — Competitor curation (mutation)

### 3a. Add real competitors

Batch-call in parallel:

```
mcp__peec-ai__create_brand(
  project_id,
  name="",
  domains=["their-domain.de"],
  aliases=["Alternate Spelling"]   # Umlaut ↔ ASCII variants, abbreviations
)
```

Categories to include:
- **Direct positioning overlap** (e.g. KI-SEO, GEO, Neuro-SEO freelancers)
- **Niche-specific freelancers** (E-commerce / Shopify SEO)
- **Local competitors** (same city / region)
- **Micro-agencies** (5–20 person KI / GEO specialists)
- **Invisible competitors** already appearing in the domain report

### 3b. Remove irrelevant competitors

For solo freelancer / service-business projects, remove SaaS tool brands:

```
mcp__peec-ai__delete_brand(project_id, brand_id)
```

Tool brands to remove: SEMrush, Ahrefs, Sistrix, Moz, Ryte, Yoast, Screaming Frog, SurferSEO, Frase, SE Ranking.

Deletion is soft. Also save a feedback memory noting "track humans only" so future sessions don't re-suggest these.

---

## Phase 4 — Keyword & intent analysis (Visibly AI + GSC)

### 4a. Verify GSC connection
```
mcp__visiblyai__get_google_connections()
  → confirm domain has a gsc_property and (ideally) a GA4 pairing
```

### 4b. Pull GSC keywords
```
mcp__visiblyai__get_keywords(domain="example.com", limit=200, location="Germany")
# or for finer control:
mcp__visiblyai__query_search_console(dimension="query", days=28, country="deu", limit=500)
```

### 4c. Classify intent

Cluster keywords into:
- **Informational (TOFU)** — "was ist", "wie funktioniert", " ohne anmeldung", ratgeber queries
- **Brand** — client brand name + variations
- **Commercial (MOFU)** — "beste", "vergleich", "Agentur vs Freelancer"
- **Transactional (BOFU)** — "Kosten", "Preis", "buchen", "kontaktieren", " + "

**Frequent pattern:** domain ranks well for TOFU informational (blog traffic) but is invisible for commercial / transactional — those are exactly the queries Peec prompts should test.

### 4d. Map GSC keywords → Peec prompts

For each top GSC keyword: does a Peec prompt exist that tests AI visibility for the same intent? If not, flag as "prompt gap".

---

## Phase 5 — Forum pain-point mining

Mine **verbatim buyer pain** from public forums → convert into Peec prompts that match real customer language (not sanitized marketing phrasing). These prompts also reveal what LLMs pull from UGC, and whether the brand surfaces in those answers.

### 5a. Sources

**German (priority for DACH):**
- Reddit DE — `r/de`, `r/Finanzen`, `r/kmu`, `r/selbststaendig`, `r/Unternehmer`; niche: `r/shopify`, `r/ecommerce`, `r/SEO`
- Gutefrage.net — broadest DE consumer Q&A; strong for commercial / transactional pain
- t3n forum (`t3n.de/forum`) — DACH digital / business pros
- OMR forum (`omr.com/de/forum`) — marketing / SEO operator pain
- gründerszene comments / deutsche-startups — B2B startup pain

**Global / EN fallback:**
- Reddit: `r/SEO`, `r/localseo`, `r/ecommerce`, `r/shopify`, `r/smallbusiness`, `r/entrepreneur`
- Quora
- Stack Exchange (Webmasters, Freelancing) for technical pain

**Video / social UGC (via WebFetch):**
- YouTube comment sections under competitor videos surfaced in the domain report
- LinkedIn post comments on competitor pulse articles (from `get_actions`)

### 5b. Query patterns

Run in parallel — different pain angles:

```
WebSearch("site:reddit.com  ")
# problem-words: "funktioniert nicht", "erfahrungen", "lohnt sich", "hilfe", "enttäuscht"
WebSearch("site:gutefrage.net ")
WebSearch("site:t3n.de/forum ")
WebSearch("site:omr.com  frage")
WebSearch(" erfahrungen forum")
WebSearch(" review reddit")
```

Example for a DACH SEO-retainer project:
- `site:reddit.com SEO Freelancer erfahrungen`
- `site:gutefrage.net SEO Berater lohnt sich`
- `"Shopify SEO" "funktioniert nicht" forum`
- `"KI SEO" reddit erfahrung`

### 5c. Extract threads

```
WebFetch(url, "Extract the original question verbat

…

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [AntonioBlago](https://github.com/AntonioBlago)
- **Source:** [AntonioBlago/peec-ai-skills](https://github.com/AntonioBlago/peec-ai-skills)
- **License:** MIT
- **Homepage:** https://antonioblago.de

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-antonioblago-peec-ai-skills-peec-setup
- Seller: https://agentstack.voostack.com/s/antonioblago
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
