<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: shibayu36</title>
    <description>The latest articles on DEV Community by shibayu36 (@shibayu36).</description>
    <link>https://dev.to/shibayu36</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F859036%2F0662f0bf-4ba8-497f-9934-b1805059e0e6.jpeg</url>
      <title>DEV Community: shibayu36</title>
      <link>https://dev.to/shibayu36</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/shibayu36"/>
    <language>en</language>
    <item>
      <title>I Added Minimum GitHub Security Settings to My OSS Repositories and Created a Setup Guide</title>
      <dc:creator>shibayu36</dc:creator>
      <pubDate>Tue, 07 Apr 2026 13:00:00 +0000</pubDate>
      <link>https://dev.to/shibayu36/i-added-minimum-github-security-settings-to-my-oss-repositories-and-created-a-setup-guide-15ad</link>
      <guid>https://dev.to/shibayu36/i-added-minimum-github-security-settings-to-my-oss-repositories-and-created-a-setup-guide-15ad</guid>
      <description>&lt;p&gt;&lt;em&gt;(This is an English translation of my original Japanese article: &lt;a href="https://blog.shibayu36.org/entry/2026/02/16/173000" rel="noopener noreferrer"&gt;日本語版はこちら&lt;/a&gt;)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Recently, attacks on well-known OSS projects hosted on GitHub have become more frequent (e.g., the &lt;a href="https://blog.jxck.io/entries/2025-09-03/nx-incidents.html" rel="noopener noreferrer"&gt;Nx incident in August 2025&lt;/a&gt; (Japanese)). I decided to learn from these cases and apply minimum security settings to my own repositories.&lt;/p&gt;

&lt;p&gt;The following three articles were particularly helpful when considering the settings:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.github.com/en/code-security/getting-started/quickstart-for-securing-your-repository" rel="noopener noreferrer"&gt;Quickstart for securing your repository - GitHub Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.jxck.io/entries/2025-09-03/nx-incidents.html" rel="noopener noreferrer"&gt;Lessons from the Nx Attack (Japanese)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://zenn.dev/shunsuke_suzuki/articles/github-immutable-release" rel="noopener noreferrer"&gt;Enable GitHub's Immutable Releases to Prevent Security Incidents (Japanese)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Based on these references, I collaborated with AI to create a minimum setup document, which I'm sharing here. If you have suggestions for additional settings I should include, I'd love to hear them.&lt;/p&gt;

&lt;h3&gt;
  
  
  GitHub OSS Minimum Security Setup
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Checklist
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Enable Dependabot Alerts&lt;/li&gt;
&lt;li&gt;[ ] Enable Private vulnerability reporting / Security Advisories&lt;/li&gt;
&lt;li&gt;[ ] Enable CodeQL&lt;/li&gt;
&lt;li&gt;[ ] Enable Secret scanning &amp;amp; Push protection&lt;/li&gt;
&lt;li&gt;[ ] Protect the main/master branch (require PRs + CI)&lt;/li&gt;
&lt;li&gt;[ ] Protect version tags&lt;/li&gt;
&lt;li&gt;[ ] Add SECURITY.md&lt;/li&gt;
&lt;li&gt;[ ] Enable release immutability&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Enable Dependabot Alerts (Vulnerability Notifications)
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;What to do:&lt;/strong&gt; Get alerts in the Security tab when vulnerabilities are found in your dependencies. &lt;a href="https://docs.github.com/en/code-security/dependabot/dependabot-alerts/configuring-dependabot-alerts" rel="noopener noreferrer"&gt;Reference&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Steps:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Repository &amp;gt; Settings &amp;gt; Advanced Security&lt;/li&gt;
&lt;li&gt;Enable Dependabot alerts&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Enable Private Vulnerability Reporting / Security Advisories
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;What to do:&lt;/strong&gt; Allow external reporters to submit vulnerability reports privately, and display a "Report a vulnerability" option. &lt;a href="https://docs.github.com/en/code-security/how-tos/report-and-fix-vulnerabilities/configure-vulnerability-reporting/configuring-private-vulnerability-reporting-for-a-repository" rel="noopener noreferrer"&gt;Reference&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Steps:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Repository &amp;gt; Settings &amp;gt; Advanced Security&lt;/li&gt;
&lt;li&gt;Enable Private vulnerability reporting&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Enable CodeQL (Code Scanning)
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;What to do:&lt;/strong&gt; Catch potential vulnerabilities with static analysis. The quickest way is to use the Default setup. &lt;a href="https://docs.github.com/en/code-security/how-tos/scan-code-for-vulnerabilities/configure-code-scanning/configuring-default-setup-for-code-scanning" rel="noopener noreferrer"&gt;Reference&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Steps:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Repository &amp;gt; Settings &amp;gt; Advanced Security&lt;/li&gt;
&lt;li&gt;Under CodeQL analysis, click Set up &amp;gt; Default&lt;/li&gt;
&lt;li&gt;Enable with the suggested triggers (push / PR / schedule)&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Enable Secret Scanning &amp;amp; Push Protection
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;What to do:&lt;/strong&gt; Detect and alert when tokens, API keys, or other secrets are committed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Steps:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Repository &amp;gt; Settings &amp;gt; Advanced Security&lt;/li&gt;
&lt;li&gt;Enable Secret scanning (or Secret Protection)&lt;/li&gt;
&lt;li&gt;Enable Push protection&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Protect main/master Branch (Require PRs + CI)
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;What to do:&lt;/strong&gt; Block direct pushes and require CI to pass before merging. GitHub offers either the traditional "Branch protection" or the more flexible "Rulesets." Rulesets can target both branches and tags. &lt;a href="https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/about-rulesets" rel="noopener noreferrer"&gt;Reference&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Steps:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Repository &amp;gt; Settings &amp;gt; Rules &amp;gt; Rulesets&lt;/li&gt;
&lt;li&gt;New branch ruleset&lt;/li&gt;
&lt;li&gt;Target &lt;code&gt;main&lt;/code&gt; (or &lt;code&gt;master&lt;/code&gt;) (e.g., Default branch / pattern matching)&lt;/li&gt;
&lt;li&gt;Enable rules:

&lt;ul&gt;
&lt;li&gt;Enforcement status: Active&lt;/li&gt;
&lt;li&gt;Add Repository admin to bypass list

&lt;ul&gt;
&lt;li&gt;This is because I do releases on the main branch — ideally, I'd remove this bypass too&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Target branches: Include default branch&lt;/li&gt;
&lt;li&gt;Restrict deletions&lt;/li&gt;
&lt;li&gt;Require a pull request before merging&lt;/li&gt;
&lt;li&gt;Require status checks to pass

&lt;ul&gt;
&lt;li&gt;Use "Add checks" to select your CI jobs (e.g., &lt;code&gt;ci&lt;/code&gt; / &lt;code&gt;test&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Note: The checks you want to require must have run at least once so GitHub recognizes the check name. &lt;a href="https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/collaborating-on-repositories-with-code-quality-features/about-status-checks" rel="noopener noreferrer"&gt;Reference&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Block force pushes&lt;/li&gt;
&lt;li&gt;Require code scanning results&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Protect Version Tags
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;What to do:&lt;/strong&gt; Restrict who can create version tags.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Steps:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Repository &amp;gt; Settings &amp;gt; Rules &amp;gt; Rulesets&lt;/li&gt;
&lt;li&gt;New tag ruleset&lt;/li&gt;
&lt;li&gt;Enable rules:

&lt;ul&gt;
&lt;li&gt;Enforcement status: Active&lt;/li&gt;
&lt;li&gt;Add Repository admin to bypass list&lt;/li&gt;
&lt;li&gt;Target tags: &lt;code&gt;v*&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Restrict creations&lt;/li&gt;
&lt;li&gt;Restrict updates&lt;/li&gt;
&lt;li&gt;Restrict deletions&lt;/li&gt;
&lt;li&gt;Require signed commits&lt;/li&gt;
&lt;li&gt;Block force pushes&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Add SECURITY.md
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;What to do:&lt;/strong&gt; Document how to report vulnerabilities so reporters don't use public Issues. You can create and commit the template directly from GitHub's UI. &lt;a href="https://docs.github.com/en/code-security/how-tos/report-and-fix-vulnerabilities/configure-vulnerability-reporting/adding-a-security-policy-to-your-repository" rel="noopener noreferrer"&gt;Reference&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Steps:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Repository &amp;gt; Security &amp;gt; Set up a security policy&lt;/li&gt;
&lt;li&gt;Edit and commit &lt;code&gt;SECURITY.md&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Minimal template (copy &amp;amp; paste):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Security Policy&lt;/span&gt;

&lt;span class="gu"&gt;## Supported Versions&lt;/span&gt;

Only the latest version is supported with security updates.
Please always use the latest release.

&lt;span class="gu"&gt;## Reporting a Vulnerability&lt;/span&gt;

&lt;span class="gs"&gt;**Please do not report security vulnerabilities through public GitHub issues.**&lt;/span&gt;

Instead, report a vulnerability through GitHub's security advisory feature at https://github.com/&lt;span class="nt"&gt;&amp;lt;owner&amp;gt;&lt;/span&gt;/&lt;span class="nt"&gt;&amp;lt;repository_name&amp;gt;&lt;/span&gt;/security/advisories/new.

You can expect an initial response within a few days. If for some reason you do not, please follow up with a comment on the advisory to ensure we received your original report.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Enable Release Immutability
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;What to do:&lt;/strong&gt; Prevent GitHub Tags, Releases, and Release assets from being modified after creation. &lt;a href="https://zenn.dev/shunsuke_suzuki/articles/github-immutable-release" rel="noopener noreferrer"&gt;Reference&lt;/a&gt; (Japanese)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Steps:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Repository &amp;gt; Settings &amp;gt; General, then enable "Enable release immutability"&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>security</category>
      <category>github</category>
      <category>programming</category>
    </item>
    <item>
      <title>Added File Search and Canvas Retrieval to slack-explorer-mcp</title>
      <dc:creator>shibayu36</dc:creator>
      <pubDate>Tue, 10 Feb 2026 17:00:00 +0000</pubDate>
      <link>https://dev.to/shibayu36/added-file-search-and-canvas-retrieval-to-slack-explorer-mcp-4hd9</link>
      <guid>https://dev.to/shibayu36/added-file-search-and-canvas-retrieval-to-slack-explorer-mcp-4hd9</guid>
      <description>&lt;p&gt;&lt;em&gt;(This is an English translation of my original Japanese article: &lt;a href="https://blog.shibayu36.org/entry/2026/01/26/170000" rel="noopener noreferrer"&gt;日本語版はこちら&lt;/a&gt;)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/shibayu36/slack-explorer-mcp" rel="noopener noreferrer"&gt;slack-explorer-mcp&lt;/a&gt; is an MCP server that lets AI agents search and retrieve Slack messages and threads. It's useful for investigating historical context like "why was this designed this way?" from Slack. For details, see &lt;a href="https://dev.to/shibayu36/making-historical-context-easily-discoverable-from-slack-with-ai-building-slack-explorer-mcp-54jj"&gt;Making Historical Context Easily Discoverable from Slack with AI - Building slack-explorer-mcp&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I added &lt;code&gt;search_files&lt;/code&gt; and &lt;code&gt;get_canvas_content&lt;/code&gt; tools so that AI agents can also read files and canvases shared on Slack.&lt;/p&gt;

&lt;h3&gt;
  
  
  search_files Tool
&lt;/h3&gt;

&lt;p&gt;This tool searches for files within Slack, including canvases, PDFs, images, and more. You can filter results by file type, channel, user, and date range.&lt;/p&gt;

&lt;p&gt;With slack-explorer-mcp installed, you can search Slack files like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Search for PDFs shared in the dev-team channel"&lt;/li&gt;
&lt;li&gt;"Search for canvases containing the word 'design document'"&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  get_canvas_content Tool
&lt;/h3&gt;

&lt;p&gt;This tool retrieves HTML content by specifying a canvas ID. It can fetch up to 20 canvases at once.&lt;/p&gt;

&lt;p&gt;I wanted AI to be able to read Slack canvas content, but file search alone doesn't return the actual content — you need to download it separately. Since the best approach for feeding content to AI varies by file format, I started with canvas support only.&lt;/p&gt;

&lt;p&gt;When you retrieve canvas content, it returns HTML. The original canvas HTML contained a lot of unnecessary ID attributes and style information, which was wasteful in terms of token usage. So I made it automatically strip unnecessary attributes before returning the content. This reduces token consumption when passing the content to AI.&lt;/p&gt;

&lt;p&gt;For example, you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Search for canvases and then have the AI summarize their content&lt;/li&gt;
&lt;li&gt;Have the AI answer questions based on the content of a specific canvas&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;If you have slack-explorer-mcp set up with your AI agent tools, you can now search Slack files and retrieve canvas content. Try it out when you want to use AI to search files in Slack or have it read canvas content.&lt;/p&gt;

&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/shibayu36/slack-explorer-mcp" rel="noopener noreferrer"&gt;shibayu36/slack-explorer-mcp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/shibayu36/slack-explorer-mcp/pull/27" rel="noopener noreferrer"&gt;Add search_files MCP tool #27&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/shibayu36/slack-explorer-mcp/pull/28" rel="noopener noreferrer"&gt;Add get_canvas_content MCP tool #28&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/shibayu36/slack-explorer-mcp/pull/36" rel="noopener noreferrer"&gt;Add Canvas HTML stripping for token efficiency #36&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>showdev</category>
      <category>mcp</category>
    </item>
    <item>
      <title>I Created Claude Skills for Convenient Pull Request Review Operations from Claude Code</title>
      <dc:creator>shibayu36</dc:creator>
      <pubDate>Sun, 04 Jan 2026 17:00:00 +0000</pubDate>
      <link>https://dev.to/shibayu36/i-created-claude-skills-for-convenient-pull-request-review-operations-from-claude-code-d7p</link>
      <guid>https://dev.to/shibayu36/i-created-claude-skills-for-convenient-pull-request-review-operations-from-claude-code-d7p</guid>
      <description>&lt;p&gt;&lt;em&gt;(This is an English translation of my original Japanese article: &lt;a href="https://blog.shibayu36.org/entry/2025/12/17/173000" rel="noopener noreferrer"&gt;日本語版はこちら&lt;/a&gt;)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When using Claude Code or Claude Code Action to have AI autonomously review Pull Requests, I encountered several issues. To solve them, I created a Claude Skill specialized for PR review operations called github-pr-review-operation. Let me introduce it here.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Problems
&lt;/h3&gt;

&lt;p&gt;I faced these three issues:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When adding inline comments, the AI would comment on the wrong line

&lt;ul&gt;
&lt;li&gt;Claude Code Action comes with an MCP for adding inline comments, but it often placed comments about a specific line on a different line&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Even when instructed to "consider past comments on this PR," it couldn't properly retrieve the comment list

&lt;ul&gt;
&lt;li&gt;It would fetch regular comments but proceed without getting inline comments&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;It couldn't properly reply to comments on the PR

&lt;ul&gt;
&lt;li&gt;It would reply to a specific comment by creating a separate inline comment instead&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;All these issues could be solved by properly using &lt;code&gt;gh&lt;/code&gt; commands, but due to the probabilistic nature of LLMs, sometimes it worked and sometimes it didn't.&lt;/p&gt;

&lt;h3&gt;
  
  
  Teaching Claude Code the Operations with Claude Skills
&lt;/h3&gt;

&lt;p&gt;As mentioned, the solution was to teach Claude Code how to use &lt;code&gt;gh&lt;/code&gt; commands. Claude Skills seemed perfect for this purpose, so I created a custom Claude Skill specialized for PR review operations.&lt;/p&gt;

&lt;p&gt;When creating Skills, it's good to use the Skill Generator that's built into Claude by default. I used the following prompt in Claude Desktop to create the base, then made various adjustments while testing it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;I want to create a skill for GitHub Pull Request reviews with the necessary operations. The required operations are:

- Get PR title and description
- Get PR file changes
- Get all comments on the PR
- Comment on the PR
- Add inline comment with line specification
- Reply to a specific comment on the PR
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The final result was a very simple structure with just SKILL.md. Using this alone solved the above issues almost 100% of the time. Very convenient!&lt;/p&gt;

&lt;p&gt;SKILL.md:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;github-pr-review-operation&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Skill&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;for&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;GitHub&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Pull&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Request&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;review&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;operations.&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Executes&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;PR&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;info&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;retrieval,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;diff&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;viewing,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;comment&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;fetching/posting,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;inline&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;comments,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;and&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;comment&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;replies&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;using&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;gh&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;commands.&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Use&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;for&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;PR&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;reviews,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;code&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;reviews,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;and&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;PR&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;operations."&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

&lt;span class="gh"&gt;# GitHub PR Review Operation&lt;/span&gt;

PR review operations using GitHub CLI (&lt;span class="sb"&gt;`gh`&lt;/span&gt;).

&lt;span class="gu"&gt;## Prerequisites&lt;/span&gt;
&lt;span class="p"&gt;
-&lt;/span&gt; &lt;span class="sb"&gt;`gh`&lt;/span&gt; installed
&lt;span class="p"&gt;-&lt;/span&gt; Authenticated with &lt;span class="sb"&gt;`gh auth login`&lt;/span&gt;

&lt;span class="gu"&gt;## Parsing PR URL&lt;/span&gt;

Extract the following from PR URL &lt;span class="sb"&gt;`https://github.com/OWNER/REPO/pull/NUMBER`&lt;/span&gt;:
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="sb"&gt;`OWNER`&lt;/span&gt;: Repository owner
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="sb"&gt;`REPO`&lt;/span&gt;: Repository name
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="sb"&gt;`NUMBER`&lt;/span&gt;: PR number

&lt;span class="gu"&gt;## Operations&lt;/span&gt;

&lt;span class="gu"&gt;### 1. Get PR Information&lt;/span&gt;

&lt;span class="p"&gt;```&lt;/span&gt;&lt;span class="nl"&gt;bash
&lt;/span&gt;gh &lt;span class="nb"&gt;pr &lt;/span&gt;view NUMBER &lt;span class="nt"&gt;--repo&lt;/span&gt; OWNER/REPO &lt;span class="nt"&gt;--json&lt;/span&gt; title,body,author,state,baseRefName,headRefName,url
&lt;span class="p"&gt;```&lt;/span&gt;

&lt;span class="gu"&gt;### 2. Get Diff (with line numbers)&lt;/span&gt;

&lt;span class="p"&gt;```&lt;/span&gt;&lt;span class="nl"&gt;bash
&lt;/span&gt;gh &lt;span class="nb"&gt;pr &lt;/span&gt;diff NUMBER &lt;span class="nt"&gt;--repo&lt;/span&gt; OWNER/REPO | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'
/^@@/ {
  match($0, /-([0-9]+)/, old)
  match($0, /\+([0-9]+)/, new)
  old_line = old[1]
  new_line = new[1]
  print $0
  next
}
/^-/ { printf "L%-4d     | %s\n", old_line++, $0; next }
/^\+/ { printf "     R%-4d| %s\n", new_line++, $0; next }
/^ / { printf "L%-4d R%-4d| %s\n", old_line++, new_line++, $0; next }
{ print }
'&lt;/span&gt;
&lt;span class="p"&gt;```&lt;/span&gt;

Output example:
&lt;span class="p"&gt;```&lt;/span&gt;&lt;span class="nl"&gt;
&lt;/span&gt;@@ -46,15 +46,25 @@ jobs:
L46   R46  |            prompt: |
L49       | -            (deleted line)
     R49  | +            (added line)
L50   R50  |              # Review guidelines
&lt;span class="p"&gt;```&lt;/span&gt;
&lt;span class="p"&gt;
-&lt;/span&gt; &lt;span class="sb"&gt;`L number`&lt;/span&gt;: LEFT (base) side line number → Use with &lt;span class="sb"&gt;`side=LEFT`&lt;/span&gt; for inline comments
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="sb"&gt;`R number`&lt;/span&gt;: RIGHT (head) side line number → Use with &lt;span class="sb"&gt;`side=RIGHT`&lt;/span&gt; for inline comments

&lt;span class="gu"&gt;### 3. Get Comments&lt;/span&gt;

Issue Comments (comments on the entire PR):
&lt;span class="p"&gt;```&lt;/span&gt;&lt;span class="nl"&gt;bash
&lt;/span&gt;gh api repos/OWNER/REPO/issues/NUMBER/comments &lt;span class="nt"&gt;--jq&lt;/span&gt; &lt;span class="s1"&gt;'.[] | {id, user: .user.login, created_at, body}'&lt;/span&gt;
&lt;span class="p"&gt;```&lt;/span&gt;

Review Comments (comments on code lines):
&lt;span class="p"&gt;```&lt;/span&gt;&lt;span class="nl"&gt;bash
&lt;/span&gt;gh api repos/OWNER/REPO/pulls/NUMBER/comments &lt;span class="nt"&gt;--jq&lt;/span&gt; &lt;span class="s1"&gt;'.[] | {id, user: .user.login, path, line, created_at, body, in_reply_to_id}'&lt;/span&gt;
&lt;span class="p"&gt;```&lt;/span&gt;

&lt;span class="gu"&gt;### 4. Comment on PR&lt;/span&gt;

&lt;span class="p"&gt;```&lt;/span&gt;&lt;span class="nl"&gt;bash
&lt;/span&gt;gh &lt;span class="nb"&gt;pr &lt;/span&gt;comment NUMBER &lt;span class="nt"&gt;--repo&lt;/span&gt; OWNER/REPO &lt;span class="nt"&gt;--body&lt;/span&gt; &lt;span class="s2"&gt;"Comment content"&lt;/span&gt;
&lt;span class="p"&gt;```&lt;/span&gt;

&lt;span class="gu"&gt;### 5. Inline Comment (specifying code line)&lt;/span&gt;

First, get the head commit SHA:
&lt;span class="p"&gt;```&lt;/span&gt;&lt;span class="nl"&gt;bash
&lt;/span&gt;gh api repos/OWNER/REPO/pulls/NUMBER &lt;span class="nt"&gt;--jq&lt;/span&gt; &lt;span class="s1"&gt;'.head.sha'&lt;/span&gt;
&lt;span class="p"&gt;```&lt;/span&gt;

Single line comment:
&lt;span class="p"&gt;```&lt;/span&gt;&lt;span class="nl"&gt;bash
&lt;/span&gt;gh api repos/OWNER/REPO/pulls/NUMBER/comments &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--method&lt;/span&gt; POST &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Comment content"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="nv"&gt;commit_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"COMMIT_SHA"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="nv"&gt;path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"src/example.py"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-F&lt;/span&gt; &lt;span class="nv"&gt;line&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;15 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="nv"&gt;side&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;RIGHT
&lt;span class="p"&gt;```&lt;/span&gt;

Multi-line comment (lines 10-15):
&lt;span class="p"&gt;```&lt;/span&gt;&lt;span class="nl"&gt;bash
&lt;/span&gt;gh api repos/OWNER/REPO/pulls/NUMBER/comments &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--method&lt;/span&gt; POST &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Comment content"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="nv"&gt;commit_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"COMMIT_SHA"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="nv"&gt;path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"src/example.py"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-F&lt;/span&gt; &lt;span class="nv"&gt;line&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;15 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="nv"&gt;side&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;RIGHT &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-F&lt;/span&gt; &lt;span class="nv"&gt;start_line&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;10 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="nv"&gt;start_side&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;RIGHT
&lt;span class="p"&gt;```&lt;/span&gt;

&lt;span class="gs"&gt;**Notes:**&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="sb"&gt;`-F`&lt;/span&gt; (uppercase): Use for numeric parameters (&lt;span class="sb"&gt;`line`&lt;/span&gt;, &lt;span class="sb"&gt;`start_line`&lt;/span&gt;). Using &lt;span class="sb"&gt;`-f`&lt;/span&gt; makes it a string and causes an error
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="sb"&gt;`side`&lt;/span&gt;: &lt;span class="sb"&gt;`RIGHT`&lt;/span&gt; (added lines) or &lt;span class="sb"&gt;`LEFT`&lt;/span&gt; (deleted lines)

&lt;span class="gu"&gt;### 6. Reply to Comment&lt;/span&gt;

&lt;span class="p"&gt;```&lt;/span&gt;&lt;span class="nl"&gt;bash
&lt;/span&gt;gh api repos/OWNER/REPO/pulls/NUMBER/comments/COMMENT_ID/replies &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--method&lt;/span&gt; POST &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Reply content"&lt;/span&gt;
&lt;span class="p"&gt;```&lt;/span&gt;

Use the &lt;span class="sb"&gt;`id`&lt;/span&gt; obtained from comment retrieval for &lt;span class="sb"&gt;`COMMENT_ID`&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Key Implementation Detail: Enabling Correct Line Placement for Inline Comments
&lt;/h3&gt;

&lt;p&gt;Getting inline comments on the correct line was the most challenging part, requiring the most adjustments after auto-generating the Skills.&lt;/p&gt;

&lt;p&gt;Let me explain why inline comments ended up on wrong lines. When you get a diff with the &lt;code&gt;gh pr diff&lt;/code&gt; command, you get output in git diff format. For example, an excerpt from &lt;a href="https://github.com/shibayu36/slack-explorer-mcp/pull/20" rel="noopener noreferrer"&gt;https://github.com/shibayu36/slack-explorer-mcp/pull/20&lt;/a&gt; looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gh"&gt;diff --git a/main.go b/main.go
index 3029a7a..9383209 100644
&lt;/span&gt;&lt;span class="gd"&gt;--- a/main.go
&lt;/span&gt;&lt;span class="gi"&gt;+++ b/main.go
&lt;/span&gt;&lt;span class="p"&gt;@@ -3,6 +3,7 @@&lt;/span&gt; package main
 import (
        "context"
        "log/slog"
&lt;span class="gi"&gt;+       "net/http"
&lt;/span&gt;        "os"
&lt;span class="err"&gt;
&lt;/span&gt;        "github.com/mark3labs/mcp-go/mcp"
&lt;span class="p"&gt;@@ -163,17 +164,55 @@&lt;/span&gt; func main() {
                handler.SearchUsersByName,
        )
&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="gd"&gt;-       if err := server.ServeStdio(s, server.WithStdioContextFunc(func(ctx context.Context) context.Context {
-               ctx = WithSlackTokenFromEnv(ctx)
&lt;/span&gt;&lt;span class="gi"&gt;+       transport := os.Getenv("TRANSPORT")
+       if transport == "" {
+               transport = "stdio"
+       }
+
+       switch transport {
+       case "stdio":
+               if err := server.ServeStdio(s, server.WithStdioContextFunc(func(ctx context.Context) context.Context {
+                       ctx = WithSlackTokenFromEnv(ctx)
&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="gd"&gt;-               // Add session ID from ClientSession
-               if session := server.ClientSessionFromContext(ctx); session != nil {
-                       ctx = WithSessionID(ctx, SessionID(session.SessionID()))
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When adding inline comments, you need to specify a line number + side (LEFT for deleted lines or RIGHT for added lines):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gh api repos/OWNER/REPO/pulls/NUMBER/comments \
  --method POST \
  -f body="Comment content" \
  -f commit_id="COMMIT_SHA" \
  -f path="src/example.py" \
  -F line=15 \
  -f side=RIGHT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because of these two API interfaces, to add an inline comment after getting the diff, you need to extract line numbers from lines like &lt;code&gt;@@ -163,17 +164,55 @@ func main() {&lt;/code&gt;, consider the &lt;code&gt;-&lt;/code&gt; or &lt;code&gt;+&lt;/code&gt; at the beginning of lines, determine whether side should be LEFT (deleted) or RIGHT (added), and use that combination for commenting. This extraction operation is difficult for LLMs (even with Opus 4.5), which caused the issue of inline comments being placed on wrong lines.&lt;/p&gt;

&lt;p&gt;However, thinking about it more, if you look at GitHub's web "Files changed" page, the information needed for inline comments is immediately visible:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F18v9ki8a6mgde1zgg8ep.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F18v9ki8a6mgde1zgg8ep.png" alt="GitHub Files changed page showing line numbers" width="800" height="312"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So I thought, why not create the same information from the CLI? That's how I created the command in section "2. Get Diff (with line numbers)" of SKILL.md:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh &lt;span class="nb"&gt;pr &lt;/span&gt;diff NUMBER &lt;span class="nt"&gt;--repo&lt;/span&gt; OWNER/REPO | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'
/^@@/ {
  match($0, /-([0-9]+)/, old)
  match($0, /\+([0-9]+)/, new)
  old_line = old[1]
  new_line = new[1]
  print $0
  next
}
/^-/ { printf "L%-4d     | %s\n", old_line++, $0; next }
/^\+/ { printf "     R%-4d| %s\n", new_line++, $0; next }
/^ / { printf "L%-4d R%-4d| %s\n", old_line++, new_line++, $0; next }
{ print }
'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using this to get the diff from &lt;a href="https://github.com/shibayu36/slack-explorer-mcp/pull/20" rel="noopener noreferrer"&gt;https://github.com/shibayu36/slack-explorer-mcp/pull/20&lt;/a&gt;, you can get similar information to the web "Files changed" page in text format:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@@ -163,17 +164,55 @@ func main() {
L163  R164 |            handler.SearchUsersByName,
L164  R165 |    )
L165  R166 |
L166      | -   if err := server.ServeStdio(s, server.WithStdioContextFunc(func(ctx context.Context) context.Context {
L167      | -           ctx = WithSlackTokenFromEnv(ctx)
     R167 | +   transport := os.Getenv("TRANSPORT")
     R168 | +   if transport == "" {
     R169 | +           transport = "stdio"
     R170 | +   }
     R171 | +
     R172 | +   switch transport {
     R173 | +   case "stdio":
     R174 | +           if err := server.ServeStdio(s, server.WithStdioContextFunc(func(ctx context.Context) context.Context {
     R175 | +                   ctx = WithSlackTokenFromEnv(ctx)
L168  R176 |
L169      | -           // Add session ID from ClientSession
L170      | -           if session := server.ClientSessionFromContext(ctx); session != nil {
L171      | -                   ctx = WithSessionID(ctx, SessionID(session.SessionID()))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now Claude Code can easily get the information needed for inline comments from the &lt;code&gt;L163  R164 |&lt;/code&gt; format on the left, allowing it to place comments on the correct lines.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;In this article, I introduced a Claude Skill that's useful when having AI autonomously review Pull Requests using Claude Code or Claude Code Action. You can use it just by placing the SKILL.md described above under &lt;code&gt;.claude/skills/github-pr-review-operation/&lt;/code&gt;. Give it a try!&lt;/p&gt;

</description>
      <category>programming</category>
      <category>ai</category>
      <category>codereview</category>
      <category>github</category>
    </item>
    <item>
      <title>How Data Formatting (Line Breaks and Indentation) Affects LLM Response Accuracy in RAG</title>
      <dc:creator>shibayu36</dc:creator>
      <pubDate>Mon, 20 Oct 2025 16:30:00 +0000</pubDate>
      <link>https://dev.to/shibayu36/how-data-formatting-line-breaks-and-indentation-affects-llm-response-accuracy-in-rag-47pe</link>
      <guid>https://dev.to/shibayu36/how-data-formatting-line-breaks-and-indentation-affects-llm-response-accuracy-in-rag-47pe</guid>
      <description>&lt;p&gt;&lt;em&gt;(This is an English translation of my original Japanese article: &lt;a href="https://blog.shibayu36.org/entry/2025/10/14/173000" rel="noopener noreferrer"&gt;日本語版はこちら&lt;/a&gt;)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In &lt;a href="https://github.com/shibayu36/slack-explorer-mcp" rel="noopener noreferrer"&gt;slack-explorer-mcp&lt;/a&gt;, instead of returning permalink URLs for each message in the response, I have the AI Agent on the client side construct them. This is because including permalinks for every message would consume a significant amount of tokens. Since permalinks can be reconstructed from other data already provided, I omit them and let the client side build them to save tokens. However, this approach has been inconsistent—sometimes it works well, sometimes it doesn't.&lt;/p&gt;

&lt;p&gt;Currently, slack-explorer-mcp returns large responses in one-line JSON format. I wondered if changing to formatted JSON with line breaks and indentation (which is more human-readable) would also improve accuracy for LLMs.&lt;/p&gt;

&lt;p&gt;So this time, I evaluated how data formatting methods (presence or absence of line breaks and indentation) affect LLM response accuracy. Please note that the test case volume and data size for this evaluation are limited (100 list items, about 16 test cases), so consider these results as a reference.&lt;/p&gt;

&lt;p&gt;Experiment location: &lt;a href="https://github.com/shibayu36/playground/tree/5201dabf441c8d4d4b5a82cf346d3c0cde9185c5/extract-slack-url-eval/en" rel="noopener noreferrer"&gt;shibayu36/playground/extract-slack-url-eval&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;From this evaluation, I found three things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Formatting with line breaks and indentation doesn't particularly improve accuracy&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The stronger the LLM model, the less impact formatting has on accuracy&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;For RAG, it's best to choose the most token-efficient format&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Incidentally, I recently came across discussions that &lt;a href="https://www.improvingagents.com/blog/best-input-data-format-for-llms" rel="noopener noreferrer"&gt;there are differences in response accuracy based on data format&lt;/a&gt;, but &lt;a href="https://news.ycombinator.com/item?id=45458455" rel="noopener noreferrer"&gt;these differences diminish as LLM models become stronger&lt;/a&gt;. While those discussions evaluate differences between data formats like Markdown, CSV, and JSONL (rather than the presence of line breaks and indentation), they seem to reach similar conclusions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Evaluation Method
&lt;/h2&gt;

&lt;p&gt;I used a tool called &lt;a href="https://www.promptfoo.dev/" rel="noopener noreferrer"&gt;promptfoo&lt;/a&gt; for the evaluation.&lt;/p&gt;

&lt;p&gt;First, I prepared dummy data mimicking the message search responses returned by slack-explorer-mcp as RAG test data. I created three format variations for this data:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;oneline JSON&lt;/strong&gt;: JSON format without line breaks or indentation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;pretty JSON&lt;/strong&gt;: JSON format with line breaks and indentation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CSV&lt;/strong&gt;: Comma-separated CSV format. Included to check performance with a token-efficient format that includes line breaks&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here's an example of the actual dummy data. For details, see &lt;a href="https://github.com/shibayu36/playground/blob/5201dabf441c8d4d4b5a82cf346d3c0cde9185c5/extract-slack-url-eval/en/messages-pretty.json" rel="noopener noreferrer"&gt;messages-pretty.json&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"workspace_url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://example.slack.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"messages"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"matches"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"U012ABC3DEF"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Sharing detailed investigation results on BigQuery materialized view deduplication&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;n&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;nFrom the investigation, we found the following:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"ts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1756096495.765749"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"channel"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"C01ABC2DE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"general"&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"U023DEF4GHI"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Got it!"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"ts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1756096501.234567"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"channel"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"C01ABC2DE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"general"&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"thread_ts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1756096495.765749"&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I designed the prompt to include information for generating Slack permalinks and output only the permalink URL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;Your role is to construct the permalink URL for a single Slack message specified by the user from Slack message data. Use the information below to construct the permalink URL.

&lt;span class="gh"&gt;# How to construct the permalink&lt;/span&gt;
Response includes workspace_url, channel.id, and ts (timestamp) which can be used to construct Slack permalinks:
&lt;span class="p"&gt;-&lt;/span&gt; Regular message (no thread_ts field): {workspace_url}/archives/{channel.id}/p{ts without dot}
&lt;span class="p"&gt;-&lt;/span&gt; Thread reply (has thread_ts field): Same URL with ?thread_ts={thread_ts}&amp;amp;cid={channel.id}

&lt;span class="gh"&gt;# Output format&lt;/span&gt;
Output only the permalink URL.

&lt;span class="gh"&gt;# Slack message information&lt;/span&gt;
{{RAG data}}

&lt;span class="gh"&gt;# Let's begin&lt;/span&gt;
Please construct the Slack permalink URL according to the instructions below.

{{input}}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I prepared 16 test cases. For example, here are some test case inputs. See &lt;a href="https://github.com/shibayu36/playground/blob/5201dabf441c8d4d4b5a82cf346d3c0cde9185c5/extract-slack-url-eval/en/promptfooconfig.yaml" rel="noopener noreferrer"&gt;here&lt;/a&gt; for all test cases.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I want the URL for the 3rd message&lt;/li&gt;
&lt;li&gt;URL of the message discussing BigQuery&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Additionally, for the evaluation models, I selected both the latest models and slightly older models to observe differences due to model performance:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;gpt-5-2025-08-07 (latest)&lt;/li&gt;
&lt;li&gt;gpt-4.1-mini-2025-04-14 (slightly older small model)&lt;/li&gt;
&lt;li&gt;claude-sonnet-4-5-20250929 (latest)&lt;/li&gt;
&lt;li&gt;claude-3-7-sonnet-20250219 (slightly older)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Results
&lt;/h2&gt;

&lt;p&gt;The accuracy rates across the 16 test cases were as follows:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;oneline JSON&lt;/th&gt;
&lt;th&gt;pretty JSON&lt;/th&gt;
&lt;th&gt;CSV&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;gpt-5&lt;/td&gt;
&lt;td&gt;&lt;span&gt;100% (16/16)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;100% (16/16)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;100% (16/16)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;gpt-4.1-mini&lt;/td&gt;
&lt;td&gt;&lt;span&gt;62.50% (10/16)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;43.75% (7/16)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;68.75% (11/16)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;claude-sonnet-4-5&lt;/td&gt;
&lt;td&gt;&lt;span&gt;62.50% (10/16)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;68.75% (11/16)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;75% (12/16)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;claude-3-7-sonnet&lt;/td&gt;
&lt;td&gt;&lt;span&gt;56.25% (9/16)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;56.25% (9/16)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;43.75% (7/16)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;gpt-5 achieved an impressive 100% accuracy rate across all formats, showing no difference based on format. For other models, the format with the highest accuracy varied.&lt;/p&gt;

&lt;p&gt;From these results, I confirmed that adding line breaks and indentation doesn't improve accuracy, and furthermore, as models become stronger, the differences due to formatting disappear.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;From this evaluation, I found that when passing list data to LLMs in RAG, formatting for readability with line breaks and indentation doesn't particularly improve accuracy. Additionally, as LLM models become stronger, differences due to formatting disappear. Since gpt-5 already achieved 100% accuracy, this trend will likely continue.&lt;/p&gt;

&lt;p&gt;Paradoxically, these results suggest that &lt;strong&gt;for RAG, it's best to choose the most token-efficient format&lt;/strong&gt;. In the RAG data used this time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;oneline JSON: 6,479 tokens&lt;/li&gt;
&lt;li&gt;pretty JSON: 9,144 tokens&lt;/li&gt;
&lt;li&gt;CSV: 4,784 tokens&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Since CSV format is the most token-efficient, it would be reasonable to adopt CSV format for slack-explorer-mcp as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/shibayu36/playground/tree/5201dabf441c8d4d4b5a82cf346d3c0cde9185c5/extract-slack-url-eval/en" rel="noopener noreferrer"&gt;shibayu36/playground/extract-slack-url-eval&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.improvingagents.com/blog/best-input-data-format-for-llms" rel="noopener noreferrer"&gt;Which Table Format Do LLMs Understand Best? (Results for 11 Formats)&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://news.ycombinator.com/item?id=45458455" rel="noopener noreferrer"&gt;Which table format do LLMs understand best? | Hacker News&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>rag</category>
      <category>llm</category>
      <category>programming</category>
    </item>
    <item>
      <title>A Detailed Workflow for Creating an MCP Server that Returns MySQL Schema Information Using Vibe Coding</title>
      <dc:creator>shibayu36</dc:creator>
      <pubDate>Wed, 08 Oct 2025 17:10:00 +0000</pubDate>
      <link>https://dev.to/shibayu36/a-detailed-workflow-for-creating-an-mcp-server-that-returns-mysql-schema-information-using-vibe-4kfp</link>
      <guid>https://dev.to/shibayu36/a-detailed-workflow-for-creating-an-mcp-server-that-returns-mysql-schema-information-using-vibe-4kfp</guid>
      <description>&lt;p&gt;&lt;em&gt;(This is an English translation of my original Japanese article: &lt;a href="https://blog.shibayu36.org/entry/2025/05/07/183000" rel="noopener noreferrer"&gt;日本語版はこちら&lt;/a&gt;)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://medium.com/@shibayu36/i-built-an-mcp-server-that-compresses-and-serves-mysql-schema-information-d4deb47bded0" rel="noopener noreferrer"&gt;MCP server that provides compressed MySQL schema information&lt;/a&gt; I introduced previously was largely built using Vibe Coding. While researching Vibe Coding techniques, I found many tips but couldn't find detailed examples of actual AI conversations and workflows, which was frustrating.&lt;/p&gt;

&lt;p&gt;So in this article, I'll share the specific Vibe Coding process I used when implementing this tool. I hope this helps others who are struggling to understand the concrete approaches like I was.&lt;/p&gt;

&lt;p&gt;When building this MCP server, my overall Vibe Coding approach was:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Built &lt;a href="https://github.com/shibayu36/mysql-schema-explorer-mcp/commit/154a1675748de0163ab57d320391fe25c6842d98" rel="noopener noreferrer"&gt;the core functionality&lt;/a&gt; almost entirely through Vibe Coding with minimal code review, just runtime verification&lt;/li&gt;
&lt;li&gt;Since Vibe Coding didn't work well for initial test structure setup, I &lt;a href="https://github.com/shibayu36/mysql-schema-explorer-mcp/commit/4b2cbfca61b086180d627dd559f300cd23106871" rel="noopener noreferrer"&gt;manually created this part&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;From there until &lt;a href="https://github.com/shibayu36/mysql-schema-explorer-mcp/commit/ce597fd258ba273a53c9d36cb07c102722e77bca" rel="noopener noreferrer"&gt;this point&lt;/a&gt;, I made changes like test creation, refactoring, and text/template implementation. I used Vibe Coding as the main approach while manually adjusting parts that didn't work well.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'd like to share some implementation examples from this process. In this repository, &lt;a href="https://github.com/shibayu36/mysql-schema-explorer-mcp/tree/ce597fd258ba273a53c9d36cb07c102722e77bca" rel="noopener noreferrer"&gt;up to this commit tree&lt;/a&gt;, I actively committed files in .cursor/ and docs/ directories, so looking at those alongside will be helpful.&lt;/p&gt;

&lt;h3&gt;
  
  
  Basic Workflow
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Before starting implementation, chat with AI to brainstorm requirements and create a requirements.md file&lt;/li&gt;
&lt;li&gt;When implementing something: first ask AI to design it in chat =&amp;gt; write out the design including TODO lists in docs =&amp;gt; reload those docs and have AI code based on them

&lt;ul&gt;
&lt;li&gt;However, if it's not complex design and won't exceed context length limits, you can implement directly without writing to docs&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;When making spec or design changes during development, document them in docs&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;I primarily used Cursor's Agent with Gemini 2.5 Pro model. Occasionally used o4-mini or Claude 3.5 Sonnet. I didn't use memory bank or MCP servers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Examples
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Requirements.md Brainstorming
&lt;/h4&gt;

&lt;p&gt;Let me start with an example of brainstorming requirements. I began with questions like this and had AI help define requirements:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq81b8y8c63p9zb5muobw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq81b8y8c63p9zb5muobw.png" alt=" " width="800" height="558"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I continued chatting quite casually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What I want to do is configure which database to connect to via environment variables, then have two tool calls:
- Output table list
- Output table details
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What would be good tool names?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After continuing the conversation, when I felt we had something reasonable, I said "Please reflect our conversation so far into requirements.md" and had it written out.&lt;/p&gt;

&lt;p&gt;What was created then is &lt;a href="https://github.com/shibayu36/mysql-schema-explorer-mcp/commit/f5243ac4905298250f19cbe131e517e42248d76c" rel="noopener noreferrer"&gt;here&lt;/a&gt;. As you can see, at this point the AI didn't understand the MCP server concept.&lt;/p&gt;

&lt;p&gt;So I continued to help AI understand MCP server concepts while updating requirements.md. Since I thought the reference material &lt;a href="https://modelcontextprotocol.io/quickstart/server" rel="noopener noreferrer"&gt;https://modelcontextprotocol.io/quickstart/server&lt;/a&gt; would be useful for implementing MCP servers, I first asked ChatGPT to create summary material:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;I want to prepare reference material for AI when implementing MCP Server.
Please read the material at https://modelcontextprotocol.io/quickstart/server and create markdown information for AI to read
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After placing the created material in docs/, I loaded it and created requirements.md again. The commit is &lt;a href="https://github.com/shibayu36/mysql-schema-explorer-mcp/commit/d9f03fdc31f821091b38e61ac48f6ca0edb6d795" rel="noopener noreferrer"&gt;here&lt;/a&gt;. This produced a requirements.md that seemed to understand MCP server tool concepts.&lt;/p&gt;

&lt;p&gt;Please also refer to &lt;a href="https://github.com/shibayu36/mysql-schema-explorer-mcp/compare/f5243ac4905298250f19cbe131e517e42248d76c...d9f03fdc31f821091b38e61ac48f6ca0edb6d795" rel="noopener noreferrer"&gt;the diff up to this point&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Implementing list_tables
&lt;/h4&gt;

&lt;p&gt;Next, let me introduce an example of implementing list_tables, a tool function that outputs summary information for table lists in a specific database. The overall picture is &lt;a href="https://github.com/shibayu36/mysql-schema-explorer-mcp/compare/d9f03fdc31f821091b38e61ac48f6ca0edb6d795...9975004378b1bc9abbbb573e60d0a7d3c2b1f08d" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Since I had a TODO list for list_tables implementation in my head, I implemented it step by step with Vibe Coding.&lt;/p&gt;

&lt;p&gt;First, I created &lt;a href="https://github.com/shibayu36/mysql-schema-explorer-mcp/compare/9fb7ea7fd7aba140de303ae9a3b87ad84dd638d7~...20cbf17910a8ec595c7980d692f899691746dec6" rel="noopener noreferrer"&gt;the part that outputs only table names and table comments&lt;/a&gt;. When creating this, I used Cursor's @ reference to load docs/ and asked to start with design rather than writing code. The chat flow was roughly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@main.go I want to create list_tables. First, please think about what kind of design to use without writing code @docs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;How about we start by listing table names and table comments?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Please read @https://github.com/mark3labs/mcp-go/blob/main/README.md and examine the content that listTablesHandler should return more carefully
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After repeating chat like this and feeling the design was reasonable, I generated code all at once:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Looks good. Please reflect this implementation in main.go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Similarly, I also created &lt;a href="https://github.com/shibayu36/mysql-schema-explorer-mcp/compare/2d32beb270e41b95c985cf9ffc89057ffeb11630~...d6565695f764cc1d642ae7124ee5b6008a31eb89" rel="noopener noreferrer"&gt;the PK, UK, FK output parts&lt;/a&gt; using this flow.&lt;/p&gt;

&lt;h4&gt;
  
  
  Refactoring to Use text/template
&lt;/h4&gt;

&lt;p&gt;After creating all functional requirements with the approach explained above, let me also introduce an example of refactoring to use text/template.&lt;/p&gt;

&lt;p&gt;The code initially created with Vibe Coding used string concatenation for text assembly. To improve readability, I considered using text/template and implemented it through Vibe Coding. The overall picture is &lt;a href="https://github.com/shibayu36/mysql-schema-explorer-mcp/compare/6354b5b112409124ec86178ff5703568c678dc8b~...ce597fd258ba273a53c9d36cb07c102722e77bca" rel="noopener noreferrer"&gt;this&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The approach was the same as previously introduced: first have AI design in chat =&amp;gt; write out the design including TODO lists in docs =&amp;gt; reload those docs and have AI code. I started with questions like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgdkvl92xxyzfk79zzpag.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgdkvl92xxyzfk79zzpag.png" alt=" " width="800" height="398"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I continued chatting, asking questions like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Should template-related processing go in view.go? Are there other good file names?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When I felt the design was roughly complete, I had it written to docs. What was created then is &lt;a href="https://github.com/shibayu36/mysql-schema-explorer-mcp/blob/ae9ccbfcd5291430eb077da08f3d4fb92bc342d3/docs/onetime/20250427-use-template.md" rel="noopener noreferrer"&gt;this&lt;/a&gt; (though this doc wasn't committed and includes describe_tables text/template work too).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Let's go in that direction. Could you write out the design so far to docs/onetime/20250427-use-template.md?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then I moved to the implementation phase. After loading the document and having AI create a TODO list:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Let's go step by step. What should we do first?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, I repeated the flow of generating code one step at a time, staging it in git, then implementing the next step. I committed when list_tables text/template conversion was complete.&lt;/p&gt;

&lt;p&gt;I then &lt;a href="https://github.com/shibayu36/mysql-schema-explorer-mcp/commit/ce597fd258ba273a53c9d36cb07c102722e77bca" rel="noopener noreferrer"&gt;created the describe_tables side&lt;/a&gt; using the same flow to complete the refactoring.&lt;/p&gt;

&lt;h3&gt;
  
  
  Thoughts After Trying Vibe Coding
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Among various models I tried, Gemini 2.5 Pro was quite good. Not sure if it's because of the long context length or other reasons

&lt;ul&gt;
&lt;li&gt;However, Gemini has a tendency to write excessive code comments, which was very annoying&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Setting up .cursor/rules/ is essential

&lt;ul&gt;
&lt;li&gt;For example, without rules like &lt;a href="https://github.com/shibayu36/mysql-schema-explorer-mcp/blob/ce597fd258ba273a53c9d36cb07c102722e77bca/.cursor/rules/000-global.mdc" rel="noopener noreferrer"&gt;000-global.mdc&lt;/a&gt;, code generation became quite chaotic and difficult. Reference: &lt;a href="https://qiita.com/masachaco/items/c56bd601576ed9612f6c" rel="noopener noreferrer"&gt;https://qiita.com/masachaco/items/c56bd601576ed9612f6c&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;I also prepared &lt;a href="https://github.com/shibayu36/mysql-schema-explorer-mcp/blob/ce597fd258ba273a53c9d36cb07c102722e77bca/.cursor/rules/100-go-test.mdc" rel="noopener noreferrer"&gt;100-go-test.mdc&lt;/a&gt; to inform about Go test execution methods&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;For newer technology specs or library usage, prepare separate docs and load them when needed

&lt;ul&gt;
&lt;li&gt;I prepared &lt;a href="https://github.com/shibayu36/mysql-schema-explorer-mcp/blob/ce597fd258ba273a53c9d36cb07c102722e77bca/docs/mcp-server-implementing-guide.md" rel="noopener noreferrer"&gt;a summary of MCP server implementation documentation&lt;/a&gt; and &lt;a href="https://github.com/shibayu36/mysql-schema-explorer-mcp/blob/ce597fd258ba273a53c9d36cb07c102722e77bca/docs/mcp-go-cheatsheet.md" rel="noopener noreferrer"&gt;a summary of mcp-go usage&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Having many such references on hand seems important&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;While I used agent delegation as a constraint to understand Vibe Coding this time, for anything other than throwaway code or tools maintained only by myself, it seems better to use Vibe Coding for PoC then adjust or rewrite code yourself&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;In this article, I introduced the specific workflow for creating an MCP server that returns MySQL schema information using Vibe Coding. Since there are many articles about Vibe Coding but few concrete examples, I hope this helps people with similar concerns.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>vibecoding</category>
      <category>programming</category>
    </item>
    <item>
      <title>Improving Code Generation Accuracy by Automatically Searching for Similar Examples After Referencing Documentation</title>
      <dc:creator>shibayu36</dc:creator>
      <pubDate>Mon, 06 Oct 2025 16:00:00 +0000</pubDate>
      <link>https://dev.to/shibayu36/improving-code-generation-accuracy-by-automatically-searching-for-similar-examples-after-2flp</link>
      <guid>https://dev.to/shibayu36/improving-code-generation-accuracy-by-automatically-searching-for-similar-examples-after-2flp</guid>
      <description>&lt;p&gt;Recently, when using AI for code generation with tools like Claude Code's slash commands, I've found that automatically searching for similar examples after referencing documentation improves generation accuracy compared to just referencing documentation alone. In this article, I'll introduce this method.&lt;/p&gt;

&lt;h3&gt;
  
  
  Documentation-only generation often leaves room for improvement in subtle nuances
&lt;/h3&gt;

&lt;p&gt;When generating code, it's well-known that referencing team-established rules such as coding conventions and database design guidelines before generation produces better accuracy than generating code from scratch. Given LLM characteristics, explicitly stating team rules rather than having no rules obviously generates something closer to those standards.&lt;/p&gt;

&lt;p&gt;However, using documentation alone often left me feeling "it's mostly correct, but something feels off about the details." For example, the writing style might be slightly different from other parts of the project.&lt;/p&gt;

&lt;h3&gt;
  
  
  Automatically search for similar examples after referencing documentation
&lt;/h3&gt;

&lt;p&gt;I believe the reason for getting "mostly correct but different" results is that documentation typically contains a summary of project rules and doesn't capture all the subtle nuances. Indeed, when we implement something ourselves, we often reference rule documentation first, then read through similar code in surrounding areas before making flexible decisions like "let's align with this writing style."&lt;/p&gt;

&lt;p&gt;So I thought: what if we follow a similar flow by automatically searching for code similar to what we're about to generate after referencing documentation, and then generate code? I tried this approach, and while it's based on subjective experience, the accuracy improved.&lt;/p&gt;

&lt;p&gt;For example, here's a slash command for generating database ALTER TABLE statements. The key point is not manually providing similar files yourself, but automatically searching for files similar to what you're about to create (step 3 in the procedure):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;allowed-tools&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Read, WebFetch, TodoWrite, Grep, WebSearch, Search&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Create&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;database&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;migration&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;files"&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

You are a MySQL expert creating database migrations.

&lt;span class="gu"&gt;## Procedure&lt;/span&gt;
&lt;span class="p"&gt;1.&lt;/span&gt; Understand the requirements written in $ARGUMENTS
&lt;span class="p"&gt;2.&lt;/span&gt; Read the database design guideline @docs/db-guideline.md
&lt;span class="p"&gt;3.&lt;/span&gt; Load 5 similar migration files from existing migration files
&lt;span class="p"&gt;    -&lt;/span&gt; Search for about 5 files in the &lt;span class="sb"&gt;`migrations/`&lt;/span&gt; directory that make similar changes and check the writing rules
&lt;span class="p"&gt;    -&lt;/span&gt; Pay special attention to the following:
&lt;span class="p"&gt;        -&lt;/span&gt; Indentation
&lt;span class="p"&gt;        -&lt;/span&gt; Which ALTER TABLE format is preferred
&lt;span class="p"&gt;        -&lt;/span&gt; Naming conventions
&lt;span class="p"&gt;        -&lt;/span&gt; Type handling
&lt;span class="p"&gt;        -&lt;/span&gt; NULL permission handling
&lt;span class="p"&gt;        -&lt;/span&gt; DEFAULT writing style
&lt;span class="p"&gt;        -&lt;/span&gt; COMMENT writing style
&lt;span class="p"&gt;4.&lt;/span&gt; Create migration files based on guidelines and similar implementations
&lt;span class="p"&gt;    -&lt;/span&gt; Write accurate SQL following MySQL 8 syntax

&lt;span class="gu"&gt;## Important Notes&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**Follow conventions**&lt;/span&gt;: Always follow the conventions written in the documentation
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**Consistency**&lt;/span&gt;: Maintain consistency with existing code
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**Verification**&lt;/span&gt;: Confirm that the generated code matches the project's style

Now let's start generating migration files according to $ARGUMENTS.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The same concept can be applied to various cases
&lt;/h3&gt;

&lt;p&gt;I think this concept of "automatically searching for similar examples after referencing documentation" can be applied to various cases. For example, when applied to blog writing where you want to generate text similar to your own style, it would look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;When writing articles, always refer to @WRITING.md.
Also, from the content of the article you're about to write, randomly pick several recent similar articles and:
&lt;span class="p"&gt;
-&lt;/span&gt; Use their structure as reference
&lt;span class="p"&gt;-&lt;/span&gt; Mimic the writing style as much as possible

Articles are stored under the shibayu36.hatenablog.com/ directory.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;In this article, I introduced a method to improve the accuracy of code generation and text generation by automatically searching for similar examples after referencing documentation. While this is based on subjective experience, the subtle details became much less concerning, so I encourage you to give it a try.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>productivity</category>
      <category>programming</category>
      <category>llm</category>
    </item>
    <item>
      <title>Creating Project-Specific Commit Messages with Claude Code Subagents</title>
      <dc:creator>shibayu36</dc:creator>
      <pubDate>Tue, 23 Sep 2025 10:15:13 +0000</pubDate>
      <link>https://dev.to/shibayu36/creating-project-specific-commit-messages-with-claude-code-subagents-514f</link>
      <guid>https://dev.to/shibayu36/creating-project-specific-commit-messages-with-claude-code-subagents-514f</guid>
      <description>&lt;p&gt;When developing with Claude Code, I often face the problem of overly verbose commit messages being generated. I recently discovered that the newly released &lt;a href="https://docs.claude.com/en/docs/claude-code/sub-agents" rel="noopener noreferrer"&gt;subagents&lt;/a&gt; feature can solve this problem, so I'd like to share how to set it up.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Problem with Claude Code's Commit Messages
&lt;/h3&gt;

&lt;p&gt;When you ask Claude Code to execute &lt;code&gt;git commit&lt;/code&gt; after implementing features, it generates extremely verbose commit messages like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Add describe_tables e2e test and refactor MCP initialization

- Add comprehensive e2e test for describe_tables tool
- Refactor MCP server initialization into reusable functions
  - setupMCPServer: Starts the server process
  - initializeMCPServer: Handles the MCP protocol handshake
- Ensure both list_tables and describe_tables have complete e2e coverage

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude &amp;lt;noreply@anthropic.com&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Claude Code's generated commit messages have several issues:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They include excessive implementation details in bullet points&lt;/li&gt;
&lt;li&gt;They reflect the conversation context from the session&lt;/li&gt;
&lt;li&gt;They don't consider the project's preferred simple message style&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In worse cases, they even include trial-and-error processes like "Initially tried this approach, but got errors, so abandoned it and ended up doing this instead." This happens because the session's conversation context influences the message generation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Solving It with Subagents
&lt;/h3&gt;

&lt;p&gt;Claude Code's subagents feature allows you to delegate specific tasks to independent agents with separated context. I thought this could isolate commit message generation from conversation context and create messages tailored to project conventions.&lt;/p&gt;

&lt;p&gt;First, I used the &lt;code&gt;/agents&lt;/code&gt; command to generate a subagent configuration file, then made some adjustments to create the following setup. Here's what this subagent does:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Check README.md and CLAUDE.md for project commit message rules and conventions&lt;/li&gt;
&lt;li&gt;Analyze detailed changes in &lt;code&gt;git add&lt;/code&gt;ed files&lt;/li&gt;
&lt;li&gt;Study the project's commit history to learn message patterns&lt;/li&gt;
&lt;li&gt;Generate commit messages following project conventions&lt;/li&gt;
&lt;li&gt;Propose the generated message to the parent session&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
  Full content of .claude/agents/git-commit-message-generator.md
  &lt;br&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;git-commit-message-generator&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Use&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;this&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;agent&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;when&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;you&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;need&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;generate&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;appropriate&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;commit&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;messages&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;for&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;staged&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;files&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;in&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;git&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;repository.&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Examples:&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;lt;example&amp;gt;Context:&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;The&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;has&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;staged&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;some&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;files&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;and&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;wants&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;commit&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;them&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;with&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;an&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;appropriate&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;message.&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;user:&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;'I've&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;staged&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;some&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;changes&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;the&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;authentication&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;system.&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Can&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;you&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;help&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;me&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;create&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;commit&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;message?'&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;assistant:&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;'I'll&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;use&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;the&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;git-commit-message-generator&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;agent&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;analyze&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;the&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;staged&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;changes&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;and&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;create&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;an&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;appropriate&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;commit&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;message&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;following&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;this&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;project's&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;conventions.'&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;lt;commentary&amp;gt;Since&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;the&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;wants&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;help&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;with&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;creating&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;commit&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;message&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;for&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;staged&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;changes,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;use&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;the&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;git-commit-message-generator&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;agent&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;analyze&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;the&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;project's&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;commit&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;conventions&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;and&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;generate&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;an&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;appropriate&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;message.&amp;lt;/commentary&amp;gt;&amp;lt;/example&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;lt;example&amp;gt;Context:&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;The&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;is&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;working&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;on&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;feature&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;and&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;has&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;staged&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;multiple&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;files.&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;user:&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;'Ready&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;commit&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;these&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;bug&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;fixes'&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;assistant:&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;'Let&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;me&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;use&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;the&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;git-commit-message-generator&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;agent&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;examine&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;the&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;staged&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;changes&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;and&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;create&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;proper&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;commit&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;message&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;that&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;follows&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;the&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;project's&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;style.'&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;lt;commentary&amp;gt;The&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;is&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;ready&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;commit&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;staged&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;changes,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;so&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;use&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;the&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;git-commit-message-generator&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;agent&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;generate&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;an&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;appropriate&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;commit&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;message.&amp;lt;/commentary&amp;gt;&amp;lt;/example&amp;gt;"&lt;/span&gt;
&lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;sonnet&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

You are a specialized agent for generating git commit messages! ✨ You are responsible for creating appropriate commit messages that follow project conventions for staged files.

&lt;span class="gu"&gt;## Your Work Process&lt;/span&gt;

&lt;span class="gu"&gt;### 1. Check Project Commit Rules&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Check CLAUDE.md and README.md files for any rules or conventions about commit messages
&lt;span class="p"&gt;-&lt;/span&gt; If found, follow those rules as top priority

&lt;span class="gu"&gt;### 2. Analyze Staged Files&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Run &lt;span class="sb"&gt;`git diff --cached`&lt;/span&gt; to check detailed changes in staged files
&lt;span class="p"&gt;-&lt;/span&gt; Identify the nature of changes (new features, bug fixes, refactoring, documentation updates, etc.)
&lt;span class="p"&gt;-&lt;/span&gt; Evaluate the scope and importance of changes

&lt;span class="gu"&gt;### 3. Analyze Project Commit History&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Run &lt;span class="sb"&gt;`git log --oneline -10`&lt;/span&gt; to check recent commit message formats
&lt;span class="p"&gt;-&lt;/span&gt; Pay special attention to these aspects:
&lt;span class="p"&gt;  -&lt;/span&gt; Language (Japanese, English, or other)
&lt;span class="p"&gt;  -&lt;/span&gt; Message structure (single-line vs multi-line format)
&lt;span class="p"&gt;  -&lt;/span&gt; Prefix usage (feat:, fix:, docs:, etc.)
&lt;span class="p"&gt;  -&lt;/span&gt; Writing style and tone patterns
&lt;span class="p"&gt;  -&lt;/span&gt; Character count tendencies
&lt;span class="p"&gt;  -&lt;/span&gt; Other distinctive patterns

&lt;span class="gu"&gt;### 4. Generate and Propose Commit Message&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Based on the analysis above, generate a commit message that perfectly matches project conventions
&lt;span class="p"&gt;-&lt;/span&gt; The message should accurately and concisely describe changes and be easily understood by future developers
&lt;span class="p"&gt;-&lt;/span&gt; End with "Please run git commit -m 'generated message' yourself"

&lt;span class="gu"&gt;## Important Notes&lt;/span&gt;
&lt;span class="p"&gt;
-&lt;/span&gt; &lt;span class="gs"&gt;**Do NOT execute git commit**&lt;/span&gt; - Only propose messages and leave the actual commit to the parent session
&lt;span class="p"&gt;-&lt;/span&gt; Respect existing project patterns and maintain consistency
&lt;span class="p"&gt;-&lt;/span&gt; For complex changes, summarize appropriately while not missing important information
&lt;span class="p"&gt;-&lt;/span&gt; Ask for clarification if anything is unclear

&lt;span class="gu"&gt;## Error Handling&lt;/span&gt;
&lt;span class="p"&gt;
-&lt;/span&gt; If no files are staged, report this
&lt;span class="p"&gt;-&lt;/span&gt; If not in a git repository or git-related errors occur, report appropriately
&lt;span class="p"&gt;-&lt;/span&gt; If project conventions can't be determined, follow general best practices and explain this

Your goal is to provide project-optimized messages that developers can confidently commit! Good luck! 💪
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;/p&gt;

&lt;p&gt;An important design choice was not letting the subagent execute the commit itself. The reason is that if the subagent commits directly, you can't adjust the message if you want to. Instead, I have it end with "Please run git commit -m 'generated message' yourself", so the parent session executes git commit. This allows message adjustments if you're not satisfied with it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Results from Actual Usage
&lt;/h3&gt;

&lt;p&gt;Usage is simple - just say "create a commit message" after doing &lt;code&gt;git add&lt;/code&gt;. Claude Code will automatically launch the subagent. If it doesn't launch automatically, you can explicitly say "create a commit message with the subagent".&lt;/p&gt;

&lt;p&gt;Let's look at an actual session log. While developing &lt;a href="https://github.com/shibayu36/slack-explorer-mcp" rel="noopener noreferrer"&gt;slack-explorer-mcp&lt;/a&gt;, I was implementing a feature to add workspace URL to responses. When I asked for a commit message afterward, it generated a simple message:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Add workspace URL to search_messages response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I'm including the session log below. You can see how the subagent properly analyzes and generates a message following project conventions, and the parent session executes &lt;code&gt;git commit&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;
  Full session log
  &lt;br&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; git add completed, subagent commit

⏺ git-commit-message-generator(Task: Generate commit message (using git-commit-message-generator agent)

                              Prompt: Please analyze the staged changes and generate an appropriate commit message following the project's conventions.)
  ⎿  Agent Response:
     No special commit message rules in CLAUDE.md. Let me analyze recent commit history patterns!

     Project Commit Message Pattern Analysis 📊

     1. Language: English
     2. Structure: Simple single-line format
     3. Prefix: None used (no feat:, fix:, etc.)
     4. Style: Imperative mood starting with verbs (Add, Update, Implement, Refactor, etc.)
     5. Character count: Around 50-70 characters

     Change Analysis 🔍

     Looking at staged changes:

     handler.go:
     - Added WorkspaceURL field to SearchMessagesResponse struct
     - Added workspace URL extraction from first message permalink when messages exist

     handler_test.go:
     - Updated existing tests to assert workspace_url is included in response
     - Added test case for when no messages found (workspace_url should be empty string)

     This is adding workspace URL return functionality to search_messages response!

     Proposed Commit Message ✨

     Following existing project patterns, I propose this commit message:

     Add workspace URL to search_messages response

     Reasons for this message:
     - Starts with imperative verb "Add" matching the pattern
     - Accurately and concisely describes the change
     - 51 characters, appropriate length
     - No prefix, matching project style

     Please run git commit -m "Add workspace URL to search_messages response" yourself!
  ⎿  Done (4 tool uses · 20.2k tokens · 27.2s)

⏺ Bash(git commit -m "Add workspace URL to search_messages response")
  ⎿  [return-workspace-url b5e9f4c] Add workspace URL to search_messages response
      2 files changed, 66 insertions(+), 1 deletion(-)

⏺ Commit completed! 🎉
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Using Claude Code's subagents feature successfully solved the verbose commit message problem. Since introducing this setup, I rarely need to manually edit commit messages. If you're experiencing similar issues with Claude Code development, I recommend giving this approach a try.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>vibecoding</category>
      <category>programming</category>
      <category>git</category>
    </item>
    <item>
      <title>Added Streamable HTTP Support to Slack Explorer MCP</title>
      <dc:creator>shibayu36</dc:creator>
      <pubDate>Mon, 22 Sep 2025 12:01:00 +0000</pubDate>
      <link>https://dev.to/shibayu36/added-streamable-http-support-to-slack-explorer-mcp-2bgg</link>
      <guid>https://dev.to/shibayu36/added-streamable-http-support-to-slack-explorer-mcp-2bgg</guid>
      <description>&lt;p&gt;I've added Streamable HTTP support to Slack Explorer MCP, which I introduced in &lt;a href="https://dev.to/shibayu36/making-historical-context-easily-discoverable-from-slack-with-ai-building-slack-explorer-mcp-54jj"&gt;this article&lt;/a&gt;. Now you can easily connect from ChatGPT and other AI tools via Remote MCP by hosting it somewhere. Let me share how to use it.&lt;/p&gt;

&lt;p&gt;Here's how to launch it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Launch in Streamable HTTP mode (default port: 8080)&lt;/span&gt;
docker run &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;--pull&lt;/span&gt; always &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;TRANSPORT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;http &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-p&lt;/span&gt; 8080:8080 &lt;span class="se"&gt;\&lt;/span&gt;
  ghcr.io/shibayu36/slack-explorer-mcp:latest

&lt;span class="c"&gt;# Launch with custom port&lt;/span&gt;
docker run &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;--pull&lt;/span&gt; always &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;TRANSPORT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;http &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;HTTP_PORT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;9090 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-p&lt;/span&gt; 9090:9090 &lt;span class="se"&gt;\&lt;/span&gt;
  ghcr.io/shibayu36/slack-explorer-mcp:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When running with default settings (&lt;a href="http://localhost:8080" rel="noopener noreferrer"&gt;http://localhost:8080&lt;/a&gt;), you can add the MCP server to Claude Code like this. The Slack token is passed through the X-Slack-User-Token header.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;claude mcp add &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--transport&lt;/span&gt; http &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s2"&gt;"X-Slack-User-Token: xoxp-..."&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--&lt;/span&gt; slack-explorer-mcp http://localhost:8080/mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why I Wanted Streamable HTTP Support
&lt;/h3&gt;

&lt;p&gt;I wanted to add Streamable HTTP support to make it easier for non-engineers to use.&lt;/p&gt;

&lt;p&gt;With the previous stdio communication, people needed to set up Docker locally and run containers... While this is simple for developers, it creates a barrier for others.&lt;/p&gt;

&lt;p&gt;With Streamable HTTP support, you can host it somewhere and connect from ChatGPT and other tools. No more local environment setup required.&lt;/p&gt;

&lt;h3&gt;
  
  
  Technical Background: Cache and Stateful Implementation
&lt;/h3&gt;

&lt;p&gt;I'd like to share a technical challenge I faced - I had to implement this as a stateful service.&lt;/p&gt;

&lt;p&gt;When adding Streamable HTTP support, it's easier to implement it stateless. That way you can easily deploy to serverless platforms like Lambda. However, Slack Explorer MCP caches Slack's user list, so I couldn't make it stateless.&lt;/p&gt;

&lt;p&gt;Therefore, I implemented it as a stateful service with in-memory cache management per session. The cache has an expiry mechanism, and I use goroutines to periodically clean up expired entries to prevent memory leaks.&lt;/p&gt;

&lt;p&gt;You can see how this is implemented in &lt;a href="https://github.com/shibayu36/slack-explorer-mcp/blob/1492f918b01dbb2a58e6f284427a600a6d164eca/user_repository.go" rel="noopener noreferrer"&gt;user_repository.go&lt;/a&gt; which handles cache management.&lt;/p&gt;

&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;I added Streamable HTTP support to Slack Explorer MCP to make it more accessible for non-engineers. While the cache implementation was challenging, I'm happy with the result.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>productivity</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Making Historical Context Easily Discoverable from Slack with AI - Building slack-explorer-mcp</title>
      <dc:creator>shibayu36</dc:creator>
      <pubDate>Tue, 02 Sep 2025 22:44:04 +0000</pubDate>
      <link>https://dev.to/shibayu36/making-historical-context-easily-discoverable-from-slack-with-ai-building-slack-explorer-mcp-54jj</link>
      <guid>https://dev.to/shibayu36/making-historical-context-easily-discoverable-from-slack-with-ai-building-slack-explorer-mcp-54jj</guid>
      <description>&lt;p&gt;When working on engineering projects, we often need to understand "why things are the way they are now." Even after reading the code, it's often unclear why certain design decisions were made or why specific specifications exist.&lt;/p&gt;

&lt;p&gt;Historical context is often preserved in commit logs, GitHub Pull Requests, and Slack discussions. By combining these sources, we can discover the background behind design decisions, the reasoning for specification choices, and troubleshooting processes that aren't visible in the code itself.&lt;/p&gt;

&lt;p&gt;However, finding past discussions in Slack can be quite challenging because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Finding the right search queries for the problem is difficult&lt;/li&gt;
&lt;li&gt;Extracting the information you need from search results is time-consuming&lt;/li&gt;
&lt;li&gt;Unlike commit logs or GitHub Pull Requests, there are limited ways for AI agents to directly access Slack information&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To make it easier to discover historical context using AI agents, I created an MCP server called slack-explorer-mcp that can retrieve Slack discussions. This has made tracking down historical context incredibly efficient. Let me introduce this tool today.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/shibayu36/slack-explorer-mcp" rel="noopener noreferrer"&gt;https://github.com/shibayu36/slack-explorer-mcp&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What is slack-explorer-mcp?
&lt;/h3&gt;

&lt;p&gt;slack-explorer-mcp is an MCP server specifically designed to retrieve Slack messages and thread information using a Slack User Token. It can be used with MCP-compatible AI agents like Claude Code, Claude Desktop, and Cursor.&lt;/p&gt;

&lt;p&gt;Key features include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Message search (with advanced filtering by channel, user, date range, reactions, file presence, and more)

&lt;ul&gt;
&lt;li&gt;Most features available in &lt;a href="https://slack.com/help/articles/202528808" rel="noopener noreferrer"&gt;Search in Slack&lt;/a&gt; are supported&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Retrieving thread replies&lt;/li&gt;

&lt;li&gt;Fetching user information (by User ID or Display name)&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Installation and Setup
&lt;/h3&gt;

&lt;p&gt;For detailed installation instructions, please refer to the &lt;a href="https://github.com/shibayu36/slack-explorer-mcp/blob/main/README.md" rel="noopener noreferrer"&gt;README.md&lt;/a&gt;. Basically, you just need to create a Slack App to obtain a User Token, then add the MCP server to your MCP-compatible AI agent like Claude Code or Cursor.&lt;/p&gt;

&lt;p&gt;If you have Docker installed and want to add it to Claude Code, you can use the following command with your User Token:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;claude mcp add slack-explorer-mcp &lt;span class="nt"&gt;--&lt;/span&gt; docker run &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;--pull&lt;/span&gt; always &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;SLACK_USER_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;xoxp-your-token-here ghcr.io/shibayu36/slack-explorer-mcp:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Example 1: Investigating Historical Context
&lt;/h3&gt;

&lt;p&gt;Let me share some specific examples of when this tool is useful.&lt;/p&gt;

&lt;h4&gt;
  
  
  Finding Why a BigQuery Table Became a Materialized View
&lt;/h4&gt;

&lt;p&gt;Recently, I was wondering "Why is this BigQuery table a materialized view?" I could ask Claude Code to investigate with a prompt like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Find out from Slack discussions why the foo_summary table in BigQuery is a materialized view.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The AI then investigated the historical context through the following process:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Thinking of search queries and performing an initial search&lt;/li&gt;
&lt;li&gt;Based on the results, creating more specific search queries for several additional searches&lt;/li&gt;
&lt;li&gt;Reading all content when threads are found&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Through this investigation process, it created a summary like "The table was changed to a materialized view at [specific time] for [specific reason]." If you request permalinks, it will also return links to the actual logs so you can verify the details.&lt;/p&gt;

&lt;h4&gt;
  
  
  Investigating Current SaaS Contract Terms
&lt;/h4&gt;

&lt;p&gt;Questions like "Why is this SaaS on an annual contract?" or "Why is the quota limit set to this number?" can also be investigated from past Slack content. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Research from past Slack discussions why the oo SaaS service is on an annual contract and why the quota limit is set to this specific number
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Example 2: Other Useful Applications
&lt;/h3&gt;

&lt;p&gt;Since this tool leverages the &lt;a href="https://slack.com/help/articles/202528808" rel="noopener noreferrer"&gt;Search in Slack&lt;/a&gt; functionality, it can be used for various purposes beyond investigating historical context.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Summarizing weekly topics in a specific channel

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Summarize all topics discussed this week in the #random channel&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Analyzes the week's conversations in the specified channel and lists main topics. Useful for weekly reviews and understanding team trends&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Summarizing who you talked to and what you discussed today

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Summarize who shibayu36 talked to today and what they discussed&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Can summarize a specific user's daily activities. Useful for writing daily reports or summarizing someone's activities&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;With slack-explorer-mcp, you can easily search and analyze past Slack discussions from Claude Code or Cursor. Try it out when you need to understand historical context that isn't visible in code, or when you want to summarize team activities. I think you'll find it quite useful!&lt;/p&gt;

&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/shibayu36/slack-explorer-mcp" rel="noopener noreferrer"&gt;shibayu36/slack-explorer-mcp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://modelcontextprotocol.io/" rel="noopener noreferrer"&gt;Model Context Protocol (MCP)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://slack.com/help/articles/202528808" rel="noopener noreferrer"&gt;Search in Slack&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Appendix: Differences from Other MCP Tools
&lt;/h3&gt;

&lt;p&gt;While there are other MCP tools for Slack, I created this new one because existing tools had some limitations for my use case.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/ubie-oss/slack-mcp-server" rel="noopener noreferrer"&gt;ubie-oss/slack-mcp-server&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;Provides various bot-perspective operations with many features&lt;/li&gt;
&lt;li&gt;To focus only on information retrieval, you need to add the bot to many channels, which was inconvenient for casual information gathering&lt;/li&gt;
&lt;li&gt;Should be useful when you want AI agents to operate Slack bots&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;a href="https://github.com/korotovsky/slack-mcp-server" rel="noopener noreferrer"&gt;korotovsky/slack-mcp-server&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;Similar to this tool, offers many features for information retrieval&lt;/li&gt;
&lt;li&gt;However, it requires browser authentication tokens, which I felt was quite poor security practice, so I didn't want to use it&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>productivity</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
