# The best "undocumented" feature of Claude Plugins

Gustavo Ambrozio 7 min read
Table of Contents

Note

The plugin mentioned below was removed from the repository as there’s now a better one. All links still work but they reference the last version before I removed it from the repository.

Getting started with my first plugin

When Anthropic announced Plugins for Claude Code 3 weeks ago, I immediately wanted to create one. Their Skills announcement a week later adding support for them in Plugins sealed the deal.

My own plugin marketplace repository was born from this excitement, along with my first plugin to help with iOS and macOS development. The plugin consisted of some of the MCP servers that I use on all my projects, a simple slash command and, what I was most excited about, a skill to help Claude when dealing with xcodebuild, a notoriously verbose tool that is known to eat a lot of tokens.

There are some MCP servers out there to help with that but they still produce a lot of tokens and every once in a while a project that compiles fine in Xcode will fail to compile using the plugin for no particular reason, sending Claude on a wild ride trying to fix non-existing issues.

A tool called xcsift showed up a few weeks ago. It can parse the verbose output of xcodebuild and swift and output a succinct json that is easier for Claude to parse and very token efficient.

I started using it on some of my projects by adding instructions to my CLAUDE.md files but I decided to integrate it into a skill within this plugin.

Building the Skill

For those unfamiliar: a skill is a set of instructions and supporting files and scripts Claude loads on demand. Sessions start with Claude reading a brief description to determine when to activate the skill, then load full instructions only when needed, saving context.

My skill had what I thought was a simple, straightforward description that I hoped would be enough to make it be used when necessary:

Compiles Xcode projects and swift packages and report errors or warnings. Use it whenever you would use xcodebuild or swift commands.

The rest of the skill instructed Claude to use the included shell script whenever it needed to invoke xcodebuild. The script was simple: it first makes sure xcsift is installed on your machine, installing it if necessary. Then it invokes xcodebuild with all the provided flags and some that I always want to provide.

Testing the skill locally on one of my projects by asking it to make sure the project compiled worked as I expected:

> Make sure the project compiles


⏺ I'll build the project to check for any compilation errors.


> The "swift-compile" skill is loading


⏺ I'll build the workspace to check for compilation errors.


Bash(cd /Users/gustavoambrozio/Development/ClaudeCodePlugins/SwiftDevelopment/skills/swift-compile && scripts/xcodebuild.sh -workspace /Users/gustavoambrozio/Develop…) timeout: 5m 0s

⎿ {

"status" : "success",

"summary" : {

… +5 lines (ctrl+o to expand)

Shell cwd was reset to /Users/gustavoambrozio/Development/MacOSTestProject


⏺ ✅ Project compiles successfully!


The build completed with:

- 0 errors

- 1 warning (minor)

- Build status: success


The MacOSTestProject workspace is building correctly. The single warning is minor and doesn't prevent compilation.

Good sign. I published and asked my co-workers to test it out.

The feedback was quick and disappointing: Claude was still using xcodebuild directly and that they had to explicitly ask Claude to use the skill.

To try to reproduce the issue I changed my agent to Haiku and turned off thinking mode. This led to Claude ignoring my instructions now.

I sighed and put this aside for a while until something caught my attention.

How a deprecation warning revealed the solution

Later that day I opened Claude Code and saw a note saying that “Output styles are deprecated”. This got me upset as this is a feature I cherish (more on that in a future post).

Luckily it provided an alternative in the form of a plugin hook.

Claude shows a link to their Explanatory Output Style Plugin. This plugin is very simple, consisting only of a SessionStart hook that gives initial instructions to Claude Code.

The plugin invokes this simple script when a session starts:

#!/bin/bash
# Output the explanatory mode instructions as additionalContext
# This mimics the deprecated Explanatory output style
cat << 'EOF'
{
"hookSpecificOutput": {
"hookEventName": "SessionStart",
"additionalContext": "You are in 'explanatory' output style mode, where you should provide educational insights about the codebase as you help with the user's task.\n\nYou should be clear and educational, providing helpful explanations while remaining focused on the task. Balance educational content with task completion. When providing insights, you may exceed typical length constraints, but remain focused and relevant.\n\n## Insights\nIn order to encourage learning, before and after writing code, always provide brief educational explanations about implementation choices using (with backticks):\n\"`★ Insight ─────────────────────────────────────`\n[2-3 key educational points]\n`─────────────────────────────────────────────────`\"\n\nThese insights should be included in the conversation, not in the codebase. You should generally focus on interesting insights that are specific to the codebase or the code you just wrote, rather than general programming concepts. Do not wait until the end to provide insights. Provide them as you write code."
}
}
EOF
exit 0

Turns out plugins DO have a way to provide instructions to the user by using a SessionStart hook. While saying this feature is “undocumented” is not accurate - the documentation for hooks clearly shows that you can do this - I hadn’t considered using this in the context of plugins to provide plugin specific instructions.

This led me to create a similar script and added to my plugin’s hook configuration. I don’t like the way Anthropic embeds their instructions in a heredoc on the shell script so my plugin reads a markdown of the instructions so it’s easier to edit them.

And that got me thinking that I could use hooks to make extra sure that Claude would use my scripts to compile code.

Since Claude always sends a PreToolUse hook that you can use to deny the use of a tool I created another script and added to the PreToolUse hook configuration. It checks what command line is being called and if the user is using xcodebuild directly it denies access to the tool and clearly tells Claude to use the skill.

After all this arm twisting I’m pretty confident that Claude will always use my skill to compile my projects. 🤞

TL;DR

Plugins are a powerful tool for Claude Code and I think we’ll start seeing a lot of very useful ones in the next few weeks, especially when developers start to understand and explore the interactions between all the parts of a plugin. I’m excited to expand this plugin with more tools and create others.

If you have any issues with this plugin or want to improve it in any way, please open an issue or, even better, clone and create a PR.

My avatar

Thanks for reading! Feel free to contact me via the social links in the footer.


More Posts

Comments