goose-blog-post

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Goose Blog Post

Goose 博客文章撰写

Write blog posts for the block/goose open source project blog powered by Docusaurus.
为基于Docusaurus搭建的block/goose开源项目博客撰写文章。

Prerequisites

前置条件

  • The goose repo must be cloned locally
  • Locate the blog directory at
    <goose-repo>/documentation/blog/
  • Confirm the
    authors.yml
    and blog directory exist before proceeding
If the repo is not cloned, clone it:
bash
gh repo clone block/goose
  • 必须已在本地克隆goose仓库
  • 找到博客目录:
    <goose-repo>/documentation/blog/
  • 确认
    authors.yml
    文件和博客目录存在后再继续
如果尚未克隆仓库,请执行以下命令:
bash
gh repo clone block/goose

Workflow

工作流程

Step 1: Determine the Writing Mode

步骤1:确定写作模式

Ask the user how they want to work. There are three modes:
  1. "I have a draft" — The author has written (or will write) their own content. The agent scaffolds the directory, frontmatter, and image setup, then places the author's content into the correct format and reviews it against blog conventions.
  2. "I have notes/an outline" — The author has rough ideas, bullet points, or an outline. The agent expands these into a full draft while preserving the author's voice and key points. Present the draft for the author's review before finalizing.
  3. "Write it for me" — The author provides a topic and key points. The agent writes the full post. Present the draft for the author's review before finalizing.
Important: For modes 1 and 2, the author's voice and intent take priority. Do not rewrite their content unnecessarily. Focus on structure, conventions, and polish — not on replacing their words.
询问用户希望的工作方式,共有三种模式:
  1. "我已有草稿" — 作者已撰写(或即将撰写)内容。Agent负责搭建目录、前置元数据和图片设置,将作者内容调整为正确格式,并根据博客规范进行审核。
  2. "我有笔记/大纲" — 作者有初步想法、要点或大纲。Agent将其扩展为完整草稿,同时保留作者的语气和核心要点。在定稿前需将草稿提交给作者审核。
  3. "帮我撰写" — 作者提供主题和核心要点。Agent负责撰写完整文章。在定稿前需将草稿提交给作者审核。
重要提示: 对于模式1和模式2,需优先保留作者的语气和意图。无需不必要地重写内容,重点关注结构、规范和润色,而非替换作者的表述。

Step 2: Gather the Blog Post Details

步骤2:收集博客文章详情

Ask the user for the following (do not assume any of these):
  1. Topic: What is the blog post about?
  2. Author: Who is the author? (needs to match a key in
    authors.yml
    )
  3. Target audience: Who is this for? (developers, beginners, community, etc.)
For modes 2 and 3, also ask: 4. Key points: What are the main things the post should cover? 5. Tone: Technical deep-dive, casual walkthrough, announcement, etc.?
For mode 1, ask: 4. Where is the draft? A file path, or ask them to paste it in.
向用户询问以下信息(请勿自行假设):
  1. 主题:博客文章的主题是什么?
  2. 作者:作者是谁?(需与
    authors.yml
    中的键名匹配)
  3. 目标受众:文章面向谁?(开发者、初学者、社区成员等)
对于模式2和模式3,还需询问: 4. 核心要点:文章需要涵盖哪些主要内容? 5. 语气:技术深度解析、轻松入门指南、公告发布等?
对于模式1,需询问: 4. 草稿位置:文件路径,或请用户粘贴草稿内容。

Step 3: Verify Author Exists

步骤3:验证作者是否存在

Check
<goose-repo>/documentation/blog/authors.yml
for the author key.
If the author does not exist, create a new entry. The format is:
yaml
authorkey:
  name: Full Name
  title: Job Title
  image_url: https://avatars.githubusercontent.com/u/<github-id>?v=4
  page: true
  socials:
    github: github-username
    x: x-username
    linkedin: linkedin-username
Ask the user for any missing details (name, title, GitHub username, social handles). The
image_url
can be derived from their GitHub profile:
https://avatars.githubusercontent.com/u/<id>?v=4
. Look up their GitHub user ID if needed:
bash
gh api users/<username> --jq '.id'
检查
<goose-repo>/documentation/blog/authors.yml
文件中是否存在该作者的键名。
如果作者不存在,请创建新条目,格式如下:
yaml
authorkey:
  name: 全名
  title: 职位
  image_url: https://avatars.githubusercontent.com/u/<github-id>?v=4
  page: true
  socials:
    github: github用户名
    x: X平台用户名
    linkedin: LinkedIn用户名
向用户询问缺失的信息(姓名、职位、GitHub用户名、社交平台账号)。
image_url
可从其GitHub个人资料获取:
https://avatars.githubusercontent.com/u/<id>?v=4
。如有需要,可通过以下命令查询其GitHub用户ID:
bash
gh api users/<username> --jq '.id'

Step 4: Create the Blog Post Directory

步骤4:创建博客文章目录

Blog posts use the naming convention:
YYYY-MM-DD-slug-title/
  index.md
  banner.png
Rules:
  • Use today's date (run
    date +%Y-%m-%d
    to get it)
  • The slug should be lowercase, hyphen-separated, concise, and descriptive
  • The directory lives inside
    <goose-repo>/documentation/blog/
bash
mkdir -p documentation/blog/YYYY-MM-DD-slug-title
博客文章目录命名规则如下:
YYYY-MM-DD-slug-title/
  index.md
  banner.png
规则说明:
  • 使用当前日期(执行
    date +%Y-%m-%d
    命令获取)
  • Slug需为小写、连字符分隔、简洁且具有描述性
  • 目录需位于
    <goose-repo>/documentation/blog/
bash
mkdir -p documentation/blog/YYYY-MM-DD-slug-title

Step 5: Assemble the Blog Post

步骤5:组装博客文章

Create
index.md
inside the new directory. The file structure is:
在新目录中创建
index.md
文件,文件结构如下:

1. Frontmatter

1. 前置元数据(Frontmatter)

markdown
---
title: "Your Blog Post Title"
description: "A concise summary of the post (1-2 sentences). Used in social previews and SEO."
authors:
  - authorkey
---
Frontmatter rules:
  • title
    — wrap in quotes, use title case
  • description
    — wrap in quotes, keep to 1-2 sentences, make it compelling for social sharing
  • authors
    — a YAML list of author keys from
    authors.yml
    (supports multiple authors)
  • Do not include a
    date
    field — Docusaurus extracts the date from the directory name
  • Do not include
    tags
    in frontmatter — the blog does not use Docusaurus tags
markdown
---
title: "你的博客文章标题"
description: "文章的简洁摘要(1-2句话),用于社交预览和SEO。"
authors:
  - authorkey
---
前置元数据规则:
  • title
    — 需用引号包裹,采用标题大小写格式
  • description
    — 需用引号包裹,控制在1-2句话,内容需吸引用户进行社交分享
  • authors
    — 从
    authors.yml
    中获取的作者键名组成的YAML列表(支持多位作者)
  • 请勿包含
    date
    字段 — Docusaurus会从目录名称中提取日期
  • 请勿在前置元数据中包含
    tags
    — 本博客不使用Docusaurus的标签功能

2. Banner Image

2. 横幅图片

Every post must include a banner image immediately after the frontmatter:
markdown
![blog banner](banner.png)
Banner image requirements:
  • Dimensions: 1200×600 pixels
  • Location: Same directory as
    index.md
  • Filename:
    banner.png
    (or
    .jpg
    ,
    .webp
    )
  • This same image is also used for social sharing (Open Graph / Twitter cards) — there is no separate social image
If the user does not have an image ready, add the image reference as a placeholder and remind them to add the file before publishing. You can also offer to generate one if image generation tools are available.
每篇文章必须在前置元数据后立即添加横幅图片:
markdown
![博客横幅](banner.png)
横幅图片要求:
  • 尺寸:1200×600像素
  • 位置:与
    index.md
    位于同一目录
  • 文件名
    banner.png
    (或
    .jpg
    .webp
    格式)
  • 该图片同时用于社交分享(Open Graph / Twitter卡片)—— 无需单独设置社交图片
如果用户尚未准备好图片,请先添加图片引用作为占位符,并提醒他们在发布前添加图片文件。若有图片生成工具,也可主动提出为其生成图片。

3. Introduction + Truncate Marker

3. 引言 + 截断标记

The intro paragraph(s) appear before the truncate marker. This controls the preview on the blog index page:
markdown
![blog banner](banner.png)

Your compelling introduction paragraph that hooks the reader.

<!--truncate-->
The intro should:
  • Hook the reader — why should they care?
  • Be 1-3 paragraphs max
  • Give enough context to decide whether to click through
引言段落需位于截断标记之前,这将控制博客首页的预览内容:
markdown
![博客横幅](banner.png)

吸引读者的引言段落。

<!--truncate-->
引言要求:
  • 吸引读者 — 为什么他们应该关注这篇文章?
  • 最多1-3个段落
  • 提供足够的上下文,让读者决定是否点击阅读全文

4. Content Body

4. 正文内容

For mode 1 (author's draft): Place the author's content here. Adjust only what's needed to match the formatting conventions below. Flag any issues for the author rather than silently rewriting.
For modes 2 and 3: Write the content following the guidelines below, then present the full draft to the author for review.
Formatting Conventions:
  • Use
    ##
    for major sections and
    ###
    for subsections
  • Do not use
    #
    (h1) in the body — the title from frontmatter is the h1
  • Include code blocks with language identifiers (
    ```python
    ,
    ```bash
    , etc.)
  • Use bullet points and numbered lists to break up dense information
  • Short paragraphs (2-4 sentences) for readability
  • End with a clear takeaway, call-to-action, or next steps
Voice & Style:
  • Write in first person when sharing personal experience, third person for announcements
  • Be conversational but technically accurate
  • The goose blog audience is developers — respect their intelligence
  • Avoid marketing fluff; be genuine and specific
  • Use concrete examples and code snippets over abstract explanations
goose-Specific Conventions:
  • Refer to the project as "goose" (lowercase) when referencing the tool
  • When linking to goose docs:
    https://block.github.io/goose/
  • When linking to the repo:
    https://github.com/block/goose
  • When linking to extensions:
    https://block.github.io/goose/extensions
对于模式1(作者提供草稿): 将作者内容放置于此。仅根据以下格式规范进行必要调整。若发现问题,需向作者指出,而非擅自重写。
对于模式2和模式3: 按照以下指南撰写内容,然后将完整草稿提交给作者审核。
格式规范:
  • 使用
    ##
    标记主要章节,
    ###
    标记子章节
  • 正文中请勿使用
    #
    (一级标题)—— 前置元数据中的
    title
    即为一级标题
  • 代码块需添加语言标识符(如
    ```python
    ```bash
    等)
  • 使用项目符号和编号列表拆分密集信息
  • 段落简短(2-4句话)以提升可读性
  • 结尾需包含明确的要点总结、行动号召或后续步骤
语气与风格:
  • 分享个人经验时使用第一人称,发布公告时使用第三人称
  • 语气需口语化但技术准确
  • goose博客的受众为开发者 — 尊重他们的专业能力
  • 避免营销套话;内容需真实具体
  • 优先使用具体示例和代码片段,而非抽象解释
Goose 专属规范:
  • 提及该工具时使用“goose”(小写)
  • 链接至goose文档时使用:
    https://block.github.io/goose/
  • 链接至仓库时使用:
    https://github.com/block/goose
  • 链接至扩展时使用:
    https://block.github.io/goose/extensions

5. Social Metadata (
<head>
Section) — Required

5. 社交元数据(
<head>
部分)—— 必填项

Every blog post must end with a
<head>
section containing Open Graph and Twitter card meta tags. This is placed at the very end of the
index.md
file, after all content:
html
<head>
  <meta property="og:title" content="YOUR TITLE HERE" />
  <meta property="og:type" content="article" />
  <meta property="og:url" content="https://block.github.io/goose/blog/YYYY/MM/DD/slug-title" />
  <meta property="og:description" content="YOUR DESCRIPTION HERE" />
  <meta property="og:image" content="https://block.github.io/goose/assets/images/BANNER_FILENAME_WITH_HASH.png" />
  <meta name="twitter:card" content="summary_large_image" />
  <meta property="twitter:domain" content="block.github.io" />
  <meta name="twitter:title" content="YOUR TITLE HERE" />
  <meta name="twitter:description" content="YOUR DESCRIPTION HERE" />
  <meta name="twitter:image" content="https://block.github.io/goose/assets/images/BANNER_FILENAME_WITH_HASH.png" />
</head>
Important: The
og:image
and
twitter:image
URLs require a Docusaurus-generated filename that includes a content hash. You cannot guess this filename — it must be obtained from the local preview. See Step 6 for how to get it.
Field reference:
  • og:title
    /
    twitter:title
    — same as the frontmatter
    title
  • og:description
    /
    twitter:description
    — same as the frontmatter
    description
  • og:url
    — the production URL:
    https://block.github.io/goose/blog/YYYY/MM/DD/slug-title
  • og:image
    /
    twitter:image
    — the static image URL obtained from local preview (see Step 6)
  • twitter:card
    — always
    summary_large_image
  • twitter:domain
    — always
    block.github.io
When first creating the post, use
https://block.github.io/goose/assets/images/BANNER_FILENAME_WITH_HASH.png
as the placeholder for
og:image
and
twitter:image
. The
BANNER_FILENAME_WITH_HASH
portion will be replaced with the real filename after Step 6.
每篇文章必须在文件末尾添加包含Open Graph和Twitter卡片元数据的
<head>
部分:
html
<head>
  <meta property="og:title" content="你的标题" />
  <meta property="og:type" content="article" />
  <meta property="og:url" content="https://block.github.io/goose/blog/YYYY/MM/DD/slug-title" />
  <meta property="og:description" content="你的摘要" />
  <meta property="og:image" content="https://block.github.io/goose/assets/images/BANNER_FILENAME_WITH_HASH.png" />
  <meta name="twitter:card" content="summary_large_image" />
  <meta property="twitter:domain" content="block.github.io" />
  <meta name="twitter:title" content="你的标题" />
  <meta name="twitter:description" content="你的摘要" />
  <meta name="twitter:image" content="https://block.github.io/goose/assets/images/BANNER_FILENAME_WITH_HASH.png" />
</head>
重要提示:
og:image
twitter:image
的URL需要Docusaurus生成的包含内容哈希的文件名。你无法猜测该文件名 — 必须通过本地预览获取。请查看步骤6了解获取方法。
字段说明:
  • og:title
    /
    twitter:title
    — 与前置元数据中的
    title
    一致
  • og:description
    /
    twitter:description
    — 与前置元数据中的
    description
    一致
  • og:url
    — 生产环境URL:
    https://block.github.io/goose/blog/YYYY/MM/DD/slug-title
  • og:image
    /
    twitter:image
    — 从本地预览获取的静态图片URL(见步骤6)
  • twitter:card
    — 固定为
    summary_large_image
  • twitter:domain
    — 固定为
    block.github.io
首次创建文章时,使用
https://block.github.io/goose/assets/images/BANNER_FILENAME_WITH_HASH.png
作为
og:image
twitter:image
的占位符。
BANNER_FILENAME_WITH_HASH
部分将在步骤6后替换为真实文件名。

Step 6: Preview Locally and Get the Image URL

步骤6:本地预览并获取图片URL

The author needs to preview the blog post locally to:
  1. Verify the post looks correct
  2. Get the static image URL needed for the
    <head>
    social metadata
Tell the user to run this in a separate terminal (do not run this command directly — it blocks the terminal):
bash
cd <goose-repo>/documentation
npm start
This starts a local dev server at
http://localhost:3000
with hot reloading.
Once the preview is running, instruct the user to:
  1. Navigate to their blog post in the browser
  2. Right-click the banner image → Copy Image Address
  3. The copied URL will be something like:
    http://localhost:3000/goose/assets/images/banner-a1b2c3d4e5f6.png
  4. Extract the filename (e.g.,
    banner-a1b2c3d4e5f6.png
    )
  5. Construct the production URL:
    https://block.github.io/goose/assets/images/banner-a1b2c3d4e5f6.png
Update the
<head>
section's
og:image
and
twitter:image
with this production URL.
作者需要在本地预览博客文章,以:
  1. 验证文章显示是否正确
  2. 获取社交元数据所需的静态图片URL
告知用户在单独的终端中运行以下命令(请勿直接运行该命令 — 它会占用终端):
bash
cd <goose-repo>/documentation
npm start
这将启动一个本地开发服务器,地址为
http://localhost:3000
,支持热重载。
预览启动后,指导用户执行以下操作:
  1. 在浏览器中导航至其博客文章
  2. 右键点击横幅图片 → 复制图片地址
  3. 复制的URL类似:
    http://localhost:3000/goose/assets/images/banner-a1b2c3d4e5f6.png
  4. 提取文件名(例如:
    banner-a1b2c3d4e5f6.png
  5. 构建生产环境URL:
    https://block.github.io/goose/assets/images/banner-a1b2c3d4e5f6.png
使用该生产环境URL更新
<head>
部分的
og:image
twitter:image
字段。

Step 7: Present the Draft for Review

步骤7:提交草稿审核

This step is critical. Before considering the post done:
  • Show the author the complete
    index.md
    content
  • Highlight any decisions you made (title wording, section structure, intro framing)
  • Ask if they want to adjust anything
  • For mode 1: call out any formatting changes you made and why
Iterate based on feedback until the author is satisfied.
此步骤至关重要。 在完成文章前:
  • 向作者展示完整的
    index.md
    内容
  • 突出说明你所做的任何决策(如标题措辞、章节结构、引言框架)
  • 询问他们是否需要调整任何内容
  • 对于模式1:说明你所做的格式调整及原因
根据反馈进行迭代,直到作者满意为止。

Step 8: Final Review Checklist

步骤8:最终审核清单

Run through this checklist and fix any issues:
  • Directory follows
    YYYY-MM-DD-slug-title/
    naming convention
  • index.md
    exists in the directory
  • Frontmatter includes
    title
    ,
    description
    , and
    authors
  • Author key exists in
    authors.yml
  • Banner image (1200×600) is referenced after frontmatter
  • Banner image file exists in the directory (or flagged as needed)
  • <!--truncate-->
    marker is placed after the intro
  • No
    #
    (h1) headers in the body — only
    ##
    and below
  • Code blocks have language identifiers
  • Links to goose resources use the correct URLs
  • <head>
    section is present at the end of the file
  • og:image
    and
    twitter:image
    URLs are filled in from local preview
  • Spelling and grammar are clean
  • Post reads well from start to finish
逐一检查以下项目,修复任何问题:
  • 目录符合
    YYYY-MM-DD-slug-title/
    命名规范
  • 目录中存在
    index.md
    文件
  • 前置元数据包含
    title
    description
    authors
    字段
  • 作者键名存在于
    authors.yml
  • 前置元数据后已引用横幅图片(1200×600像素)
  • 横幅图片文件存在于目录中(或已标记为需要添加)
  • <!--truncate-->
    标记已放置在引言之后
  • 正文中未使用
    #
    (一级标题)—— 仅使用
    ##
    及以下层级
  • 代码块已添加语言标识符
  • 指向goose资源的链接使用正确URL
  • 文件末尾已添加
    <head>
    部分
  • og:image
    twitter:image
    URL已从本地预览中获取并填写
  • 拼写和语法无误
  • 文章通读流畅

Content Types That Work Well

适合的内容类型

When helping the author brainstorm or choose a direction, these formats tend to perform well on the goose blog:
  • Tutorials and how-tos — "How I built X with goose"
  • Deep dives — architecture, features, or design decisions
  • Community spotlights — contributor stories and use cases
  • Comparisons — goose vs. other tools, honest assessments
  • Release announcements — what's new and why it matters
  • Tips and workflows — power-user guides and productivity hacks
  • Thought leadership — opinions on AI agents, developer tools, open source
当帮助作者构思或选择写作方向时,以下格式在goose博客上表现良好:
  • 教程与操作指南 — "我如何使用goose构建X"
  • 深度解析 — 架构、功能或设计决策
  • 社区聚焦 — 贡献者故事和使用案例
  • 对比分析 — goose与其他工具的对比、客观评估
  • 版本发布公告 — 新功能及重要性
  • 技巧与工作流程 — 高级用户指南和效率技巧
  • 思想领导力 — 关于AI Agent、开发者工具、开源的观点

Example

示例

A complete blog post:
markdown
---
title: "Building a Custom MCP Server for Your Team"
description: "A step-by-step guide to creating a Model Context Protocol server that connects goose to your team's internal tools."
authors:
  - ebony
---

![blog banner](banner.png)

If your team has internal tools that aren't covered by existing extensions, building a custom MCP server is easier than you think. In this post, I'll walk through how I built one for our team's deployment pipeline.

<!--truncate-->
完整的博客文章示例:
markdown
---
title: "为团队构建自定义MCP服务器"
description: "一步一步指导你创建Model Context Protocol服务器,将goose连接至团队内部工具。"
authors:
  - ebony
---

![博客横幅](banner.png)

如果你的团队有现有扩展未覆盖的内部工具,构建自定义MCP服务器比你想象的更简单。在本文中,我将逐步介绍如何为我们团队的部署管道构建一个MCP服务器。

<!--truncate-->

Why Build a Custom MCP Server?

为什么要构建自定义MCP服务器?

goose connects to tools through the Model Context Protocol (MCP). While there are hundreds of community extensions available, sometimes your team has unique internal tools that need a custom integration.
goose通过Model Context Protocol (MCP)连接至工具。虽然已有数百个社区扩展,但有时你的团队有独特的内部工具,需要自定义集成。

Getting Started

开始搭建

First, scaffold a new MCP server project:
bash
npx create-mcp-server my-server
cd my-server
首先,初始化一个新的MCP服务器项目:
bash
npx create-mcp-server my-server
cd my-server

Defining Your Tools

定义你的工具

The core of any MCP server is its tool definitions...
任何MCP服务器的核心都是其工具定义...

Wrapping Up

总结

Building an MCP server took about an hour and saved our team countless context switches. If you want to learn more, check out the MCP documentation and the goose extensions directory.
<head> <meta property="og:title" content="Building a Custom MCP Server for Your Team" /> <meta property="og:type" content="article" /> <meta property="og:url" content="https://block.github.io/goose/blog/2025/07/01/custom-mcp-server" /> <meta property="og:description" content="A step-by-step guide to creating a Model Context Protocol server that connects goose to your team's internal tools." /> <meta property="og:image" content="https://block.github.io/goose/assets/images/banner-a1b2c3d4e5f6.png" /> <meta name="twitter:card" content="summary_large_image" /> <meta property="twitter:domain" content="block.github.io" /> <meta name="twitter:title" content="Building a Custom MCP Server for Your Team" /> <meta name="twitter:description" content="A step-by-step guide to creating a Model Context Protocol server that connects goose to your team's internal tools." /> <meta name="twitter:image" content="https://block.github.io/goose/assets/images/banner-a1b2c3d4e5f6.png" /> </head> ````
构建MCP服务器大约花费了我一个小时,为我们团队节省了无数的上下文切换时间。如果你想了解更多,请查看MCP文档goose扩展目录
<head> <meta property="og:title" content="为团队构建自定义MCP服务器" /> <meta property="og:type" content="article" /> <meta property="og:url" content="https://block.github.io/goose/blog/2025/07/01/custom-mcp-server" /> <meta property="og:description" content="一步一步指导你创建Model Context Protocol服务器,将goose连接至团队内部工具。" /> <meta property="og:image" content="https://block.github.io/goose/assets/images/banner-a1b2c3d4e5f6.png" /> <meta name="twitter:card" content="summary_large_image" /> <meta property="twitter:domain" content="block.github.io" /> <meta name="twitter:title" content="为团队构建自定义MCP服务器" /> <meta name="twitter:description" content="一步一步指导你创建Model Context Protocol服务器,将goose连接至团队内部工具。" /> <meta name="twitter:image" content="https://block.github.io/goose/assets/images/banner-a1b2c3d4e5f6.png" /> </head> ````