A quick‑start guide to create a working Claude plugin using the official SDK
Welcome to another official UVF IT build guide! In the next 45 minutes you’ll spin up a tiny Claude plugin that can be discovered and invoked from Claude Code, mirroring the structure of the official plugin directory.
We’ll use Node.js (v18+) with a local SQLite DB to store a simple command, no paid APIs required – just pure open‑source tooling.
plugins/ folder is writable – the SDK writes a temporary plugin.json during install.We start by creating a fresh npm workspace so the SDK has a place to install its dependencies. This step also generates a package.json that will track our plugin's metadata and scripts.
Next we pull in the official Claude plugin SDK, which provides the request handling, validation, and registration helpers you need to expose a slash command to Claude Code.
npm init -y
npm install @anthropic/claude-plugin-sdkClaude discovers plugins via a manifest file placed under a .claude-plugin folder. The manifest tells Claude the plugin's slug, description, and the HTTP endpoint it should call.
We keep it minimal: a unique slug, a short description, and the path to our local server (http://localhost:3000). This is enough for Claude Code to list and invoke the plugin.
.claude-plugin/plugin.json
{
"slug": "minimal-clone",
"name": "Minimal Claude Plugin Clone",
"description": "A tiny example plugin exposing a single slash command.",
"api": {
"base_url": "http://localhost:3000"
}
}We’ll spin up a tiny Express server that Claude can call via a slash command. The endpoint lives under /commands/hello and simply returns a JSON payload with a friendly greeting, which Claude will surface to the user. Keeping the logic minimal makes it easy to extend later with parameters or authentication.
Next we register the route with Express, set the appropriate CORS headers so Claude’s webview can reach it, and export the server so npm start can launch it. This file becomes the heart of your clone – every command you add will be another route here.
server.js
const express = require('express');
const cors = require('cors');
const app = express();
const PORT = process.env.PORT || 3000;
app.use(cors()); // allow Claude to call our endpoint
app.use(express.json());
// Slash command: /commands/hello
app.post('/commands/hello', (req, res) => {
// Claude sends a JSON body; we ignore it for this static example
res.json({
type: 'text',
content: 'Hello from your minimal Claude plugin!'
});
});
app.listen(PORT, () => {
console.log(`Server listening on http://localhost:${PORT}`);
});Now that the server code is ready, start it with Node. The process will bind to the port declared in plugin.json (default 3000), making the /commands/hello endpoint reachable from your machine.
While the server runs, you can open a browser or use curl to confirm the route returns the expected JSON. If you see the greeting, the plugin is ready for Claude to load.
node server.jsOpen Claude Code (the web IDE for Claude) and add your plugin manifest by running the install command with a local path. Claude will read .claude-plugin/plugin.json and register the /hello command automatically.
After installation, type /hello in a Claude conversation. Claude should call your local server and display the greeting you defined earlier. If it does, the clone is fully functional!
# Quick sanity check from the terminal
curl -s http://localhost:3000/commands/hello | grep Hello| Check | Command / Why it matters |
|---|---|
| package.json exists after npm init | ls -1 | grep package.json |
| plugin.json is correctly placed under .claude-plugin | cat .claude-plugin/plugin.json |
| Server starts without errors | node server.js |
| HTTP 200 returned from /commands/hello | curl -s http://localhost:3000/commands/hello | grep Hello |
Your minimal Claude plugin is now live and callable from Claude Code. Extend it by adding more commands, persisting data in SQLite, or exposing agents—just follow the same pattern.