Build, embed, integrate
Everything you need to publish tools, embed them anywhere, and ship integrations.
Concepts
MiniToolkit has four primitives:
- Tool — a JSON document describing a form, a system prompt, a user prompt template, and a price. Tools live either as files in the seed pack or as user-published rows in the database.
- Run — an execution of a tool with concrete input. Charges credits, produces text output, may accrue earnings to the tool's author.
- Credit — the unit of consumption. 1 credit ≈ $0.10 at retail. Tools cost 1–5 credits per run.
- Surface — where a tool runs from: the website, an embed, an API call, a Slack command, an MCP agent, the browser extension. All surfaces share the same tool definitions and accounting.
Authentication
Programmatic access uses API keys. Mint one at /me/api. Format: mtk_ followed by 48 hex chars. Show-once-only — copy it immediately, the server stores only a SHA-256 hash.
Pass the key in either of these headers:
Authorization: Bearer mtk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
X-MTK-API-Key: mtk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Web sessions use mt_sid HttpOnly cookies via magic-link sign-in — no password, no OAuth, no setup beyond clicking an email link.
HTTP API
Base URL: https://app.minitoolkits.com
Run a tool
POST /api/run/{slug}
Submit form fields as application/x-www-form-urlencoded. Returns an HTML fragment containing a <pre id="raw-output"> with the model output. The HTML is what the website itself uses; programmatic clients should parse it or strip tags.
curl -X POST https://app.minitoolkits.com/api/run/cold-email-subjects \
-H "Authorization: Bearer mtk_..." \
-d "pitch=we help DTC brands cut returns by 30%" \
-d "tone=direct"
Response codes:
| 200 | Success — body is HTML fragment with the result. |
| 400 | Validation failed (missing required field, exceeds max_chars). Credits refunded automatically. |
| 402 | Insufficient credits or anonymous and limit reached. |
| 404 | Tool not found. |
| 429 | Rate limit hit. |
| 500 | Model call failed. Credits refunded. |
List your favorite tools
GET /api/me/favorites
curl https://app.minitoolkits.com/api/me/favorites \
-H "Authorization: Bearer mtk_..."
Returns:
{
"favorites": [
{
"slug": "apology-email",
"title": "Apology Email",
"tagline": "Three drafts calibrated to severity.",
"icon": "🙏",
"category": "Writing",
"price_credits": 3,
"inputs": [...]
}
]
}
Get a tool definition (no auth)
GET /api/tools/{slug}
Public endpoint. Returns the form schema for a tool — used by the embed widget.
List a creator's tools (no auth)
GET /api/users/{handle}/tools
Returns a creator's public, embed-enabled tools.
MCP server
MiniToolkit speaks Model Context Protocol over HTTP, so every public tool is callable from any MCP-compatible agent: Claude Desktop, Cursor, Cline, Goose, etc.
Add to Claude Desktop / Cursor
Edit claude_desktop_config.json (or your MCP client's equivalent):
{
"mcpServers": {
"minitoolkit": {
"type": "http",
"url": "https://app.minitoolkits.com/mcp",
"headers": {
"Authorization": "Bearer mtk_..."
}
}
}
}
Restart the agent. Your tools appear in the tool picker. The agent can pick the right tool dynamically based on what the user is doing.
Manual JSON-RPC
POST JSON-RPC 2.0 requests to /mcp. Three methods are implemented:
initialize
{"jsonrpc":"2.0","id":1,"method":"initialize",
"params":{"protocolVersion":"2024-11-05","capabilities":{}}}
tools/list
{"jsonrpc":"2.0","id":2,"method":"tools/list"}
tools/call
{"jsonrpc":"2.0","id":3,"method":"tools/call",
"params":{
"name":"apology-email",
"arguments":{"situation":"...","severity":"moderate (real impact)","relationship":"a client"}
}}
Each call debits credits the same as a web run. Owner-runs are free. Author share accrues normally.
Web Component embed
Drop tools into any HTML — blog, Substack, Notion, Webflow, your own product. No iframe, no CSS leak, themeable.
Single tool
<script src="https://app.minitoolkits.com/widget.js" defer></script>
<mtk-tool slug="apology-email" theme="auto"></mtk-tool>
Multi-tool shelf
<mtk-shelf creator="chabli" theme="auto"></mtk-shelf>
<!-- or explicit list -->
<mtk-shelf tools="apology-email,vendor-negotiation,meeting-multiplexer"></mtk-shelf>
Theme
The theme attribute can be auto (follows the host's color scheme), light, or dark (default). Override individual properties with CSS custom properties:
mtk-tool {
--mtk-bg: #fffaf0;
--mtk-fg: #1a1a1a;
--mtk-brand: #ff6b35;
--mtk-radius: 6px;
}
Payment modes
Each of your tools has an embed_payment_mode set on its embed page (/me/tools/{id}/embed):
- sponsor — your embed budget pays. Best for marketing.
- visitor_pays — embed shows a sign-in CTA; runs charge the visitor's wallet.
- tip_jar — free for everyone, optional tip post-run (coming soon).
Set per-tool daily caps to bound spend. The widget shows a "Try it on MiniToolkit" CTA when the budget is empty or capped.
Browser extension
Source lives in /extension/ in the project repo. Manifest V3, works in Chrome, Edge, and Firefox.
Install (development)
- Visit
chrome://extensions, enable Developer mode. - Click Load unpacked and pick the
extension/directory. - Click the toolbar icon → Settings → paste an API key from /me/api.
Use
- Toolbar popup: list of your pinned tools with inline runner.
- Right-click on any selected text → MiniToolkit → pick a pinned tool. Result is copied to clipboard.
Customize
The extension is a thin wrapper over the public API. To fork or rebrand: edit API_BASE in background.js, popup.js, options.js; update manifest.json, swap the icons, ship.
Slack integration
Slash commands and modal-based forms — your tools available everywhere your team types.
Setup (workspace admin)
- Create a Slack app at api.slack.com/apps → "From scratch".
- Slash Commands →
/mtk→ request URLhttps://app.minitoolkits.com/slack/commands. - Interactivity & Shortcuts → enable → request URL
https://app.minitoolkits.com/slack/interactivity. - OAuth & Permissions → redirect URL
https://app.minitoolkits.com/slack/oauth/callback. Bot scopes:commands,users:read,users:read.email,chat:write. - Copy Client ID, Client Secret, and Signing Secret into your server's
.envasSLACK_CLIENT_ID,SLACK_CLIENT_SECRET,SLACK_SIGNING_SECRET. - Visit
https://app.minitoolkits.com/slack/installto install in your workspace.
Use
/mtkalone → tool picker modal./mtk apology-email I missed the demo deadline→ opens the apology form pre-filled with that text.- Form submit → result is DM'd to the user.
Each Slack user is auto-linked to a MiniToolkit account using their Slack profile email on first use. They get the standard 20 free credits. Subsequent runs charge that wallet.
Tool JSON schema
Tools are JSON documents. Whether stored as files in app/tools/ or in the database, the structure is the same.
{
"slug": "kebab-case-id", // unique within marketplace
"title": "Tool Title", // short, ≤45 chars
"tagline": "Single-line sales pitch.", // ≤80 chars
"category": "Writing", // freeform
"icon": "✏️", // single emoji
"featured": 8, // sort weight (higher = higher)
"visibility": "public", // "public" or "draft"
"inputs": [
{
"name": "snake_case", // matches {{name}} in user_prompt_template
"label": "Form label",
"type": "text" | "textarea" | "select",
"required": true,
"max_chars": 2000,
"placeholder": "example value",
"options": ["a", "b"], // select only
"default": "a" // select only
}
],
"system_prompt": "You are…", // model persona + style rules
"user_prompt_template": "Input: {{name}}",// {{var}} placeholders
"model": "claude-haiku-4-5", // or claude-sonnet-4-6
"max_output_tokens": 800, // 50–4000
"price_credits": 3 // 0–20
}
Writing system prompts that work
Patterns that consistently produce sharp output:
- Address the model in second person. "You are an SEO specialist…" beats "Act as an SEO specialist…".
- Name what to AVOID, specifically. "You never use the words 'leverage', 'unlock', or 'opportunity'." A list of forbidden phrases beats vague directions.
- Hard rules with reasons. "Each subject line ≤50 characters because mobile inboxes truncate at 60." The model respects rules better when given the reason.
- Format the output explicitly in your
user_prompt_template— model follows headings and structure better than paragraphs. - Length scales pricing. 200 tokens out → 1 credit. 600 → 2. 1200 → 3. 1800 → 4. 2500 → 5.
Validation
Server-side, every input is validated before the model is called:
- Required fields must be non-empty.
max_charsenforced server-side (browsermaxlengthis advisory).selectvalues must be inoptions.- Validation failures return 400 and refund any debited credit.
The tool generator
The fastest way to build a tool is to describe it. /me/new takes a one-sentence description and returns a complete tool JSON, ready to publish.
Behind the scenes: Sonnet 4.6 with a meta-prompt that knows our schema, picks reasonable inputs, writes an opinionated system prompt, and clamps the price/length. The generated tool is saved as a draft owned by you.
You'll always want to review and tighten the generated prompt — Sonnet is good, but a tool you've actually used yourself will produce better results than a one-shot draft. Edit at /me/tools/{id}/edit.
Design tips
- Keep inputs to 1–4. More than that and the form feels heavy. Don't ask for things the model can infer.
- Format placeholders with realistic examples. They're scanned by the user before they type — concrete examples set expectations.
- Pick the model. Use Haiku 4.5 by default — fast, cheap, smart enough for focused tasks. Use Sonnet 4.6 only when the tool genuinely needs deeper reasoning (multi-step structure, ambiguous input).
Earnings & payouts
You earn 70% of every credit-paying run on tools you own. 1 credit = $0.10, so a 3-credit run gives you $0.21.
Track your earnings
See the running total at /me/payouts. Detail per run in the earnings_ledger — exposed via the JSON API at /api/me/earnings (coming soon).
Get paid
Connect a payout method via Stripe Connect Express on /me/payouts. Stripe handles KYC, tax forms, and country support. We never touch your bank details.
Once your account is active and your unpaid balance crosses $10, the weekly payout cron sends a Stripe Transfer to your connected account. Each payout creates a row in payouts and an offsetting entry in earnings_ledger so the running balance reflects post-payout state.
Rate limits & quotas
| Surface | Limit |
|---|---|
| Anonymous web | 20 runs / IP / hour |
| Anonymous embed | 5 runs / IP / tool / hour |
| Authenticated | No hard rate limit; bounded by credit balance |
| Embed (sponsor mode) | Per-tool daily cap, set by tool owner (default $10) |
| MCP / API key | No hard rate limit; bounded by credit balance |
Hitting a limit returns HTTP 429 with a human-readable message in the body.
Errors
Standard HTTP status codes:
| 200 | Success. |
| 204 | Success, no body (CORS preflight, MCP notifications). |
| 302 / 303 | Redirect. Used after form submissions and OAuth flows. |
| 400 | Bad request — usually invalid input. The body explains what's wrong. |
| 401 | Auth required. |
| 402 | Payment required — out of credits. |
| 403 | Forbidden (rare — usually scope or ownership). |
| 404 | Tool / user / resource not found. |
| 429 | Rate limited. |
| 500 | Server error. We log every 500. Credits are refunded automatically when the model call is the cause. |
| 503 | Required external service (DB / Stripe / Resend / Slack) is not configured. |
MCP error codes
Per JSON-RPC 2.0:
| -32601 | Method not found. |
| -32602 | Invalid params (validation failure on tool inputs). |
| -32603 | Internal error (model call failed). |
| -32000 | Insufficient credits. |
| -32001 | Authentication required. |
Questions?
For setup help: support@minitoolkits.com. For API issues: include the request/response and your API key prefix (first 12 chars), never the full key.