# Weavetab Plugin Authoring Specification (@weavetab/sdk v2.6.0) > Standalone specification for AI coding agents (Cursor, Claude Code, Antigravity, Windsurf, ChatGPT) to create, test, and publish Weavetab MCP plugins without needing to read the SDK repository or source code. ## 1. Quickstart CLI Scaffold a ready-to-publish TypeScript plugin in seconds: ```bash npx @weavetab/sdk init my-weavetab-plugin cd my-weavetab-plugin npm install npm run build npm test ``` ## 2. Minimal 20-Line Plugin (`src/index.ts`) Every Weavetab plugin exports a default plugin definition created with `definePlugin` from `@weavetab/sdk`: ```typescript import { definePlugin, createTool, z } from "@weavetab/sdk"; const extractHeadings = createTool({ name: "extract_headings", description: "Extracts all H1-H3 headings from the active browser tab.", inputSchema: z.object({ maxItems: z.number().int().min(1).max(100).default(25), }), handler: async (args, ctx) => { const headings = await ctx.cdp.evaluate(` Array.from(document.querySelectorAll('h1, h2, h3')) .slice(0, ${args.maxItems}) .map(el => el.textContent?.trim() || '') .filter(Boolean) `); return { count: headings.length, headings }; }, }); export default definePlugin({ name: "weavetab-plugin-headings", version: "1.0.0", description: "Fast heading extraction tool for Weavetab MCP.", permissions: { cdp: { evaluate: true, reason: "Reads H1-H3 text nodes from the active tab." }, }, tools: [extractHeadings], }); ``` ## 3. Plugin Context API (`ctx` passed to `handler(args, ctx)`) - `ctx.cdp.evaluate(expression: string): Promise` — Evaluates JavaScript in the active browser tab. - `ctx.cdp.send(method: string, params?: Record): Promise` — Sends a raw Chrome DevTools Protocol command (e.g. `Page.captureScreenshot`, `DOM.getDocument`, `Network.enable`). - `ctx.cdp.navigate(url: string): Promise` — Navigates the active tab. - `ctx.storage.get(key: string): Promise` — Reads plugin-scoped persistent JSON state (`~/.weavetab/plugin-storage/`). - `ctx.storage.set(key: string, value: T): Promise` — Writes plugin-scoped persistent JSON state. - `ctx.storage.delete(key: string): Promise` — Deletes a key from plugin storage. - `ctx.logger.info(msg)` / `ctx.logger.warn(msg)` / `ctx.logger.error(msg)` — Structured diagnostic logging. ## 4. Required `weavetab.json` Manifest (at package root) Auto-generate from your TypeScript entry with `npx weavetab-sdk manifest`, or create `weavetab.json` at the package root: ```json { "$schema": "https://weavetab.dev/schema/plugin.json", "name": "weavetab-plugin-headings", "displayName": "Heading Extractor", "version": "1.0.0", "description": "Fast heading extraction tool for Weavetab MCP.", "main": "dist/index.js", "engines": { "weavetab": ">=2.5.0", "node": ">=20.0.0" }, "permissions": { "cdp": { "evaluate": true, "reason": "Reads H1-H3 text nodes from the active tab." } }, "tools": [ { "name": "extract_headings", "description": "Extracts all H1-H3 headings from the active browser tab." } ] } ``` ## 5. Required `package.json` Fields for Marketplace Discovery To appear automatically on `https://weavetab.dev/discover`: 1. Include `"weavetab-plugin"` in `keywords`. 2. Include `"weavetab.json"` and `"dist"` in `files`. 3. Declare `"@weavetab/sdk": "^2.6.0"` in `dependencies` or `peerDependencies`. ## 6. Unit Testing with `PluginTestHarness` (`test/plugin.test.mjs`) ```javascript import test from "node:test"; import assert from "node:assert/strict"; import { PluginTestHarness } from "@weavetab/sdk"; import plugin from "../dist/index.js"; test("extract_headings returns headings from mocked CDP", async () => { const harness = new PluginTestHarness(plugin, { evaluateHandler: async () => ["Welcome", "Features"], }); const res = await harness.invokeTool("extract_headings", { maxItems: 10 }); assert.equal(res.count, 2); assert.deepEqual(res.headings, ["Welcome", "Features"]); }); ```