<?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>Forem: Gary Jarrel</title>
    <description>The latest articles on Forem by Gary Jarrel (@garyj).</description>
    <link>https://forem.com/garyj</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%2F945604%2F143e6f17-ef11-4255-ad77-4b05edf2a79e.jpeg</url>
      <title>Forem: Gary Jarrel</title>
      <link>https://forem.com/garyj</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/garyj"/>
    <language>en</language>
    <item>
      <title>Claude Code Plugin CLI: The Missing Manual</title>
      <dc:creator>Gary Jarrel</dc:creator>
      <pubDate>Wed, 14 Jan 2026 06:25:51 +0000</pubDate>
      <link>https://forem.com/garyj/claude-code-plugin-cli-the-missing-manual-40nf</link>
      <guid>https://forem.com/garyj/claude-code-plugin-cli-the-missing-manual-40nf</guid>
      <description>&lt;p&gt;Claude Code for me is like a best friend at work, I use it in my daily coding work, and non coding tasks, like sorting supplier invoices, summarizing account payables, though I always verify its output, the productivity gains are huge.&lt;/p&gt;

&lt;p&gt;More and more I find myself relying on &lt;a href="https://code.claude.com/docs/en/discover-plugins" rel="noopener noreferrer"&gt;Claude Code plugins&lt;/a&gt; (skills, hooks, commands, etc). Commonly, I would write these myself partly as a learning exercise as it gets you thinking about the underlying mechanics of Claude Code, but also because I have specific needs that are not common to the Claude Code use case, yet work surprisingly well in Claude code. For example processing, summarizing and "Exelifying" (not a word) compliance documents in our Real Estate business.&lt;/p&gt;

&lt;p&gt;Since October, when Anthropic released the plugin system for Claude Code, the number of publicly available plugins has skyrocketed. And, of course with new shiny tools comes the desire to try them.&lt;/p&gt;

&lt;p&gt;After pushing past the anxiety of installing more untrusted code into my machine (subject for another post), I ran into an installation issue. As a native Linux user, I primarily work in the CLI and heavily rely on scripts, aliases, and various shortcuts. The Claude Code plugin installation didn't fit my workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Claude Code's &lt;a href="https://code.claude.com/docs/en/discover-plugins#try-it:-add-the-demo-marketplace" rel="noopener noreferrer"&gt;plugin docs&lt;/a&gt; primarily focuses on the use of the interactive &lt;code&gt;/plugin&lt;/code&gt; commands which is used inside Claude Code REPL.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/plugin marketplace add anthropics/claude-code
/plugin &lt;span class="nb"&gt;install &lt;/span&gt;some-plugin@marketplace
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means I would have to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open Claude Code&lt;/li&gt;
&lt;li&gt;Wait for it to initialise&lt;/li&gt;
&lt;li&gt;Type the command&lt;/li&gt;
&lt;li&gt;Restart Claude Code&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This to me feels clunky, slow and "unmanaged". I wanted to manage plugins the same way I manage everything else on my system - from my terminal.&lt;/p&gt;

&lt;h2&gt;
  
  
  The CLI Commands (That Actually Exist)
&lt;/h2&gt;

&lt;p&gt;In the docs the &lt;code&gt;claude plugin install&lt;/code&gt; command is &lt;a href="https://code.claude.com/docs/en/discover-plugins#manage-installed-plugins" rel="noopener noreferrer"&gt;mentioned&lt;/a&gt; but nothing to manage the marketplaces. The section on the &lt;a href="https://code.claude.com/docs/en/discover-plugins#use-cli-commands" rel="noopener noreferrer"&gt;Marketplace CLI&lt;/a&gt; at the time of writing still shows usage of &lt;code&gt;/plugin&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Even &lt;code&gt;claude --help&lt;/code&gt; doesn't mention the &lt;code&gt;marketplace&lt;/code&gt; subcommand&lt;/strong&gt; On my installation (v2.1.6).&lt;/p&gt;

&lt;h3&gt;
  
  
  Marketplace Commands
&lt;/h3&gt;

&lt;p&gt;Undocumented&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;# Add a marketplace&lt;/span&gt;
claude plugin marketplace add &amp;lt;url-or-repo&amp;gt;

&lt;span class="c"&gt;# List all marketplaces&lt;/span&gt;
claude plugin marketplace list

&lt;span class="c"&gt;# Update a marketplace&lt;/span&gt;
claude plugin marketplace update &amp;lt;name&amp;gt;

&lt;span class="c"&gt;# Remove a marketplace&lt;/span&gt;
claude plugin marketplace remove &amp;lt;name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Plugin Commands
&lt;/h3&gt;

&lt;p&gt;Documented in 2 lines in the docs.&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;# Install a plugin (with optional scope)&lt;/span&gt;
claude plugin &lt;span class="nb"&gt;install&lt;/span&gt; &amp;lt;plugin&amp;gt;@&amp;lt;marketplace&amp;gt;
claude plugin &lt;span class="nb"&gt;install&lt;/span&gt; &amp;lt;plugin&amp;gt;@&amp;lt;marketplace&amp;gt; &lt;span class="nt"&gt;--scope&lt;/span&gt; project
claude plugin &lt;span class="nb"&gt;install&lt;/span&gt; &amp;lt;plugin&amp;gt;@&amp;lt;marketplace&amp;gt; &lt;span class="nt"&gt;--scope&lt;/span&gt; &lt;span class="nb"&gt;local&lt;/span&gt;

&lt;span class="c"&gt;# Uninstall a plugin&lt;/span&gt;
claude plugin uninstall &amp;lt;plugin&amp;gt;

&lt;span class="c"&gt;# Enable/disable a plugin&lt;/span&gt;
claude plugin &lt;span class="nb"&gt;enable&lt;/span&gt; &amp;lt;plugin&amp;gt;
claude plugin disable &amp;lt;plugin&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These commands allowed me easily to manage my Claude Code plugins from the terminal. I wanted to try &lt;a href="https://github.com/obra" rel="noopener noreferrer"&gt;Jesse Vincent&lt;/a&gt;'s &lt;a href="https://github.com/obra/superpowers" rel="noopener noreferrer"&gt;Superpowers plugin&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;claude plugin marketplace add https://github.com/obra/superpowers
claude plugin &lt;span class="nb"&gt;install &lt;/span&gt;superpowers@superpowers-marketplace
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Simple and clean!&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Not Use Third-Party Tools?
&lt;/h2&gt;

&lt;p&gt;When trying to find a solution I came across the &lt;a href="https://github.com/Kamalnrf/claude-plugins" rel="noopener noreferrer"&gt;claude-plugins&lt;/a&gt; CLI community tools, which probably would have done the trick.&lt;/p&gt;

&lt;p&gt;But my take: that is another package in my supply chain. Another thing I need to trust. Another thing that could be compromised via dependency confusion, typosquatting, etc. All too often I type &lt;code&gt;claud&lt;/code&gt; missing the &lt;code&gt;e&lt;/code&gt; at the end.&lt;/p&gt;

&lt;p&gt;The official CLI commands come from Anthropic, the same trust boundary I have already accepted when I installed Claude Code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Making It Ergonomic
&lt;/h2&gt;

&lt;p&gt;With the help of Claude Code I wrapped these commands in a &lt;a href="https://github.com/garyj/dotfiles/blob/master/home/dot_justfiles/claude.justfile" rel="noopener noreferrer"&gt;justfile&lt;/a&gt; which forms part of my dotfiles config, this allows me to simply run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;just claude mpa &amp;lt;url&amp;gt;      &lt;span class="c"&gt;# Add/update a marketplace&lt;/span&gt;
just claude mpr &amp;lt;name&amp;gt;     &lt;span class="c"&gt;# Remove marketplace (and its plugins)&lt;/span&gt;
just claude mpup &amp;lt;name&amp;gt;    &lt;span class="c"&gt;# Update a marketplace&lt;/span&gt;
just claude mpl            &lt;span class="c"&gt;# List marketplaces&lt;/span&gt;

just claude pla &amp;lt;plugin&amp;gt;   &lt;span class="c"&gt;# Install a plugin&lt;/span&gt;
just claude plr &amp;lt;plugin&amp;gt;   &lt;span class="c"&gt;# Uninstall a plugin&lt;/span&gt;
just claude ple &amp;lt;plugin&amp;gt;   &lt;span class="c"&gt;# Enable a plugin&lt;/span&gt;
just claude pld &amp;lt;plugin&amp;gt;   &lt;span class="c"&gt;# Disable a plugin&lt;/span&gt;
just claude pll            &lt;span class="c"&gt;# List installed plugins&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;mpa&lt;/code&gt; command is idempotent - if the marketplace is already installed, it automatically updates instead of failing. Claude throws an error if you try to add a marketplace that already exists.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;mpr&lt;/code&gt; command removes all plugins from a marketplace before removing it, preventing orphans.&lt;/p&gt;

&lt;p&gt;Here's the justfile:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;&lt;span class="c"&gt;# add or update a marketplace
&lt;/span&gt;&lt;span class="err"&gt;[group(&lt;/span&gt;&lt;span class="s2"&gt;"plugins"&lt;/span&gt;&lt;span class="err"&gt;),&lt;/span&gt; &lt;span class="err"&gt;script(&lt;/span&gt;&lt;span class="s2"&gt;"bash"&lt;/span&gt;&lt;span class="err"&gt;)]&lt;/span&gt;
&lt;span class="nl"&gt;mpa url&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nv"&gt;output&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;command &lt;/span&gt;claude plugin marketplace add &lt;span class="s2"&gt;"{{ url &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;}"&lt;/span&gt; 2&amp;gt;&amp;amp;1&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$output&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-qi&lt;/span&gt; &lt;span class="s2"&gt;"already installed"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
        &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$output&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"s/.*Marketplace '&lt;/span&gt;&lt;span class="se"&gt;\(&lt;/span&gt;&lt;span class="s2"&gt;[^']*&lt;/span&gt;&lt;span class="se"&gt;\)&lt;/span&gt;&lt;span class="s2"&gt;'.*/&lt;/span&gt;&lt;span class="se"&gt;\1&lt;/span&gt;&lt;span class="s2"&gt;/p"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Already installed, will update instead: &lt;/span&gt;&lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
        just &lt;span class="nt"&gt;--justfile&lt;/span&gt; &lt;span class="o"&gt;{{&lt;/span&gt; justfile &lt;span class="o"&gt;}}&lt;/span&gt; mpup &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$output&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="c"&gt;# remove a marketplace (and its plugins)
&lt;/span&gt;&lt;span class="err"&gt;[group(&lt;/span&gt;&lt;span class="s2"&gt;"plugins"&lt;/span&gt;&lt;span class="err"&gt;),&lt;/span&gt; &lt;span class="err"&gt;script(&lt;/span&gt;&lt;span class="s2"&gt;"bash"&lt;/span&gt;&lt;span class="err"&gt;)]&lt;/span&gt;
&lt;span class="nl"&gt;mpr name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="c"&gt;# Find and remove all plugins from this marketplace&lt;/span&gt;
    &lt;span class="nv"&gt;plugins&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;$(&lt;/span&gt;jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'.plugins | keys[] | select(endswith("@{{ name &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s1"&gt;}")) | split("@")[0]'&lt;/span&gt; ~/.claude/plugins/installed_plugins.json 2&amp;gt;/dev/null&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;for &lt;/span&gt;plugin &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nv"&gt;$plugins&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Removing plugin: &lt;/span&gt;&lt;span class="nv"&gt;$plugin&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
        &lt;span class="nb"&gt;command &lt;/span&gt;claude plugin uninstall &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$plugin&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; 2&amp;gt;&amp;amp;1 &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;
    &lt;span class="k"&gt;done&lt;/span&gt;
    &lt;span class="c"&gt;# Remove the marketplace&lt;/span&gt;
    &lt;span class="nb"&gt;command &lt;/span&gt;claude plugin marketplace remove &lt;span class="s2"&gt;"{{ name }}"&lt;/span&gt;

&lt;span class="c"&gt;# update a marketplace
&lt;/span&gt;&lt;span class="err"&gt;[group(&lt;/span&gt;&lt;span class="s2"&gt;"plugins"&lt;/span&gt;&lt;span class="err"&gt;)]&lt;/span&gt;
&lt;span class="nl"&gt;@mpup name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nb"&gt;command &lt;/span&gt;claude plugin marketplace update &lt;span class="s2"&gt;"{{ name }}"&lt;/span&gt;

&lt;span class="c"&gt;# list marketplaces
&lt;/span&gt;&lt;span class="err"&gt;[group(&lt;/span&gt;&lt;span class="s2"&gt;"plugins"&lt;/span&gt;&lt;span class="err"&gt;)]&lt;/span&gt;
&lt;span class="nl"&gt;@mpl&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nb"&gt;command &lt;/span&gt;claude plugin marketplace list

&lt;span class="c"&gt;# add/install a plugin
&lt;/span&gt;&lt;span class="err"&gt;[group(&lt;/span&gt;&lt;span class="s2"&gt;"plugins"&lt;/span&gt;&lt;span class="err"&gt;)]&lt;/span&gt;
&lt;span class="nl"&gt;@pla plugin&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nb"&gt;command &lt;/span&gt;claude plugin &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="s2"&gt;"{{ plugin }}"&lt;/span&gt;

&lt;span class="c"&gt;# remove/uninstall a plugin
&lt;/span&gt;&lt;span class="err"&gt;[group(&lt;/span&gt;&lt;span class="s2"&gt;"plugins"&lt;/span&gt;&lt;span class="err"&gt;)]&lt;/span&gt;
&lt;span class="nl"&gt;@plr plugin&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nb"&gt;command &lt;/span&gt;claude plugin uninstall &lt;span class="s2"&gt;"{{ plugin }}"&lt;/span&gt;

&lt;span class="c"&gt;# disable a plugin
&lt;/span&gt;&lt;span class="err"&gt;[group(&lt;/span&gt;&lt;span class="s2"&gt;"plugins"&lt;/span&gt;&lt;span class="err"&gt;)]&lt;/span&gt;
&lt;span class="nl"&gt;@pld plugin&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nb"&gt;command &lt;/span&gt;claude plugin disable &lt;span class="s2"&gt;"{{ plugin }}"&lt;/span&gt;

&lt;span class="c"&gt;# enable a plugin
&lt;/span&gt;&lt;span class="err"&gt;[group(&lt;/span&gt;&lt;span class="s2"&gt;"plugins"&lt;/span&gt;&lt;span class="err"&gt;)]&lt;/span&gt;
&lt;span class="nl"&gt;@ple plugin&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nb"&gt;command &lt;/span&gt;claude plugin &lt;span class="nb"&gt;enable&lt;/span&gt; &lt;span class="s2"&gt;"{{ plugin }}"&lt;/span&gt;

&lt;span class="c"&gt;# list installed plugins
&lt;/span&gt;&lt;span class="err"&gt;[group(&lt;/span&gt;&lt;span class="s2"&gt;"plugins"&lt;/span&gt;&lt;span class="err"&gt;)]&lt;/span&gt;
&lt;span class="nl"&gt;@pll&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="c"&gt;# why is there no `claude plugin list`? :&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
    jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'.plugins | keys[] | split("@") | "\(.[0]) (from \(.[1]))"'&lt;/span&gt; ~/.claude/plugins/installed_plugins.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Get the Full Config
&lt;/h2&gt;

&lt;p&gt;The complete justfile is part of my  &lt;a href="https://www.chezmoi.io/" rel="noopener noreferrer"&gt;chezmoi&lt;/a&gt; managed &lt;a href="https://github.com/garyj/dotfiles/blob/master/home/dot_justfiles/claude.justfile" rel="noopener noreferrer"&gt;dotfiles&lt;/a&gt; specifically the &lt;a href="https://github.com/garyj/dotfiles/blob/master/home/dot_justfiles/claude.justfile" rel="noopener noreferrer"&gt;claude.justfile&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you've been frustrated by plugin management in Claude Code, I hope this saves you some time. The CLI exists, it's just hiding.&lt;/p&gt;

</description>
      <category>claudecode</category>
      <category>cli</category>
      <category>productivity</category>
      <category>dotfiles</category>
    </item>
  </channel>
</rss>
