Connect your agent to the GTM team.
ChiefLab onboarding should feel like service activation, not enterprise setup: connect the agent, send repo context, approve the first GTM plan, then connect channels only when the launch needs them.
Fast path: install in Cursor, say launch this, let the agent collect repo context, then approve the launch room ChiefLab returns. Or get a key upfront if you'd rather skip agent-first signup.
⚡ One-click install
Hosted MCP works today at https://api.chieflab.io/api/mcp. Your agent mints a key on first call via chieflab_signup_workspace and writes it into your MCP config — no browser round-trip. CLI live on npm as @chieflab/cli.
Pick your agent runtime.
Three runtimes support arbitrary MCP servers today. ChiefLab installs into all three with the same hosted endpoint.
Cursor
One-click MCP install. Native agent + repo context.
Claude Desktop & Code
Add to claude_desktop_config.json or ~/.claude.json. Restart, done.
Codex
OpenAI Codex MCP plugin. JSON snippet → restart → launch this.
On a different runtime (Node, Python, Telegram, voice, LangChain, custom SDK)? Hit https://api.chieflab.io/api/mcp directly. See all runtimes →
Service activation flow
- Connect agent. Cursor, Claude, Codex, hosted MCP, or direct HTTPS.
- Connect product brain. Agent passes productUrl plus repoContext: what changed, files, routes, README, pricing, screenshots, ICP.
- Choose first outcome. Launch product, announce feature, send launch email, publish social, or measure what happened.
- Approve plan. Human opens the signed reviewUrl and approves only the actions they want to execute.
- Connect channels just-in-time. ChiefLab asks for Zernio, Resend, GA4, Search Console, or CMS only when the launch needs it.
Pick your runtime
Hosted MCP — Live path today. Call the hosted JSON-RPC/MCP endpoint directly from any agent runtime or server. · HTTPS POST
# Live hosted MCP endpoint. No npm package required.
curl -X POST https://api.chieflab.io/api/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
# To call launch tools, include a ChiefLab key:
curl -X POST https://api.chieflab.io/api/mcp \
-H "Authorization: Bearer $CHIEFLAB_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0", "id": 1, "method": "tools/call",
"params": {
"name": "chiefmo_launch_product",
"arguments": {
"productUrl": "https://yoursite.com",
"goal": "Get our first 100 users"
}
}
}' Cursor — Native MCP support + one-click install deeplink. 60-second setup via Settings → MCP, ~/.cursor/mcp.json, or the cursor:// install button. · MCP (hosted url or stdio)
// ~/.cursor/mcp.json
{
"mcpServers": {
"chieflab": {
"url": "https://api.chieflab.io/api/mcp",
"headers": {
"Authorization": "Bearer clp_dev_..."
}
}
}
}
// Restart Cursor. In any chat after building something:
// "launch this" / "get users" / "market this" / "announce this" / "post this"
// Cursor's agent picks chiefmo_launch_product automatically, gathers
// repo context (commits, files, routes, README), and returns a launch pack. Claude Desktop — Native MCP support. Add to claude_desktop_config.json, restart, done. · MCP (hosted url or stdio)
// macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
// Windows: %APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"chieflab": {
"url": "https://api.chieflab.io/api/mcp",
"headers": {
"Authorization": "Bearer clp_dev_..."
}
}
}
}
// Quit Claude Desktop fully and reopen. ChiefLab tools appear in the
// input area. Ask: "Use ChiefMO to launch this product." Node script / web app — Plain fetch. No MCP client required. Drop into any Node service, Next.js route, edge function. · HTTPS POST
// Node 20+ (built-in fetch)
const r = await fetch("https://api.chieflab.io/api/mcp", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.CHIEFLAB_API_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
jsonrpc: "2.0", id: 1, method: "tools/call",
params: {
name: "chiefmo_launch_product",
arguments: {
productUrl: "https://yoursite.com",
goal: "Get our first 100 users",
channels: ["linkedin", "x", "product_hunt", "email", "landing_hero"],
tenantId: "acme-co"
}
}
})
});
const { result } = await r.json();
const payload = JSON.parse(result.content[0].text);
// payload.launchPack.channels — per-channel drafting briefs your LLM renders
// payload.publishActions[] — approval-gated; fire executorTool after approval
// payload.reviewUrl — surface to user for approval (HMAC-signed, no login) Python — httpx / requests. Drop into any FastAPI, Flask, LangChain, LlamaIndex, Pydantic AI agent. · HTTPS POST
import os, json, httpx
r = httpx.post(
"https://api.chieflab.io/api/mcp",
headers={"Authorization": f"Bearer {os.environ['CHIEFLAB_API_KEY']}"},
json={
"jsonrpc": "2.0", "id": 1, "method": "tools/call",
"params": {
"name": "chiefmo_launch_product",
"arguments": {
"productUrl": "https://yoursite.com",
"goal": "Get our first 100 users",
"channels": ["linkedin", "x", "product_hunt", "email", "landing_hero"],
"tenantId": "acme-co"
}
}
},
timeout=60.0
)
payload = json.loads(r.json()["result"]["content"][0]["text"])
# payload["launchPack"]["channels"] — per-channel briefs your LLM renders
# payload["publishActions"] — approval-gated; fire executorTool after approval
# payload["reviewUrl"] — surface to user (HMAC-signed, no login) Telegram bot — Inside your webhook handler, fetch the endpoint. Use chat ID as tenantId for per-user context. · HTTPS POST
// inside your Telegram bot webhook handler
import { Telegraf } from "telegraf";
const bot = new Telegraf(process.env.TELEGRAM_TOKEN);
bot.command("launch", async (ctx) => {
// ctx.message.text comes in like "/launch https://acme.co Get our first 100 users"
const [, productUrl, ...goalParts] = ctx.message.text.split(/s+/);
const r = await fetch("https://api.chieflab.io/api/mcp", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.CHIEFLAB_API_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
jsonrpc: "2.0", id: 1, method: "tools/call",
params: {
name: "chiefmo_launch_product",
arguments: {
productUrl,
goal: goalParts.join(" ") || "Get our first users",
channels: ["linkedin", "x", "product_hunt", "email"],
// Per-user context: each Telegram user is a tenant
tenantId: `tg-${ctx.from.id}`
}
}
})
});
const { result } = await r.json();
const payload = JSON.parse(result.content[0].text);
// Surface the reviewUrl — user clicks, approves, agent fires executors
await ctx.reply(`Launch staged. Approve here: ${payload.reviewUrl}`);
}); Vapi / voice agents — Register ChiefLab as a function call. Vapi runtime hits the endpoint; your voice agent's LLM speaks the rendered output back. · HTTPS POST (function call)
// Vapi function definition (in your assistant config)
{
"name": "chiefmo_launch_product",
"description": "Plan and queue a product launch end-to-end. Use when the caller has just shipped a product and asks to launch it / get users / market it / announce it / post about it.",
"parameters": {
"type": "object",
"properties": {
"productUrl": { "type": "string" },
"goal": { "type": "string" },
"tenantId": { "type": "string", "description": "Use the caller's phone number" }
},
"required": ["productUrl"]
},
"server": {
"url": "https://api.chieflab.io/api/mcp",
"headers": { "Authorization": "Bearer YOUR_CHIEFLAB_KEY" },
"method": "POST"
}
}
// The Vapi runtime translates a function call into a JSON-RPC call to
// chieflab.io/api/mcp. The voice agent's LLM (Vapi → OpenAI/Anthropic)
// reads the launchPack briefs and speaks the rendered marketing back
// to the caller, then SMSs them the reviewUrl for approval. LangChain / LangGraph — Wrap as a Tool. The agent's LLM gets a brief, renders the final output. · HTTPS POST
from langchain.tools import Tool
import httpx, json, os
def chiefmo_launch(query: str) -> str:
"""Plan and queue a product launch. Input format: '<productUrl> | <goal>'."""
parts = [s.strip() for s in query.split("|", 1)]
product_url = parts[0]
goal = parts[1] if len(parts) > 1 else "Get our first users"
r = httpx.post(
"https://api.chieflab.io/api/mcp",
headers={"Authorization": f"Bearer {os.environ['CHIEFLAB_API_KEY']}"},
json={
"jsonrpc": "2.0", "id": 1, "method": "tools/call",
"params": {
"name": "chiefmo_launch_product",
"arguments": {
"productUrl": product_url,
"goal": goal,
"channels": ["linkedin", "x", "product_hunt", "email", "landing_hero"]
}
}
}
)
payload = json.loads(r.json()["result"]["content"][0]["text"])
channels = payload["launchPack"]["channels"]
briefs = "\n\n---\n\n".join(channels[k]["body"] for k in channels)
return f"REVIEW URL: {payload['reviewUrl']}\n\n{briefs}"
chiefmo_tool = Tool(
name="chiefmo_launch_product",
description="Plan and queue a product launch end-to-end. Use after the user ships something and says 'launch this' / 'get users' / 'market this' / 'announce this' / 'post this'. Returns per-channel briefs + signed reviewUrl.",
func=chiefmo_launch
)
# Add chiefmo_tool to any LangChain / LangGraph agent. The agent's LLM
# renders each brief into final copy — no extra ChiefLab server-side LLM cost. Custom agent / SDK — OpenClaw, Hermes, Manus, Devin, Replit Agent, your own SDK — anything with HTTPS works. · HTTPS POST
Same shape as the others — POST JSON-RPC with a Bearer token. See the Node example as a starting point.
What you get back
Every chiefmo_launch_product call returns:
- launchPack — positioning, per-channel assets, repo evidence, connector readiness, and measurement plan.
- reviewUrl — signed, no-login approval room your human opens to review, edit, approve, or reject.
- publishActions[] — proposed external actions (publish, send, manual fallback) with approval requirements.
- groundingEvidence + genericityRisk — proof of what repo facts were used and whether the launch reads generic.
- agentProofLine + launchValue — the sentence an agent can say to justify why this is more than a chat draft.
- generatedImages[] — hosted images or image briefs, depending on requested mode and credits.
- trackingPlan — what ChiefLab measures after launch and which next tool/action to run.
Want ChiefLab to write server-side instead of returning briefs for your agent's LLM? Pass outputMode: "full" — premium credits, slower, but you don't need a strong calling model.
Install the after-build hook
Add repo instructions so Cursor, Claude Code, Codex, Windsurf, Cline, and other coding agents know to call ChiefLab when the user says "launch this" or "get users" after build.
# Writes AGENTS.md, Cursor rule, Claude command, Codex note, and MCP config stub
npx @chieflab/cli init
# hosted fallback: macOS / Linux / Git Bash
curl -fsSL https://chieflab.io/install-agent-hook.mjs | node -
# hosted fallback: Windows PowerShell
iwr https://chieflab.io/install-agent-hook.mjs -OutFile .chieflab-install-agent-hook.mjs; node .\.chieflab-install-agent-hook.mjs Static files: AGENTS.md, Cursor rule, Claude command, Codex instruction, and MCP config.
Verify your install works
One copy-paste command confirms the hosted endpoint is reachable and the tool catalog is intact. Drop this in any post-install hook.
# Required: a ChiefLab key (any prefix — clp_dev_, clp_test_, clp_live_)
export CHIEFLAB_API_KEY=clp_dev_...
# One-shot — checks initialize, tools/list, and the wedge tool name
curl -fsSL https://chieflab.io/install-verify.mjs | node -
# Or, with a real launch against your product URL
curl -fsSL https://chieflab.io/install-verify.mjs | \
node - --launch=yoursite.com Exit code 0 on success, non-zero with a clear message otherwise. Source: scripts/install-verify.mjs in the public repo. No secrets sent anywhere except chieflab.io/api/mcp; all output is local.
Each per-runtime install page (Cursor, Claude Desktop, Codex) ends with this same verification step — so an "install" is only "verified" once this script exits 0.
Multi-tenant: serving your own customers
If your agent serves multiple end-users, register each as a tenant:
chieflab_create_tenant({
tenantId: "acme-co",
name: "Acme Co",
domain: "acme.co"
})
chieflab_set_tenant_context({
tenantId: "acme-co",
brand: "Acme Co",
audience: "B2B SaaS founders",
voice: "Direct, founder-led, no jargon"
}) Then call chiefmo_launch_product with tenantId: "acme-co" and ChiefLab grounds every launch against that tenant's context. One workspace can serve thousands of tenants.