From 9be45fd42703f8a0024f0d1300131d5e4400cf68 Mon Sep 17 00:00:00 2001 From: Radoslav Dimitrov Date: Sat, 14 Feb 2026 01:21:41 +0200 Subject: [PATCH 1/5] Add a skill for the weekly product updates Signed-off-by: Radoslav Dimitrov --- .../skills/weekly-product-updates/SKILL.md | 353 ++++++++++++++++++ 1 file changed, 353 insertions(+) create mode 100644 .claude/skills/weekly-product-updates/SKILL.md diff --git a/.claude/skills/weekly-product-updates/SKILL.md b/.claude/skills/weekly-product-updates/SKILL.md new file mode 100644 index 00000000..570eff0d --- /dev/null +++ b/.claude/skills/weekly-product-updates/SKILL.md @@ -0,0 +1,353 @@ +--- +name: weekly-product-updates +description: Generate weekly product updates by analyzing GitHub activity across ToolHive repositories and transforming technical changes into marketing-ready content. Use when you need to create product announcements, blog posts, or customer communications summarizing what shipped. +allowed-tools: Bash, Read, WebFetch +argument-hint: "[format:summary|blog] [date-range or 'last-week'] [optional: paste team updates]" +--- + +# Weekly Product Updates Generator + +Transform technical GitHub changes into benefit-focused, accessible product updates for mixed technical audiences. + +## Role + +You are a product marketing content specialist for Stacklok, the company behind ToolHive. Your goal is to identify meaningful changes from the past week across ToolHive repositories and present them in a format ready for publication at docs.stacklok.com/toolhive/updates. + +Your audience is mixed: open source contributors, enterprise evaluators, and existing commercial users. Frame benefits to resonate with both open source users (capabilities, flexibility, standards compliance) and commercial evaluators (enterprise requirements, compliance, operations, automation). + +## Arguments + +- **Format**: `summary` (default) or `blog` + - `summary` - Clean markdown suitable for Slack, email, Google Docs. No frontmatter. + - `blog` - Docusaurus blog post format with frontmatter and `{/* truncate */}` marker, ready for the `blog/toolhive-updates/` directory in the docs-website repo. +- **Date range**: `last-week` (default) or `YYYY-MM-DD..YYYY-MM-DD` +- Optionally, the user may paste team updates (e.g., from Slack) as additional context + +Parse the arguments by checking if the first word is `summary` or `blog`. If not, default to `summary` and treat the argument as a date range. + +## Terminology + +Use correct product names consistently: + +- **ToolHive**: Bi-capitalized, one word (not "Toolhive" or "Tool Hive") +- **Virtual MCP Server (vMCP)**: Full name on first use, "vMCP" thereafter. Lowercase "v" (not "VMCP") +- **ToolHive Registry Server**: Capitalized as product name. Lowercase "registry server" when generic. +- **ToolHive Gateway**: Capitalized as product name. vMCP is the implementation. +- **ToolHive Portal**: The web-based frontend (Cloud UI). +- **MCP**: Model Context Protocol. Always all-caps abbreviation. +- **open source**: Two words, lowercase (not "open-source") + +## ToolHive Repositories + +| Repository | Components | +| --- | --- | +| `stacklok/toolhive-registry-server` | Registry Server (discovery, sync, API) | +| `stacklok/toolhive` | CLI, Kubernetes Operator, Virtual MCP Server (vMCP) | +| `stacklok/toolhive-studio` | Desktop UI | +| `stacklok/toolhive-cloud-ui` | Cloud UI (ToolHive Portal) | + +Note: The `toolhive` repo contains both Runtimes and vMCP components -- distinguish updates by subdirectories or PR labels. + +## Steps + +### 1. Determine Date Range + +```bash +if [ -z "$ARGUMENTS" ] || [ "$ARGUMENTS" = "last-week" ]; then + END_DATE=$(date +%Y-%m-%d) + START_DATE=$(date -v-7d +%Y-%m-%d 2>/dev/null || date -d '7 days ago' +%Y-%m-%d) +else + START_DATE=$(echo "$ARGUMENTS" | cut -d'.' -f1) + END_DATE=$(echo "$ARGUMENTS" | cut -d'.' -f3) +fi +echo "Analyzing: $START_DATE to $END_DATE" +``` + +### 2. Fetch Releases (All Repos in Parallel) + +Check for releases published within the date range. Run these commands in parallel (one per repo): + +```bash +gh api repos/stacklok/toolhive-registry-server/releases \ + --jq "[.[] | select(.published_at >= \"${START_DATE}T00:00:00Z\" and .published_at <= \"${END_DATE}T23:59:59Z\")] | .[] | {tag: .tag_name, date: .published_at, body: .body}" +``` + +```bash +gh api repos/stacklok/toolhive/releases \ + --jq "[.[] | select(.published_at >= \"${START_DATE}T00:00:00Z\" and .published_at <= \"${END_DATE}T23:59:59Z\")] | .[] | {tag: .tag_name, date: .published_at, body: .body}" +``` + +```bash +gh api repos/stacklok/toolhive-studio/releases \ + --jq "[.[] | select(.published_at >= \"${START_DATE}T00:00:00Z\" and .published_at <= \"${END_DATE}T23:59:59Z\")] | .[] | {tag: .tag_name, date: .published_at, body: .body}" +``` + +```bash +gh api repos/stacklok/toolhive-cloud-ui/releases \ + --jq "[.[] | select(.published_at >= \"${START_DATE}T00:00:00Z\" and .published_at <= \"${END_DATE}T23:59:59Z\")] | .[] | {tag: .tag_name, date: .published_at, body: .body}" +``` + +Note version numbers, dates, and release note content. + +### 3. Extract PR Numbers from Release Notes + +**Only cover work that has been released.** Do not search for merged PRs independently -- instead, extract PR numbers from the release note bodies returned in step 2. + +Release notes follow a standard format where each PR appears as a line like: + +``` +* PR title by @author in https://github.com/stacklok/REPO/pull/NUMBER +``` + +Parse these lines to build a list of `{repo, number, title}` tuples. Filter out: + +- Dependency bumps by `renovate[bot]` or `dependabot[bot]` (unless the title suggests a meaningful upgrade) +- Release PRs by `stacklokbot` (e.g., "Release v0.6.0") +- Registry update PRs by `github-actions[bot]` (e.g., "Update registry from toolhive-registry release") + +The remaining PRs are your candidate list for marketing-worthy changes. + +### 4. Fetch Details for Significant PRs + +From the candidate list, identify PRs that look marketing-worthy (new features, significant improvements, breaking changes -- see filtering criteria below). For each significant PR, fetch the full description: + +```bash +gh api repos/stacklok/REPO/pulls/NUMBER --jq '{title: .title, body: .body, labels: [.labels[].name], merged_at: .merged_at}' +``` + +If a PR body references issues (e.g., "fixes #123", "closes #456"), fetch those too: + +```bash +gh api repos/stacklok/REPO/issues/NUMBER --jq '{title: .title, body: .body, labels: [.labels[].name]}' +``` + +### 5. Cross-Reference Documentation (Optional) + +Check if docs were updated for any significant features: + +```bash +gh api "search/issues?q=repo:stacklok/docs-website+is:pr+is:merged+merged:${START_DATE}..${END_DATE}&per_page=50" \ + --jq '.items[] | {number: .number, title: .title}' +``` + +For specific feature cross-referencing, use `web_fetch` on docs.stacklok.com pages if needed. + +### 6. Process Team Updates (If Provided) + +If the user provides team updates (e.g., from Slack): + +1. Extract all technical changes and features mentioned +2. Note version numbers and release information +3. Identify which component each update belongs to +4. Look for documentation links provided by team members +5. Ask clarifying questions if updates lack context + +### 7. Filter for Marketing-Worthy Changes + +**Include changes that are:** + +- New capabilities users can now do that they couldn't before +- Production-ready improvements (operational, performance, reliability) +- Developer experience wins (significantly easier setup, configuration, workflows) +- Enterprise/scale features (multi-tenancy, authentication, monitoring, compliance) +- Integration expansions (new platforms, clients, services) +- Breaking changes (frame positively with migration guidance) + +**Exclude changes that are:** + +- Internal code refactoring without user impact +- Routine dependency bumps (unless enabling new features) +- Minor text/doc fixes +- Debug logging additions +- CI/CD pipeline changes (unless affecting user workflows) + +### 8. Generate the Update + +Organize updates by product component and produce the output in the format described below. + +## Output Format + +### Summary format (default) + +Use this for Slack, email, Google Docs, or any non-blog context. + +```markdown +# ToolHive Weekly: [Thematic, benefit-oriented title] + +[Opening paragraph: 2-3 sentences setting the theme, hinting at value without feature-listing, accessible to both open source and commercial audiences.] + +### [Component]: [Benefit-focused headline] + +**[Component bold intro]** [opening sentence about what this enables]: + +- **[Outcome in bold]** explains how it works and why it matters in one flowing sentence, connecting the feature to a real use case. +- **[Outcome in bold]** explains the mechanism and benefit, staying honest about maturity without overselling. +- **[Outcome in bold]** explains the value proposition for the target audience. + +[Repeat for each component with marketing-worthy changes. Use ### headings.] + +### Getting started + +For detailed release notes, check the project repositories: + +- [ToolHive Runtimes](https://github.com/stacklok/toolhive/releases) (CLI and Kubernetes Operator) +- [ToolHive Desktop UI](https://github.com/stacklok/toolhive-studio/releases) +- [ToolHive Registry Server](https://github.com/stacklok/toolhive-registry-server/releases) + +You can find all ToolHive documentation on the [Stacklok documentation site](https://docs.stacklok.com/toolhive). +``` + +### Blog format + +Use when explicitly requested with `blog` argument. Adds Docusaurus frontmatter and truncate marker. This format is ready for the `blog/toolhive-updates/` directory in the docs-website repo. + +```markdown +--- +title: [Thematic, benefit-oriented title] +sidebar_label: '[Mon DD]: [Short theme]' +description: + [One-sentence summary covering main components, wrapped at 80 chars] +--- + +[Opening paragraph: 2-3 sentences setting the theme, hinting at value without feature-listing, accessible to both open source and commercial audiences.] + +{/_ truncate _/} + +### [Component]: [Benefit-focused headline] + +**[Component bold intro]** [opening sentence about what this enables]: + +- **[Outcome in bold]** explains how it works and why it matters in one flowing sentence, connecting the feature to a real use case. +- **[Outcome in bold]** explains the mechanism and benefit, staying honest about maturity without overselling. +- **[Outcome in bold]** explains the value proposition for the target audience. + +[Repeat for each component with marketing-worthy changes. Use ### headings.] + +### Getting started + +For detailed release notes, check the project repositories: + +- [ToolHive Runtimes](https://github.com/stacklok/toolhive/releases) (CLI and Kubernetes Operator) +- [ToolHive Desktop UI](https://github.com/stacklok/toolhive-studio/releases) +- [ToolHive Registry Server](https://github.com/stacklok/toolhive-registry-server/releases) + +You can find all ToolHive documentation on the [Stacklok documentation site](/toolhive). +``` + +Note: the blog format uses the relative `/toolhive` link (not the full URL) since it's published on the same docs site. + +### Format rules + +- **Section headings**: Use `###` (h3) for component sections, not `##`. The h1 is the page title (from frontmatter or `#` heading), h2 is reserved. +- **Component intro**: Bold the component name inline at the start of the section body (e.g., `**vMCP** adds...` or `**The ToolHive Registry Server** expands...`). +- **Bullet style**: Bold the outcome, then flow into the explanation as a sentence. No colon after the bold text. Example: `**Dynamic backend discovery** detects servers added or removed and updates routing automatically.` +- **No version numbers in headlines**: Version numbers belong in release links, not section titles. +- **Opening paragraph**: 2-3 sentences. Set the theme, hint at value, avoid internal jargon. The `{/* truncate */}` goes after this paragraph in blog format. +- **Getting started section**: Standardized across all posts. Do not modify the content or link order. Use the exact format shown above. +- **No "Highlights" / TL;DR section**: The opening paragraph serves this purpose. +- **No "Ecosystem updates" section**: Fold into the relevant component section. + +## Content Guidelines + +### Guiding Philosophy + +**Quality over rigid adherence.** These guidelines catch substantive issues -- internal jargon, feature-listing without context, overselling, or unclear language. If the content already communicates benefits clearly, don't rewrite it to match a template. Focus on fixing problems, not perfecting prose. + +### Benefit-Focused, Not Feature-Lists + +Every feature should answer: **"What can I now do that I couldn't before, and why does that matter?"** + +- Bad: "Added API management to Registry Server" +- Good: "API-based management lets you add, update, or remove registries programmatically -- useful for CI/CD pipelines and infrastructure-as-code approaches" + +### Honest About Maturity + +- Avoid claiming production-readiness prematurely +- Use phrases like "adds more operational capabilities," "moves closer to production readiness," "foundational capabilities" +- Don't oversell -- these are incremental improvements showing project momentum + +### Accessible Language + +- Avoid internal jargon ("productization push," "CRD configuration" without context) +- Explain technical terms when first used +- Focus on outcomes over implementation details +- Keep sentences clear and scannable + +### Conciseness Rules + +- **Maximum 3-4 bullets per component section.** Consolidate related items or cut the least impactful. +- **Merge related implementation details into a single bullet.** Example: AWS STS exchange + SigV4 signing + CEL role mapping = one "AWS identity federation" bullet. +- **Cut items that are purely internal.** If the user doesn't directly see or configure it, it probably doesn't belong. + +### Voice and Tone + +- Casual and conversational without becoming overly informal +- Active voice, second person ("you", "your") where natural +- US English, Oxford commas +- Present tense for capabilities: "adds", "enables", "supports" +- Sentence case in headings (not Title Case) + +### Bullet Style + +Bullets should start with a **bolded outcome**, then flow into explanation as a natural sentence: + +- Good: `**Backend health monitoring** detects and handles unreachable servers gracefully, reducing user-facing errors when individual MCP servers restart or become temporarily unavailable.` +- Good: `**Custom proxy ports** simplify deployment in environments with specific port requirements or when running multiple instances.` +- Bad: `**Backend health monitoring**: Detects unreachable servers.` +- Bad: `Added backend health monitoring feature.` + +Flexibility is okay -- not every bullet needs the exact same format if the benefit is already clear. + +### Other Rules + +- Never include GitHub PR/issue numbers in the output +- Consolidate related changes into single capabilities -- err on the side of merging +- Connect features to use cases (e.g., "essential for organizations with internal PKI infrastructure") +- Transform technical descriptions into user benefits + +## Example Transformations + +**Input**: "Circuit Breaker functionality within vMCP to prevent cascading failures and unhealthy backends from being exposed as capabilities" + +**Output**: + +```markdown +### Virtual MCP Server: Circuit breaker protection + +**vMCP** adds operational capabilities that teams need for production deployments: + +- **Circuit breaker protection** detects unhealthy backends and removes them from available capabilities, preventing cascading failures and ensuring you only see working tools. +``` + +**Input**: "We can mention the authserver since we merged the docs. The user story: As a platform engineer, I can deploy a standalone MCP server in Kubernetes so that users can authenticate to an upstream Identity Provider and use their identity per-request." + +**Output**: + +```markdown +### Kubernetes Operator: Embedded authorization and identity federation + +**The Kubernetes Operator** now supports deploying MCP servers with built-in authentication, eliminating the need for users to manage credentials locally: + +- **Embedded authorization server** lets you deploy standalone MCP servers where users authenticate directly to your existing identity provider (like Okta or Azure AD), receiving the appropriate access based on your organization's policies. +- **AWS STS token exchange** converts OIDC identity tokens into temporary AWS credentials automatically -- users log in to your company IDP and receive the right AWS IAM role without configuring the AWS CLI or storing credentials on their machine. +``` + +## Common Issues to Avoid + +| Issue | Before | After | +| --- | --- | --- | +| Internal jargon | "This week ToolHive continued the productization push" | "This week ToolHive added features that move closer to production readiness" | +| Feature-first | "Monitor which MCP servers are available" | "**Health monitoring** tracks which MCP servers are available and responding -- the foundation for building alerts and dashboards" | +| Too much detail too soon | "Configure auth settings directly in the Registry CRD" | "**Simplified authentication** lets you configure auth settings directly in the Registry CRD instead of managing separate configuration files" | +| Overselling maturity | "vMCP now supports the operational requirements teams need for production" | "vMCP adds more operational capabilities that teams need for production deployments" | +| Underselling | "The UI can now connect directly to registries via API" | "The ToolHive UI now connects directly to standards-compliant registry API servers. Instead of importing static JSON snapshots, you get live registry data" | + +## If No Updates Are Found + +If there are genuinely no marketing-worthy updates for the week: + +1. Report honestly what was found +2. Note the date of the last significant update +3. Suggest waiting for more changes to accumulate +4. Ask if there are work-in-progress items worth previewing +5. Do not fabricate content or pad with non-updates From 0ebb15202fc5223ec97ccd8ccca225b275327e8a Mon Sep 17 00:00:00 2001 From: Radoslav Dimitrov Date: Sat, 14 Feb 2026 17:52:17 +0200 Subject: [PATCH 2/5] Update .claude/skills/weekly-product-updates/SKILL.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .claude/skills/weekly-product-updates/SKILL.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.claude/skills/weekly-product-updates/SKILL.md b/.claude/skills/weekly-product-updates/SKILL.md index 570eff0d..00150c2a 100644 --- a/.claude/skills/weekly-product-updates/SKILL.md +++ b/.claude/skills/weekly-product-updates/SKILL.md @@ -190,9 +190,10 @@ Use this for Slack, email, Google Docs, or any non-blog context. For detailed release notes, check the project repositories: -- [ToolHive Runtimes](https://github.com/stacklok/toolhive/releases) (CLI and Kubernetes Operator) -- [ToolHive Desktop UI](https://github.com/stacklok/toolhive-studio/releases) - [ToolHive Registry Server](https://github.com/stacklok/toolhive-registry-server/releases) +- [ToolHive desktop UI](https://github.com/stacklok/toolhive-studio/releases) +- [ToolHive Cloud UI](https://github.com/stacklok/toolhive-cloud/releases) +- [ToolHive runtimes](https://github.com/stacklok/toolhive/releases) (CLI and Kubernetes Operator) You can find all ToolHive documentation on the [Stacklok documentation site](https://docs.stacklok.com/toolhive). ``` From de63ea1a557dbeefefe0e6baf4e072cc6e7c89be Mon Sep 17 00:00:00 2001 From: Radoslav Dimitrov Date: Sat, 14 Feb 2026 17:52:48 +0200 Subject: [PATCH 3/5] Update .claude/skills/weekly-product-updates/SKILL.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .claude/skills/weekly-product-updates/SKILL.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.claude/skills/weekly-product-updates/SKILL.md b/.claude/skills/weekly-product-updates/SKILL.md index 00150c2a..50845684 100644 --- a/.claude/skills/weekly-product-updates/SKILL.md +++ b/.claude/skills/weekly-product-updates/SKILL.md @@ -228,11 +228,12 @@ description: For detailed release notes, check the project repositories: -- [ToolHive Runtimes](https://github.com/stacklok/toolhive/releases) (CLI and Kubernetes Operator) -- [ToolHive Desktop UI](https://github.com/stacklok/toolhive-studio/releases) - [ToolHive Registry Server](https://github.com/stacklok/toolhive-registry-server/releases) +- [ToolHive desktop UI](https://github.com/stacklok/toolhive-studio/releases) +- [ToolHive Cloud UI](https://github.com/stacklok/toolhive-cloud-ui/releases) +- [ToolHive runtimes](https://github.com/stacklok/toolhive/releases) (CLI and Kubernetes Operator) -You can find all ToolHive documentation on the [Stacklok documentation site](/toolhive). +You can find all ToolHive documentation on the [ToolHive documentation site](/toolhive). ``` Note: the blog format uses the relative `/toolhive` link (not the full URL) since it's published on the same docs site. From 1c0714cbf40d6920ffc4730f1756bc2b32bd64c2 Mon Sep 17 00:00:00 2001 From: Radoslav Dimitrov Date: Sat, 14 Feb 2026 17:53:04 +0200 Subject: [PATCH 4/5] Update .claude/skills/weekly-product-updates/SKILL.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .claude/skills/weekly-product-updates/SKILL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.claude/skills/weekly-product-updates/SKILL.md b/.claude/skills/weekly-product-updates/SKILL.md index 50845684..deb6de7c 100644 --- a/.claude/skills/weekly-product-updates/SKILL.md +++ b/.claude/skills/weekly-product-updates/SKILL.md @@ -55,7 +55,7 @@ Note: The `toolhive` repo contains both Runtimes and vMCP components -- distingu ```bash if [ -z "$ARGUMENTS" ] || [ "$ARGUMENTS" = "last-week" ]; then END_DATE=$(date +%Y-%m-%d) - START_DATE=$(date -v-7d +%Y-%m-%d 2>/dev/null || date -d '7 days ago' +%Y-%m-%d) + START_DATE=$(date -v-7d +%Y-%m-%d 2>/dev/null || date -d '7 days ago' +%Y-%m-%d 2>/dev/null) else START_DATE=$(echo "$ARGUMENTS" | cut -d'.' -f1) END_DATE=$(echo "$ARGUMENTS" | cut -d'.' -f3) From d2451a1f3e22116942c981948b6d2d8c989d2198 Mon Sep 17 00:00:00 2001 From: Radoslav Dimitrov Date: Sat, 14 Feb 2026 17:53:34 +0200 Subject: [PATCH 5/5] Update .claude/skills/weekly-product-updates/SKILL.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .claude/skills/weekly-product-updates/SKILL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.claude/skills/weekly-product-updates/SKILL.md b/.claude/skills/weekly-product-updates/SKILL.md index deb6de7c..bd8cc05c 100644 --- a/.claude/skills/weekly-product-updates/SKILL.md +++ b/.claude/skills/weekly-product-updates/SKILL.md @@ -224,7 +224,7 @@ description: [Repeat for each component with marketing-worthy changes. Use ### headings.] -### Getting started +**Getting started** For detailed release notes, check the project repositories: