# ── Shared base ────────────────────────────────────────────────────────── # Globals, MCP servers, subjects, all agents, and the SHARED content-pipeline # phases. Per-workflow phases + workflow defs + schedules live in workflow-*.yaml. # All .animus/workflows/*.yaml compile together (animus workflow config compile). default_workflow_ref: blog-production tools_allowlist: - git - gh - bash - WebSearch - WebFetch mcp_servers: animus: command: animus args: - mcp - serve exa: command: npx args: - -y - exa-mcp-server env: EXA_API_KEY: ${EXA_API_KEY:-UNSET} tavily: command: npx args: - -y - tavily-mcp env: TAVILY_API_KEY: ${TAVILY_API_KEY:-UNSET} brave: command: npx args: - -y - '@anthropic/brave-search-mcp' env: BRAVE_API_KEY: ${BRAVE_API_KEY:-UNSET} firecrawl: command: npx args: - -y - firecrawl-mcp-server env: FIRECRAWL_API_KEY: ${FIRECRAWL_API_KEY:-UNSET} google-maps: command: npx args: - -y - google-maps-mcp-server env: GOOGLE_MAPS_API_KEY: ${GOOGLE_MAPS_API_KEY:-UNSET} search-console: command: npx args: - -y - search-console-mcp env: GSC_CLIENT_EMAIL: ${GSC_CLIENT_EMAIL:-UNSET} GSC_PRIVATE_KEY: ${GSC_PRIVATE_KEY:-UNSET} replicate: command: npx args: - -y - replicate-mcp env: REPLICATE_API_TOKEN: ${REPLICATE_API_TOKEN:-UNSET} perplexity: command: npx args: - -y - '@perplexity/modelcontextprotocol' env: PERPLEXITY_API_KEY: ${PERPLEXITY_API_KEY:-UNSET} transcript-source: # SINGLE active transcript provider (Krisp OR Granola — never both). Wire # your provider's MCP command/args/env here; TRANSCRIPT_PROVIDER must match # what you wire. Until then this stub exits immediately, so transcript-fetch # fails fast (not silently) and the discovery schedule stays disabled. command: "true" args: [] env: {} content-library: # BRING YOUR OWN (macOS): an org "knowledge brain" MCP server that gives # agents deep drafting context — prior research, established facts, brand # positions, and angles already used — so they produce unique, high-quality # content. Replace command/args/env with your own content MCP. Until then # this is a no-op stub; agents fall back to content/manifest.json + research. command: "true" args: [] env: {} subjects: - id: linear-discovery backend: linear config: # Real values go in .env (sourced into the daemon's shell). Uses the # repo's :-UNSET convention so config compiles before secrets exist; the # linear backend stays non-functional until LINEAR_API_TOKEN is set. team_id: ${LINEAR_TEAM_ID:-UNSET} project_id: ${LINEAR_DISCOVERY_PROJECT_ID:-UNSET} agents: content-strategist: model: claude-sonnet-4-6 tool: claude mcp_servers: - animus - exa - tavily - brave - firecrawl - search-console - content-library system_prompt: | SKILLS: Read and follow .animus/skills/content-strategy.md CONTEXT: Read business-context.yaml for all client details — business info, target audience, competitors, content pillars, and differentiators. CONTENT BRAIN: Consult content-library for prior coverage, established facts, and angles already used when selecting topics or building briefs; ground choices in it. If unavailable or empty, use content/manifest.json and external research — do not block. Only in the news-scan / discovery phases: create tasks via animus_task_create and enqueue via animus_queue_enqueue for genuinely time-sensitive topics. When converting an existing ticket to a brief, do NOT create new subjects. content-researcher: model: claude-sonnet-4-6 tool: claude mcp_servers: - firecrawl - exa - tavily - brave - google-maps - content-library system_prompt: | CONTEXT: Read business-context.yaml — niche, audience, market area, competitors. Ground every search in that context. You gather source material for the content-writer; you do not write prose. CONTENT BRAIN: Query content-library (the org knowledge brain) for prior research, established facts, and brand positions; treat it as a primary source alongside external search. If it is unavailable or returns nothing, continue with external sources only — do not block. SOURCING RULES: - Prefer primary, recent, authoritative sources (industry/market reports, government or census data, named studies). Capture the exact source URL and publication date for each. - Every statistic must carry an attributable source — no orphan numbers. - Include local/market context when the niche is geo-relevant. - Flag claims you could not verify instead of passing them through. content-writer: model: claude-opus-4-6 tool: claude mcp_servers: - content-library system_prompt: | SKILLS: Read and follow .animus/skills/content-production.md, .animus/skills/ai-seo.md, .animus/skills/content-humanizer.md CONTEXT: Read business-context.yaml for client details and voice guidelines. CONTENT BRAIN: Before drafting, query content-library for related prior work, established facts, brand positions, and angles already used; ground the post in that context and avoid repeating prior angles. If content-library is unavailable or returns nothing, proceed using content/manifest.json and the research package — do not block. Write in the voice defined in business-context.yaml. Use the perspective, tone, and style specified there. Reference specific locations and details relevant to the business's market area. CONTENT RULES: Get to the point in 3-4 sentences. All claims need citations. Target readability: US grade 8-10 (Flesch Reading Ease ~60-70). Structure for scannability — headers, bullets, tables. Include Q&A sections for LLM extractability. Use specific numbers with sources. Include "As of [date]..." for recency signals. SEO: Target keyword in title, first paragraph, one H2, meta description. Keyword density 0.5-1.5%. Internal links to 2-3 related blog posts — source candidates from content-library MCP and content/manifest.json; use real slugs of published posts, do not invent them. First paragraph answers the core query directly (featured snippet). Output contract reminder: slug is required and must be emitted verbatim — downstream register-post and linear-finalize depend on it. Output: markdown with frontmatter (title, slug, meta_description, date, author, keywords, schema_type, content_pillar, target_keyword, word_count, featuredImage, excerpt, seoTitle, seoDescription). seo-optimizer: model: claude-sonnet-4-6 tool: claude mcp_servers: - search-console - firecrawl - content-library system_prompt: | SKILLS: Read and follow .animus/skills/seo-audit.md, .animus/skills/schema-markup.md, .animus/skills/ai-seo.md SEO AUDIT CHECKLIST: - Target keyword in title, first paragraph, at least one H2, meta description - Keyword density 0.5-1.5% - Meta description under 155 characters with CTA - Title under 60 characters - Internal links to 2-3 related blog posts (not service pages). Verify each slug via content-library MCP or content/manifest.json; drop and replace any broken slug. - No AI cliche words - Readability grade 8-10 SCHEMA MARKUP: This is a markdown/frontmatter pipeline. Update supported frontmatter/schema fields when available. Do not inject raw