toolcapsule 0.1.0-alpha.11 → 0.1.0-alpha.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts","../src/mcp/client.ts","../src/mcp/importer.ts","../src/utils/fs.ts","../src/profile.ts","../src/schema/brief.ts","../src/schema/summarize.ts","../src/skill/generator.ts","../src/skill/installer.ts","../src/runs/recorder.ts","../src/utils/tokens.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { cac } from \"cac\";\nimport pc from \"picocolors\";\nimport type { ProfileConfig } from \"./types.js\";\nimport { McpClient } from \"./mcp/client.js\";\nimport { discoverMcpServers, selectImportedServers } from \"./mcp/importer.js\";\nimport { loadProfile } from \"./profile.js\";\nimport { briefTools } from \"./schema/brief.js\";\nimport { summarizeTool, summarizeTools } from \"./schema/summarize.js\";\nimport { defaultSkillTarget, generateSkill, type SkillTarget, writeProfile } from \"./skill/generator.js\";\nimport { installAgentSkill } from \"./skill/installer.js\";\nimport { createRunId, loadRun, saveRun } from \"./runs/recorder.js\";\nimport { writeFile } from \"node:fs/promises\";\nimport { ensureToolCapsuleIgnored, readJson } from \"./utils/fs.js\";\nimport { percentReduction, roughTokens } from \"./utils/tokens.js\";\n\nconst cli = cac(\"toolcapsule\");\n\nasync function readPackageVersion(): Promise<string> {\n try {\n const pkg = JSON.parse(await readFile(new URL(\"../package.json\", import.meta.url), \"utf8\")) as { version?: string };\n return pkg.version || \"0.0.0\";\n } catch {\n return \"0.0.0\";\n }\n}\n\nconst packageVersion = await readPackageVersion();\n\nasync function withClient<T>(profile: ProfileConfig, fn: (client: McpClient) => Promise<T>): Promise<T> {\n const client = new McpClient(profile, { clientVersion: packageVersion });\n try {\n await client.init();\n return await fn(client);\n } finally {\n await client.close();\n }\n}\n\nfunction readArgsPath(raw: string): string {\n return raw.startsWith(\"@\") ? raw.slice(1) : raw;\n}\n\nfunction readSkillTarget(raw: string | undefined): SkillTarget {\n const target = raw || defaultSkillTarget;\n if ([\"copilot\", \"claude\", \"opencode\", \"agents\", \"all\"].includes(target)) return target as SkillTarget;\n throw new Error(\"Invalid --target. Use one of: copilot, claude, opencode, agents, all\");\n}\n\nfunction runBaseDir(profileName: string): string {\n return join(\".toolcapsule\", \"runs\", profileName);\n}\n\ncli\n .command(\"init <name>\", \"Create a profile and generated Agent Skill for an MCP server\")\n .option(\"--url <url>\", \"Remote MCP URL\")\n .option(\"--command <command>\", \"stdio MCP command\")\n .option(\"--arg <arg>\", \"stdio MCP argument, repeatable\", { type: [String] })\n .option(\"--output <dir>\", \"Skill output directory\")\n .option(\"--target <target>\", \"Skill target: copilot, claude, opencode, agents, all\", { default: defaultSkillTarget })\n .action(async (name: string, options: { url?: string; command?: string; arg?: string[]; output?: string; target?: string }) => {\n if (!options.url && !options.command) throw new Error(\"Provide --url for remote MCP or --command for stdio MCP\");\n const profile: ProfileConfig = options.url\n ? { name, transport: { type: \"remote\", url: options.url } }\n : { name, transport: { type: \"stdio\", command: options.command!, args: options.arg ?? [] } };\n await ensureToolCapsuleIgnored();\n await writeProfile(join(\".toolcapsule\", \"profiles\", `${name}.json`), profile);\n const out = await generateSkill(profile, options.output ? { outputDir: options.output } : { target: readSkillTarget(options.target) });\n console.log(pc.green(`Created profile and skill at ${out}`));\n });\n\ncli\n .command(\"install-skill\", \"Install the generic ToolCapsule Agent Skill into this workspace\")\n .option(\"--output <dir>\", \"Skill output directory\")\n .option(\"--target <target>\", \"Skill target: copilot, claude, opencode, agents, all\", { default: defaultSkillTarget })\n .action(async (options: { output?: string; target?: string }) => {\n const out = await installAgentSkill(options.output, readSkillTarget(options.target));\n console.log(pc.green(`Installed ToolCapsule Agent Skill at ${out}`));\n });\n\ncli\n .command(\"import\", \"Import existing MCP configuration into ToolCapsule profiles and skills\")\n .option(\"--include-user\", \"Also inspect user-level MCP config files\")\n .option(\"--name <name>\", \"Import only one MCP server by name\")\n .option(\"--all\", \"Import all discovered MCP servers\")\n .option(\"--target <target>\", \"Skill target: copilot, claude, opencode, agents, all\", { default: defaultSkillTarget })\n .option(\"--dry-run\", \"List importable MCP servers without writing files\")\n .action(\n async (options: { includeUser?: boolean; name?: string; all?: boolean; target?: string; dryRun?: boolean }) => {\n const discovered = await discoverMcpServers(options.includeUser ? { includeUser: true } : {});\n if (discovered.length === 0) {\n console.log(\"No importable MCP servers found.\");\n return;\n }\n\n if (options.dryRun) {\n for (const server of discovered) {\n console.log(`${server.name}\\t${server.source.tool}\\t${server.source.path}`);\n for (const warning of server.warnings) console.log(pc.yellow(` warning: ${warning}`));\n }\n return;\n }\n\n const selected = selectImportedServers(discovered, options.name, options.all);\n if (selected.length === 0) {\n throw new Error(\"Multiple MCP servers found. Re-run with --dry-run, then pass --name <server> or --all.\");\n }\n\n for (const server of selected) {\n await ensureToolCapsuleIgnored();\n await writeProfile(join(\".toolcapsule\", \"profiles\", `${server.profile.name}.json`), server.profile);\n const out = await generateSkill(server.profile, { target: readSkillTarget(options.target) });\n console.log(pc.green(`Imported ${server.name} from ${server.source.path} -> ${out}`));\n for (const warning of server.warnings) console.log(pc.yellow(` warning: ${warning}`));\n }\n },\n );\n\ncli\n .command(\"tools <profile>\", \"List MCP tools\")\n .option(\"--brief\", \"Print compact tool summaries\")\n .option(\"--names\", \"Print tool names only\")\n .option(\"--json\", \"Print raw JSON\")\n .action(async (profileName: string, options: { brief?: boolean; names?: boolean; json?: boolean }) => {\n const profile = await loadProfile(profileName);\n const result = await withClient(profile, (client) => client.listTools());\n if (options.json) console.log(JSON.stringify(result, null, 2));\n else if (options.names) console.log(result.tools.map((tool) => tool.name).join(\"\\n\"));\n else console.log(briefTools(result.tools));\n });\n\ncli\n .command(\"describe <profile> <tool>\", \"Describe one MCP tool\")\n .option(\"--brief\", \"Print summarized schema instead of raw schema\")\n .action(async (profileName: string, toolName: string, options: { brief?: boolean }) => {\n const profile = await loadProfile(profileName);\n const result = await withClient(profile, (client) => client.listTools());\n const tool = result.tools.find((item) => item.name === toolName);\n if (!tool) throw new Error(`Tool not found: ${toolName}`);\n console.log(JSON.stringify(options.brief ? summarizeTool(tool) : tool, null, 2));\n });\n\ncli.command(\"schema <profile> <tool>\", \"Print a compact schema for one MCP tool\").action(async (profileName: string, toolName: string) => {\n const profile = await loadProfile(profileName);\n const result = await withClient(profile, (client) => client.listTools());\n const tool = result.tools.find((item) => item.name === toolName);\n if (!tool) throw new Error(`Tool not found: ${toolName}`);\n console.log(JSON.stringify(summarizeTool(tool), null, 2));\n});\n\ncli\n .command(\"call <profile> <tool> <args>\", \"Call an MCP tool with JSON args or @args.json\")\n .option(\"--save-run\", \"Save request, response, and command under .toolcapsule/runs/<profile>/\")\n .action(async (profileName: string, toolName: string, argsRaw: string, options: { saveRun?: boolean }) => {\n const argsPath = readArgsPath(argsRaw);\n const toolArgs = argsRaw.startsWith(\"@\") ? await readJson(argsPath) : JSON.parse(argsRaw);\n const profile = await loadProfile(profileName);\n const request = { name: toolName, arguments: toolArgs };\n const command = `toolcapsule call ${profileName} ${toolName} ${argsRaw}`;\n const runId = createRunId();\n try {\n const response = await withClient(profile, (client) => client.callTool(toolName, toolArgs));\n console.log(JSON.stringify(response, null, 2));\n if (options.saveRun) {\n await ensureToolCapsuleIgnored();\n const dir = await saveRun(runBaseDir(profile.name), {\n id: runId,\n createdAt: new Date().toISOString(),\n profile: profile.name,\n tool: toolName,\n argsFile: argsPath,\n status: \"success\",\n command,\n request,\n response,\n });\n console.error(pc.green(`Saved run: ${dir}`));\n }\n } catch (error) {\n if (options.saveRun) {\n await ensureToolCapsuleIgnored();\n const dir = await saveRun(runBaseDir(profile.name), {\n id: runId,\n createdAt: new Date().toISOString(),\n profile: profile.name,\n tool: toolName,\n argsFile: argsPath,\n status: \"error\",\n command,\n request,\n error: error instanceof Error ? error.message : String(error),\n });\n console.error(pc.yellow(`Saved failed run: ${dir}`));\n }\n throw error;\n }\n });\n\ncli.command(\"retry <runDir>\", \"Retry a saved run, re-reading the args file\").action(async (runDir: string) => {\n const run = await loadRun(runDir);\n const toolArgs = await readJson(run.argsFile);\n const profile = await loadProfile(run.profile);\n const response = await withClient(profile, (client) => client.callTool(run.tool, toolArgs));\n console.log(JSON.stringify(response, null, 2));\n});\n\ncli.command(\"summarize <profile>\", \"Summarize all tools into compact JSON\").action(async (profileName: string) => {\n const profile = await loadProfile(profileName);\n const result = await withClient(profile, (client) => client.listTools());\n console.log(JSON.stringify(summarizeTools(result.tools), null, 2));\n});\n\ncli\n .command(\"benchmark <profile>\", \"Estimate schema savings for a profile\")\n .option(\"--markdown\", \"Print a Markdown report\")\n .option(\"--out <file>\", \"Write report to a file\")\n .action(async (profileName: string, options: { markdown?: boolean; out?: string }) => {\n const profile = await loadProfile(profileName);\n const result = await withClient(profile, (client) => client.listTools());\n const nativeTokens = roughTokens(result);\n const brief = summarizeTools(result.tools);\n const briefTokens = roughTokens(brief);\n const summary = {\n profile: profileName,\n tools: result.tools.length,\n nativeToolsRoughTokens: nativeTokens,\n summarizedToolsRoughTokens: briefTokens,\n estimatedReductionPct: Number(percentReduction(nativeTokens, briefTokens).toFixed(2)),\n };\n const output = options.markdown\n ? `# ToolCapsule benchmark: ${profileName}\\n\\n| Metric | Value |\\n|---|---:|\\n| MCP tools | ${summary.tools} |\\n| Native MCP schema rough tokens | ${summary.nativeToolsRoughTokens} |\\n| ToolCapsule summary rough tokens | ${summary.summarizedToolsRoughTokens} |\\n| Estimated reduction | ${summary.estimatedReductionPct}% |\\n\\n> Rough tokens are estimated from serialized schema length. Use this report to compare schema footprint before and after capsule summaries.\\n`\n : JSON.stringify(summary, null, 2);\n if (options.out) await writeFile(options.out, output);\n console.log(output);\n});\n\ncli.command(\"render-readme\", \"Print website hero copy snippets\").action(async () => {\n console.log(await readFile(new URL(\"../docs/hero-copy.md\", import.meta.url), \"utf8\"));\n});\n\ncli.help();\ncli.version(packageVersion);\n\ntry {\n cli.parse();\n} catch (error) {\n console.error(pc.red(error instanceof Error ? error.message : String(error)));\n process.exit(1);\n}\n","import { spawn, type ChildProcessWithoutNullStreams } from \"node:child_process\";\nimport { once } from \"node:events\";\nimport { resolve } from \"node:path\";\nimport type { JsonRpcMessage, ProfileConfig, ToolsListResult } from \"../types.js\";\n\nexport type McpClientOptions = {\n timeoutMs?: number;\n debug?: boolean;\n clientVersion?: string;\n};\n\nexport class McpClient {\n private child: ChildProcessWithoutNullStreams;\n private nextId = 1;\n private buffer = \"\";\n private pending = new Map<\n number,\n { resolve: (value: JsonRpcMessage) => void; reject: (error: Error) => void }\n >();\n private timeoutMs: number;\n private debug: boolean;\n private clientVersion: string;\n\n constructor(profile: ProfileConfig, opts: McpClientOptions = {}) {\n this.timeoutMs = opts.timeoutMs ?? Number(process.env.TOOLCAPSULE_TIMEOUT_MS || \"45000\");\n this.debug = opts.debug ?? process.env.TOOLCAPSULE_DEBUG === \"1\";\n this.clientVersion = opts.clientVersion ?? \"0.0.0\";\n if (profile.transport.type === \"remote\") {\n this.child = spawn(\"npx\", [\"-y\", \"mcp-remote\", profile.transport.url, ...headersToArgs(profile.transport.headers)], {\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n env: { ...process.env, ...profile.transport.env },\n });\n } else {\n this.child = spawn(profile.transport.command, profile.transport.args ?? [], {\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n env: { ...process.env, ...profile.transport.env },\n cwd: profile.transport.cwd ? resolve(profile.transport.cwd) : undefined,\n });\n }\n this.child.stdout.setEncoding(\"utf8\");\n this.child.stdout.on(\"data\", (chunk: string) => this.onStdout(chunk));\n this.child.stderr.on(\"data\", (chunk: Buffer) => this.onStderr(chunk));\n this.child.on(\"exit\", (code, signal) => {\n const error = new Error(`MCP process exited early (code=${code}, signal=${signal})`);\n for (const waiter of this.pending.values()) waiter.reject(error);\n this.pending.clear();\n });\n }\n\n private onStderr(chunk: Buffer): void {\n if (!this.debug) return;\n process.stderr.write(redactSecrets(chunk.toString(\"utf8\")));\n }\n\n private onStdout(chunk: string): void {\n this.buffer += chunk;\n let newlineIndex: number;\n while ((newlineIndex = this.buffer.indexOf(\"\\n\")) >= 0) {\n const line = this.buffer.slice(0, newlineIndex).trim();\n this.buffer = this.buffer.slice(newlineIndex + 1);\n if (!line) continue;\n let message: JsonRpcMessage;\n try {\n message = JSON.parse(line) as JsonRpcMessage;\n } catch {\n process.stderr.write(`${line}\\n`);\n continue;\n }\n if (typeof message.id === \"number\") {\n const waiter = this.pending.get(message.id);\n if (waiter) {\n this.pending.delete(message.id);\n waiter.resolve(message);\n }\n }\n }\n }\n\n async init(): Promise<void> {\n await this.request(\"initialize\", {\n protocolVersion: \"2025-03-26\",\n capabilities: {},\n clientInfo: { name: \"toolcapsule\", version: this.clientVersion },\n });\n this.notify(\"notifications/initialized\", {});\n }\n\n async request(method: string, params?: unknown): Promise<unknown> {\n const id = this.nextId++;\n const responsePromise = new Promise<JsonRpcMessage>((resolve, reject) => {\n this.pending.set(id, { resolve, reject });\n });\n this.child.stdin.write(`${JSON.stringify({ jsonrpc: \"2.0\", id, method, params })}\\n`);\n const response = await this.withTimeout(responsePromise, method);\n if (response.error) throw new Error(`${method} failed: ${JSON.stringify(response.error, null, 2)}`);\n return response.result;\n }\n\n notify(method: string, params?: unknown): void {\n this.child.stdin.write(`${JSON.stringify({ jsonrpc: \"2.0\", method, params })}\\n`);\n }\n\n async listTools(): Promise<ToolsListResult> {\n return (await this.request(\"tools/list\", {})) as ToolsListResult;\n }\n\n async callTool(name: string, args: unknown): Promise<unknown> {\n return await this.request(\"tools/call\", { name, arguments: args });\n }\n\n async close(): Promise<void> {\n if (!this.child.killed) this.child.kill();\n if (this.child.exitCode === null) await Promise.race([once(this.child, \"exit\"), new Promise((resolve) => setTimeout(resolve, 500))]);\n }\n\n private async withTimeout<T>(promise: Promise<T>, label: string): Promise<T> {\n let timer: NodeJS.Timeout | undefined;\n const timeout = new Promise<never>((_, reject) => {\n timer = setTimeout(() => reject(new Error(`${label} timed out after ${this.timeoutMs}ms`)), this.timeoutMs);\n });\n try {\n return await Promise.race([promise, timeout]);\n } finally {\n if (timer) clearTimeout(timer);\n }\n }\n}\n\nfunction headersToArgs(headers: Record<string, string> | undefined): string[] {\n if (!headers) return [];\n return Object.entries(headers).flatMap(([key, value]) => [\"--header\", `${key}:${value}`]);\n}\n\nfunction redactSecrets(text: string): string {\n return text\n .replace(/https:\\/\\/mcp\\.feishu\\.cn\\/mcp\\/[^\\s\"']+/g, \"https://mcp.feishu.cn/mcp/[redacted]\")\n .replace(/(Bearer\\s+)[A-Za-z0-9._~+/=-]+/gi, \"$1[redacted]\")\n .replace(/(token=)[^\\s&\"']+/gi, \"$1[redacted]\")\n .replace(/(api[_-]?key=)[^\\s&\"']+/gi, \"$1[redacted]\");\n}\n","import { existsSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport type { ProfileConfig, TransportConfig } from \"../types.js\";\nimport { readJson } from \"../utils/fs.js\";\n\nexport type McpConfigSource = {\n tool: \"vscode\" | \"claude\" | \"opencode\" | \"gemini\" | \"cursor\" | \"generic\";\n path: string;\n userLevel?: boolean;\n};\n\nexport type ImportedMcpServer = {\n name: string;\n source: McpConfigSource;\n profile: ProfileConfig;\n warnings: string[];\n};\n\ntype ServerRecord = Record<string, unknown>;\n\nconst workspaceSources: McpConfigSource[] = [\n { tool: \"vscode\", path: join(\".vscode\", \"mcp.json\") },\n { tool: \"claude\", path: \".mcp.json\" },\n { tool: \"opencode\", path: \"opencode.json\" },\n { tool: \"gemini\", path: join(\".gemini\", \"settings.json\") },\n { tool: \"cursor\", path: join(\".cursor\", \"mcp.json\") },\n];\n\nconst userSources: McpConfigSource[] = [\n { tool: \"claude\", path: join(homedir(), \".claude.json\"), userLevel: true },\n { tool: \"opencode\", path: join(homedir(), \".config\", \"opencode\", \"opencode.json\"), userLevel: true },\n { tool: \"gemini\", path: join(homedir(), \".gemini\", \"settings.json\"), userLevel: true },\n];\n\nfunction asRecord(value: unknown): ServerRecord | undefined {\n return value && typeof value === \"object\" && !Array.isArray(value) ? (value as ServerRecord) : undefined;\n}\n\nfunction stringArray(value: unknown): string[] | undefined {\n return Array.isArray(value) && value.every((item) => typeof item === \"string\") ? value : undefined;\n}\n\nfunction stringRecord(value: unknown): Record<string, string> | undefined {\n const record = asRecord(value);\n if (!record) return undefined;\n const entries = Object.entries(record).filter((entry): entry is [string, string] => typeof entry[1] === \"string\");\n return entries.length > 0 ? Object.fromEntries(entries) : undefined;\n}\n\nfunction cleanName(name: string): string {\n const cleaned = name\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .replace(/-{2,}/g, \"-\");\n return cleaned || \"imported-mcp\";\n}\n\nfunction mapServer(name: string, source: McpConfigSource, raw: unknown): ImportedMcpServer | undefined {\n const server = asRecord(raw);\n if (!server) return undefined;\n\n const warnings: string[] = [];\n let transport: TransportConfig | undefined;\n const type = typeof server.type === \"string\" ? server.type : undefined;\n const url = typeof server.url === \"string\" ? server.url : typeof server.httpUrl === \"string\" ? server.httpUrl : undefined;\n const commandValue = server.command;\n const headers = stringRecord(server.headers);\n const env = stringRecord(server.env) ?? stringRecord(server.environment);\n const cwd = typeof server.cwd === \"string\" ? server.cwd : undefined;\n\n if (url && (!type || [\"http\", \"streamable-http\", \"remote\", \"sse\", \"ws\"].includes(type))) {\n transport = { type: \"remote\", url, ...(headers ? { headers } : {}), ...(env ? { env } : {}) };\n if (type === \"sse\" || type === \"ws\") warnings.push(`Imported ${type} server as remote URL; verify transport compatibility.`);\n } else if (typeof commandValue === \"string\") {\n transport = {\n type: \"stdio\",\n command: commandValue,\n args: stringArray(server.args) ?? [],\n ...(env ? { env } : {}),\n ...(cwd ? { cwd } : {}),\n };\n } else if (Array.isArray(commandValue) && commandValue.every((item) => typeof item === \"string\") && commandValue.length > 0) {\n transport = { type: \"stdio\", command: commandValue[0]!, args: commandValue.slice(1), ...(env ? { env } : {}), ...(cwd ? { cwd } : {}) };\n }\n\n if (!transport) return undefined;\n if (server.headers && !headers) warnings.push(\"Headers were present but not copied because they were not string values.\");\n if ((server.env || server.environment) && !env) warnings.push(\"Environment variables were present but not copied because they were not string values.\");\n if (server.includeTools || server.excludeTools) warnings.push(\"Tool include/exclude filters were not copied; use ToolCapsule brief/schema commands to choose tools manually.\");\n\n const profileName = cleanName(name);\n return {\n name: profileName,\n source,\n warnings,\n profile: {\n name: profileName,\n transport,\n },\n };\n}\n\nfunction serverEntries(source: McpConfigSource, config: ServerRecord): Array<[string, unknown]> {\n if (source.tool === \"vscode\" || source.tool === \"cursor\") return Object.entries(asRecord(config.servers) ?? {});\n if (source.tool === \"opencode\") return Object.entries(asRecord(config.mcp) ?? {});\n if (source.tool === \"claude\") {\n const projectEntries = Object.entries(asRecord(config.mcpServers) ?? {});\n const projectConfigs = Object.entries(asRecord(config.projects) ?? {}).flatMap(([, project]) =>\n Object.entries(asRecord(asRecord(project)?.mcpServers) ?? {}),\n );\n return [...projectEntries, ...projectConfigs];\n }\n return Object.entries(asRecord(config.mcpServers) ?? {});\n}\n\nexport async function discoverMcpServers(opts: { includeUser?: boolean } = {}): Promise<ImportedMcpServer[]> {\n const sources = opts.includeUser ? [...workspaceSources, ...userSources] : workspaceSources;\n const discovered: ImportedMcpServer[] = [];\n\n for (const source of sources) {\n if (!existsSync(source.path)) continue;\n const config = asRecord(await readJson(source.path));\n if (!config) continue;\n for (const [name, raw] of serverEntries(source, config)) {\n const imported = mapServer(name, source, raw);\n if (imported) discovered.push(imported);\n }\n }\n\n return discovered;\n}\n\nexport function selectImportedServers(servers: ImportedMcpServer[], name?: string, all?: boolean): ImportedMcpServer[] {\n if (all) return servers;\n if (!name) return servers.length === 1 ? servers : [];\n const normalized = cleanName(name);\n return servers.filter((server) => server.name === normalized || server.name === name);\n}\n","import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname, resolve } from \"node:path\";\n\nexport async function readJson<T>(path: string): Promise<T> {\n return JSON.parse(await readFile(path, \"utf8\")) as T;\n}\n\nexport async function writeJson(path: string, value: unknown): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, `${JSON.stringify(value, null, 2)}\\n`);\n}\n\nexport async function writeText(path: string, value: string): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, value);\n}\n\nexport async function ensureToolCapsuleIgnored(): Promise<void> {\n const gitignorePath = \".gitignore\";\n const entry = \".toolcapsule/\";\n let content = \"\";\n try {\n content = await readFile(gitignorePath, \"utf8\");\n } catch (error) {\n if (!(error instanceof Error && \"code\" in error && error.code === \"ENOENT\")) throw error;\n }\n\n const lines = content.split(/\\r?\\n/).map((line) => line.trim());\n const alreadyIgnored = lines.some((line) => line === entry || line === `/${entry}` || line === \".toolcapsule\");\n if (alreadyIgnored) return;\n\n const prefix = content.length > 0 && !content.endsWith(\"\\n\") ? \"\\n\" : \"\";\n await writeFile(gitignorePath, `${content}${prefix}${entry}\\n`);\n}\n\nexport function abs(path: string): string {\n return resolve(process.cwd(), path);\n}\n","import { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { z } from \"zod\";\nimport type { ProfileConfig } from \"./types.js\";\nimport { readJson } from \"./utils/fs.js\";\n\nconst profileSchema = z.object({\n name: z.string().min(1),\n transport: z.union([\n z.object({\n type: z.literal(\"remote\"),\n url: z.string().url(),\n headers: z.record(z.string()).optional(),\n env: z.record(z.string()).optional(),\n }),\n z.object({\n type: z.literal(\"stdio\"),\n command: z.string().min(1),\n args: z.array(z.string()).optional(),\n env: z.record(z.string()).optional(),\n cwd: z.string().optional(),\n }),\n ]),\n skill: z\n .object({\n name: z.string().optional(),\n description: z.string().optional(),\n })\n .optional(),\n shortcuts: z\n .record(\n z.object({\n tool: z.string(),\n description: z.string().optional(),\n args: z.record(z.enum([\"string\", \"file\", \"json\", \"boolean\", \"number\"])).optional(),\n }),\n )\n .optional(),\n});\n\nexport async function loadProfile(profilePathOrName: string): Promise<ProfileConfig> {\n const candidates = [\n profilePathOrName,\n `${profilePathOrName}.json`,\n join(\".toolcapsule\", \"profiles\", `${profilePathOrName}.json`),\n join(\".github\", \"skills\", `${profilePathOrName}-mcp`, \"toolcapsule.config.json\"),\n ];\n const found = candidates.find((path) => existsSync(path));\n if (!found) throw new Error(`Profile not found: ${profilePathOrName}`);\n return profileSchema.parse(await readJson(found)) as ProfileConfig;\n}\n","import type { McpTool } from \"../types.js\";\n\nexport function toolTitle(tool: McpTool): string {\n return tool.annotations?.title || tool.description?.split(/\\n/)[0]?.slice(0, 100) || tool.name;\n}\n\nexport function briefTool(tool: McpTool): string {\n const schema = tool.inputSchema as any;\n const required = Array.isArray(schema?.required) ? schema.required : [];\n const properties = schema?.properties && typeof schema.properties === \"object\" ? Object.keys(schema.properties) : [];\n const flags = [\n tool.annotations?.readOnlyHint ? \"read-only\" : undefined,\n tool.annotations?.destructiveHint ? \"destructive\" : undefined,\n ].filter(Boolean);\n return `- ${tool.name}: ${toolTitle(tool)}${flags.length ? ` [${flags.join(\", \")}]` : \"\"}${required.length ? ` required=${required.join(\"|\")}` : \"\"}${properties.length ? ` args=${properties.slice(0, 12).join(\"|\")}` : \"\"}`;\n}\n\nexport function briefTools(tools: McpTool[]): string {\n return tools.map(briefTool).join(\"\\n\");\n}\n","import type { McpTool } from \"../types.js\";\n\nexport function summarizeTool(tool: McpTool): unknown {\n const schema = tool.inputSchema as any;\n const properties = schema?.properties && typeof schema.properties === \"object\" ? schema.properties : {};\n return {\n name: tool.name,\n title: tool.annotations?.title,\n description: tool.description?.split(/\\n\\n/)[0]?.slice(0, 500),\n annotations: tool.annotations,\n required: Array.isArray(schema?.required) ? schema.required : [],\n arguments: Object.fromEntries(\n Object.entries(properties).map(([key, value]: [string, any]) => [\n key,\n { type: value?.type, enum: value?.enum, description: value?.description?.slice?.(0, 160) },\n ]),\n ),\n };\n}\n\nexport function summarizeTools(tools: McpTool[]): unknown[] {\n return tools.map(summarizeTool);\n}\n","import { mkdir, writeFile } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\nimport Handlebars from \"handlebars\";\nimport type { ProfileConfig } from \"../types.js\";\nimport { writeJson } from \"../utils/fs.js\";\n\nexport type SkillTarget = \"copilot\" | \"claude\" | \"opencode\" | \"agents\" | \"all\";\n\nexport const defaultSkillTarget: SkillTarget = \"claude\";\n\nexport function skillOutputDir(skillName: string, target: Exclude<SkillTarget, \"all\">): string {\n if (target === \"copilot\") return join(\".github\", \"skills\", skillName);\n if (target === \"claude\") return join(\".claude\", \"skills\", skillName);\n if (target === \"opencode\") return join(\".opencode\", \"skills\", skillName);\n return join(\".agents\", \"skills\", skillName);\n}\n\nexport function expandSkillTargets(target: SkillTarget): Exclude<SkillTarget, \"all\">[] {\n return target === \"all\" ? [\"copilot\", \"claude\", \"opencode\", \"agents\"] : [target];\n}\n\nconst skillTemplate = `---\nname: {{skillName}}\ndescription: '{{description}}'\nargument-hint: 'MCP task, tool name, or args file to run'\n---\n\n# {{title}}\n\nThis skill wraps an MCP server as a lightweight, lazy-loaded, file-first workflow.\n\n## Why use this skill\n\n- Keep full MCP tool schemas out of the model context until needed.\n- Use brief tool summaries for everyday work.\n- Store large payloads in local files such as \\`args.json\\` or \\`content.md\\`.\n- Patch local artifacts and retry failed calls deterministically.\n\n## Commands\n\n\\`\\`\\`bash\ntoolcapsule tools {{profileName}} --brief\ntoolcapsule describe {{profileName}} <tool>\ntoolcapsule call {{profileName}} <tool> @args.json\ntoolcapsule retry .toolcapsule/runs/{{profileName}}/<run-id>\n\\`\\`\\`\n\n## Workflow\n\n1. Use \\`tools --brief\\` to find the likely tool.\n2. Use \\`describe <tool>\\` only when the brief schema is insufficient.\n3. Put complex arguments in a local JSON file.\n4. Call with \\`@args.json\\` and save the run.\n5. On failure, patch the local file and run \\`retry\\`.\n\n## Safety\n\n- Do not fabricate IDs, URLs, user IDs, or opaque tokens.\n- Prefer local files for large payloads.\n- Do not print secrets.\n- Review destructive tools before calling.\n`;\n\nexport type GenerateSkillOptions = {\n outputDir?: string;\n target?: SkillTarget;\n};\n\nasync function generateSkillAt(profile: ProfileConfig, outputDir: string): Promise<string> {\n const skillName = profile.skill?.name || `${profile.name}-mcp`;\n await mkdir(join(outputDir, \"scripts\"), { recursive: true });\n\n const template = Handlebars.compile(skillTemplate);\n const description =\n profile.skill?.description ||\n `Use when operating tools from the ${profile.name} MCP server. Lazy-load schemas, call tools through local files, and retry failed calls by patching artifacts.`;\n const markdown = template({\n skillName,\n profileName: profile.name,\n title: `${profile.name} MCP Skill`,\n description: description.replace(/'/g, \"''\"),\n });\n await writeFile(join(outputDir, \"SKILL.md\"), markdown);\n await writeJson(join(outputDir, \"toolcapsule.config.json\"), profile);\n await writeFile(\n join(outputDir, \"scripts\", \"README.md\"),\n `# Scripts\\n\\nThis skill uses the project-level \\`toolcapsule\\` CLI.\\n`,\n );\n return outputDir;\n}\n\nexport async function generateSkill(profile: ProfileConfig, opts: GenerateSkillOptions = {}): Promise<string> {\n const skillName = profile.skill?.name || `${profile.name}-mcp`;\n const target = opts.target || defaultSkillTarget;\n const outputs = opts.outputDir\n ? [await generateSkillAt(profile, opts.outputDir)]\n : await Promise.all(expandSkillTargets(target).map((item) => generateSkillAt(profile, skillOutputDir(skillName, item))));\n return outputs.join(\", \");\n}\n\nexport async function writeProfile(path: string, profile: ProfileConfig): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n await writeJson(path, profile);\n}\n","import { mkdir, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { defaultSkillTarget, expandSkillTargets, skillOutputDir, type SkillTarget } from \"./generator.js\";\n\nconst agentSkill = `---\nname: toolcapsule\ndescription: 'Use when: converting MCP servers into lightweight Agent Skills, installing ToolCapsule, lazy-loading MCP schemas, calling MCP tools through local args files, or using patch-and-retry workflows for heavy MCP tools.'\nargument-hint: 'MCP server URL/command, tool name, args file, or retry task'\n---\n\n# ToolCapsule Agent Skill\n\nUse ToolCapsule when an agent needs to work with heavy MCP servers without carrying every tool schema in the prompt.\n\n## Install\n\nIf \\`toolcapsule\\` or \\`tcap\\` is missing:\n\n\\`\\`\\`bash\nnpm install -g toolcapsule\n\\`\\`\\`\n\n## Core workflow\n\n1. Initialize a profile and generated Skill:\n\n\\`\\`\\`bash\ntcap init <name> --url <remote-mcp-url>\n# or\ntcap init <name> --command <stdio-command> --arg <arg>\n\\`\\`\\`\n\n2. Discover tools briefly:\n\n\\`\\`\\`bash\ntcap tools <name> --brief\n\\`\\`\\`\n\n3. Inspect one tool only when needed:\n\n\\`\\`\\`bash\ntcap schema <name> <tool>\n\\`\\`\\`\n\n4. Put complex arguments in a local JSON file.\n\n5. Call the MCP tool through the local args file:\n\n\\`\\`\\`bash\ntcap call <name> <tool> @args.json --save-run\n\\`\\`\\`\n\n6. If the call fails, patch the local file and retry:\n\n\\`\\`\\`bash\ntcap retry .toolcapsule/runs/<name>/<run-id>\n\\`\\`\\`\n\n## Safety\n\n- Do not print or commit private MCP URLs, tokens, API keys, user IDs, or document IDs.\n- Keep generated profiles and run artifacts local unless reviewed.\n- Use \\`TOOLCAPSULE_DEBUG=1\\` only when debugging; normal transport logs are quiet by default.\n- Prefer \\`--brief\\` and \\`schema\\` before reading full MCP schemas.\n\n## When to use\n\nUse ToolCapsule for MCP servers with:\n\n- many tools;\n- long schemas;\n- large Markdown/JSON payloads;\n- document, ticket, wiki, dashboard, or batch workflows;\n- failures that benefit from patching local artifacts instead of regenerating a full tool call.\n`;\n\nexport async function installAgentSkill(outputDir?: string, target: SkillTarget = defaultSkillTarget): Promise<string> {\n const outputDirs = outputDir ? [outputDir] : expandSkillTargets(target).map((item) => skillOutputDir(\"toolcapsule\", item));\n await Promise.all(\n outputDirs.map(async (dir) => {\n await mkdir(dir, { recursive: true });\n await writeFile(join(dir, \"SKILL.md\"), agentSkill);\n }),\n );\n return outputDirs.join(\", \");\n}\n","import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type { RunRecord } from \"../types.js\";\nimport { writeJson } from \"../utils/fs.js\";\n\nexport function createRunId(): string {\n return new Date().toISOString().replace(/[:.]/g, \"-\");\n}\n\nexport async function saveRun(baseDir: string, record: RunRecord): Promise<string> {\n const dir = join(baseDir, record.id);\n await mkdir(dir, { recursive: true });\n await writeJson(join(dir, \"run.json\"), record);\n await writeJson(join(dir, \"request.json\"), record.request);\n if (record.response !== undefined) await writeJson(join(dir, \"response.json\"), record.response);\n if (record.error) await writeFile(join(dir, \"error.txt\"), record.error);\n await writeFile(join(dir, \"command.txt\"), `${record.command}\\n`);\n return dir;\n}\n\nexport async function loadRun(runDir: string): Promise<RunRecord> {\n return JSON.parse(await readFile(join(runDir, \"run.json\"), \"utf8\")) as RunRecord;\n}\n","export function roughTokens(value: unknown): number {\n const text = typeof value === \"string\" ? value : JSON.stringify(value);\n return Math.ceil(text.length / 4);\n}\n\nexport function percentReduction(before: number, after: number): number {\n return before === 0 ? 0 : ((before - after) / before) * 100;\n}\n"],"mappings":"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","names":["readFile","join","resolve","resolve","existsSync","join","join","existsSync","mkdir","writeFile","dirname","join","join","mkdir","writeFile","dirname","mkdir","writeFile","join","mkdir","writeFile","join","mkdir","readFile","writeFile","join","join","mkdir","writeFile","readFile","writeFile","readFile","join","writeFile"]}
1
+ {"version":3,"sources":["../src/cli.ts","../src/mcp/inventory.ts","../src/mcp/importer.ts","../src/utils/fs.ts","../src/paths.ts","../src/mcp/client.ts","../src/profile.ts","../src/schema/brief.ts","../src/schema/summarize.ts","../src/skill/generator.ts","../src/skill/installer.ts","../src/runs/recorder.ts","../src/utils/tokens.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { readFile } from \"node:fs/promises\";\nimport { cac } from \"cac\";\nimport pc from \"picocolors\";\nimport type { ProfileConfig, SnapshotProfileConfig } from \"./types.js\";\nimport { disableNativeMcp, disableToolCapsuleProfile, formatInventory, listMcpInventory } from \"./mcp/inventory.js\";\nimport { McpClient } from \"./mcp/client.js\";\nimport { discoverMcpServers, linkedProfileForImportedServer, selectImportedServers } from \"./mcp/importer.js\";\nimport { userProfilePath, workspaceProfilePath, workspaceRunBaseDir } from \"./paths.js\";\nimport { loadProfile } from \"./profile.js\";\nimport { briefTools } from \"./schema/brief.js\";\nimport { summarizeTool, summarizeTools } from \"./schema/summarize.js\";\nimport { defaultSkillTarget, fetchProfileTools, generateSkill, type SkillTarget, writeProfile } from \"./skill/generator.js\";\nimport { installAgentSkill } from \"./skill/installer.js\";\nimport { createRunId, loadRun, saveRun } from \"./runs/recorder.js\";\nimport { writeFile } from \"node:fs/promises\";\nimport { ensureToolCapsuleIgnored, readJson } from \"./utils/fs.js\";\nimport { percentReduction, roughTokens } from \"./utils/tokens.js\";\n\nconst cli = cac(\"toolcapsule\");\n\nasync function readPackageVersion(): Promise<string> {\n try {\n const pkg = JSON.parse(await readFile(new URL(\"../package.json\", import.meta.url), \"utf8\")) as { version?: string };\n return pkg.version || \"0.0.0\";\n } catch {\n return \"0.0.0\";\n }\n}\n\nconst packageVersion = await readPackageVersion();\n\nasync function withClient<T>(profile: SnapshotProfileConfig, fn: (client: McpClient) => Promise<T>): Promise<T> {\n const client = new McpClient(profile, { clientVersion: packageVersion });\n try {\n await client.init();\n return await fn(client);\n } finally {\n await client.close();\n }\n}\n\nfunction readArgsPath(raw: string): string {\n return raw.startsWith(\"@\") ? raw.slice(1) : raw;\n}\n\nfunction readSkillTarget(raw: string | undefined): SkillTarget {\n const target = raw || defaultSkillTarget;\n if ([\"copilot\", \"claude\", \"opencode\", \"agents\", \"all\"].includes(target)) return target as SkillTarget;\n throw new Error(\"Invalid --target. Use one of: copilot, claude, opencode, agents, all\");\n}\n\nfunction renameSnapshotProfile(profile: SnapshotProfileConfig, name: string): SnapshotProfileConfig {\n return { ...profile, name };\n}\n\nasync function writeImportedServer(\n server: Awaited<ReturnType<typeof discoverMcpServers>>[number],\n opts: { as?: string | undefined; local?: boolean | undefined; copy?: boolean | undefined; target?: string | undefined },\n): Promise<void> {\n const profileName = opts.as || server.name;\n const local = opts.local === true;\n const copy = opts.copy === true;\n const profilePath = local ? workspaceProfilePath(profileName) : userProfilePath(profileName);\n if (local) await ensureToolCapsuleIgnored();\n const profile = copy ? renameSnapshotProfile(server.profile, profileName) : linkedProfileForImportedServer(server, profileName);\n await writeProfile(profilePath, profile);\n const tools = await fetchProfileTools(renameSnapshotProfile(server.profile, profileName), { clientVersion: packageVersion });\n const skillOptions = { target: readSkillTarget(opts.target), embedProfile: local, ...(tools ? { tools } : {}) };\n const out = await generateSkill(profile, skillOptions);\n const mode = copy ? \"snapshot\" : \"linked\";\n console.log(pc.green(`Imported ${server.name} as ${profileName} from ${server.source.path} -> ${profilePath} (${mode}), ${out}`));\n for (const warning of server.warnings) console.log(pc.yellow(` warning: ${warning}`));\n}\n\ncli\n .command(\"init <name>\", \"Create a profile and generated Agent Skill for an MCP server\")\n .option(\"--url <url>\", \"Remote MCP URL\")\n .option(\"--command <command>\", \"stdio MCP command\")\n .option(\"--arg <arg>\", \"stdio MCP argument, repeatable\", { type: [String] })\n .option(\"--output <dir>\", \"Skill output directory\")\n .option(\"--target <target>\", \"Skill target: copilot, claude, opencode, agents, all\", { default: defaultSkillTarget })\n .option(\"--local\", \"Store the MCP profile in this workspace instead of ~/.toolcapsule\")\n .action(async (name: string, options: { url?: string; command?: string; arg?: string[]; output?: string; target?: string; local?: boolean }) => {\n if (!options.url && !options.command) throw new Error(\"Provide --url for remote MCP or --command for stdio MCP\");\n const local = options.local === true;\n const profile: ProfileConfig = options.url\n ? { name, transport: { type: \"remote\", url: options.url } }\n : { name, transport: { type: \"stdio\", command: options.command!, args: options.arg ?? [] } };\n const profilePath = local ? workspaceProfilePath(name) : userProfilePath(name);\n if (local) await ensureToolCapsuleIgnored();\n await writeProfile(profilePath, profile);\n const tools = await fetchProfileTools(profile, { clientVersion: packageVersion });\n const skillOptions = options.output\n ? { outputDir: options.output, embedProfile: local, ...(tools ? { tools } : {}) }\n : { target: readSkillTarget(options.target), embedProfile: local, ...(tools ? { tools } : {}) };\n const out = await generateSkill(\n profile,\n skillOptions,\n );\n console.log(pc.green(`Created profile at ${profilePath} and skill at ${out}`));\n });\n\ncli\n .command(\"install-skill\", \"Install the generic ToolCapsule Agent Skill into this workspace\")\n .option(\"--output <dir>\", \"Skill output directory\")\n .option(\"--target <target>\", \"Skill target: copilot, claude, opencode, agents, all\", { default: defaultSkillTarget })\n .action(async (options: { output?: string; target?: string }) => {\n const out = await installAgentSkill(options.output, readSkillTarget(options.target));\n console.log(pc.green(`Installed ToolCapsule Agent Skill at ${out}`));\n });\n\ncli\n .command(\"import\", \"Import existing MCP configuration into ToolCapsule profiles and skills\")\n .option(\"--include-user\", \"Also inspect user-level MCP config files\")\n .option(\"--name <name>\", \"Import only one MCP server by name\")\n .option(\"--as <name>\", \"Store the imported server under a different ToolCapsule profile name\")\n .option(\"--all\", \"Import all discovered MCP servers\")\n .option(\"--target <target>\", \"Skill target: copilot, claude, opencode, agents, all\", { default: defaultSkillTarget })\n .option(\"--local\", \"Store imported MCP profiles in this workspace instead of ~/.toolcapsule\")\n .option(\"--copy\", \"Copy MCP transport details into a ToolCapsule snapshot instead of linking the source config\")\n .option(\"--dry-run\", \"List importable MCP servers without writing files\")\n .action(\n async (options: { includeUser?: boolean; name?: string; as?: string; all?: boolean; target?: string; local?: boolean; copy?: boolean; dryRun?: boolean }) => {\n const local = options.local === true;\n const copy = options.copy === true;\n const discovered = await discoverMcpServers(options.includeUser ? { includeUser: true } : {});\n if (discovered.length === 0) {\n console.log(\"No importable MCP servers found.\");\n return;\n }\n\n if (options.dryRun) {\n for (const server of discovered) {\n console.log(`${server.name}\\t${server.source.tool}\\t${server.source.path}`);\n for (const warning of server.warnings) console.log(pc.yellow(` warning: ${warning}`));\n }\n return;\n }\n\n const selected = selectImportedServers(discovered, options.name, options.all);\n if (selected.length === 0) {\n throw new Error(\"Multiple MCP servers found. Re-run with --dry-run, then pass --name <server> or --all.\");\n }\n\n for (const server of selected) {\n await writeImportedServer(server, { as: options.as, local, copy, target: options.target });\n }\n },\n );\n\ncli\n .command(\"mcp <action> [name]\", \"List, enable, or disable MCP servers\")\n .option(\"--include-user\", \"Also inspect user-level MCP config files\")\n .option(\"--json\", \"Print JSON output for list\")\n .option(\"--as <name>\", \"Store an enabled server under a different ToolCapsule profile name\")\n .option(\"--target <target>\", \"Skill target: copilot, claude, opencode, agents, all\", { default: defaultSkillTarget })\n .option(\"--local\", \"Store ToolCapsule profile in this workspace\")\n .option(\"--copy\", \"Copy MCP transport details into a ToolCapsule snapshot instead of linking source config\")\n .option(\"--native\", \"For disable: disable the native MCP config instead of the ToolCapsule profile\")\n .option(\"--yes\", \"Apply native disable changes; otherwise native disable is dry-run\")\n .action(async (action: string, name: string | undefined, options: { includeUser?: boolean; json?: boolean; as?: string; target?: string; local?: boolean; copy?: boolean; native?: boolean; yes?: boolean }) => {\n if (action === \"list\") {\n const items = await listMcpInventory(options.includeUser ? { includeUser: true } : {});\n console.log(options.json ? JSON.stringify(items, null, 2) : formatInventory(items));\n return;\n }\n if (action === \"enable\") {\n if (!name) throw new Error(\"Usage: tcap mcp enable <server> [--as <profile>]\");\n const discovered = await discoverMcpServers(options.includeUser ? { includeUser: true } : {});\n const selected = selectImportedServers(discovered, name, false);\n if (selected.length !== 1) throw new Error(`Expected one MCP server named ${name}; run tcap mcp list --include-user first.`);\n await writeImportedServer(selected[0]!, { as: options.as, local: options.local, copy: options.copy, target: options.target });\n return;\n }\n if (action === \"disable\") {\n if (!name) throw new Error(\"Usage: tcap mcp disable <profile|server>\");\n const message = options.native\n ? await disableNativeMcp(name, { ...(options.includeUser ? { includeUser: true } : {}), dryRun: options.yes !== true })\n : await disableToolCapsuleProfile(name);\n console.log(message);\n return;\n }\n throw new Error(\"Unknown mcp action. Use: list, enable, disable\");\n });\n\ncli\n .command(\"tools <profile>\", \"List MCP tools\")\n .option(\"--brief\", \"Print compact tool summaries\")\n .option(\"--names\", \"Print tool names only\")\n .option(\"--json\", \"Print raw JSON\")\n .action(async (profileName: string, options: { brief?: boolean; names?: boolean; json?: boolean }) => {\n const profile = await loadProfile(profileName);\n const result = await withClient(profile, (client) => client.listTools());\n if (options.json) console.log(JSON.stringify(result, null, 2));\n else if (options.names) console.log(result.tools.map((tool) => tool.name).join(\"\\n\"));\n else console.log(briefTools(result.tools));\n });\n\ncli\n .command(\"describe <profile> <tool>\", \"Describe one MCP tool\")\n .option(\"--brief\", \"Print summarized schema instead of raw schema\")\n .action(async (profileName: string, toolName: string, options: { brief?: boolean }) => {\n const profile = await loadProfile(profileName);\n const result = await withClient(profile, (client) => client.listTools());\n const tool = result.tools.find((item) => item.name === toolName);\n if (!tool) throw new Error(`Tool not found: ${toolName}`);\n console.log(JSON.stringify(options.brief ? summarizeTool(tool) : tool, null, 2));\n });\n\ncli.command(\"schema <profile> <tool>\", \"Print a compact schema for one MCP tool\").action(async (profileName: string, toolName: string) => {\n const profile = await loadProfile(profileName);\n const result = await withClient(profile, (client) => client.listTools());\n const tool = result.tools.find((item) => item.name === toolName);\n if (!tool) throw new Error(`Tool not found: ${toolName}`);\n console.log(JSON.stringify(summarizeTool(tool), null, 2));\n});\n\ncli\n .command(\"call <profile> <tool> <args>\", \"Call an MCP tool with JSON args or @args.json\")\n .option(\"--save-run\", \"Save request, response, and command under .toolcapsule/runs/<profile>/\")\n .action(async (profileName: string, toolName: string, argsRaw: string, options: { saveRun?: boolean }) => {\n const argsPath = readArgsPath(argsRaw);\n const toolArgs = argsRaw.startsWith(\"@\") ? await readJson(argsPath) : JSON.parse(argsRaw);\n const profile = await loadProfile(profileName);\n const request = { name: toolName, arguments: toolArgs };\n const command = `toolcapsule call ${profileName} ${toolName} ${argsRaw}`;\n const runId = createRunId();\n try {\n const response = await withClient(profile, (client) => client.callTool(toolName, toolArgs));\n console.log(JSON.stringify(response, null, 2));\n if (options.saveRun) {\n await ensureToolCapsuleIgnored();\n const dir = await saveRun(workspaceRunBaseDir(profile.name), {\n id: runId,\n createdAt: new Date().toISOString(),\n profile: profile.name,\n tool: toolName,\n argsFile: argsPath,\n status: \"success\",\n command,\n request,\n response,\n });\n console.error(pc.green(`Saved run: ${dir}`));\n }\n } catch (error) {\n if (options.saveRun) {\n await ensureToolCapsuleIgnored();\n const dir = await saveRun(workspaceRunBaseDir(profile.name), {\n id: runId,\n createdAt: new Date().toISOString(),\n profile: profile.name,\n tool: toolName,\n argsFile: argsPath,\n status: \"error\",\n command,\n request,\n error: error instanceof Error ? error.message : String(error),\n });\n console.error(pc.yellow(`Saved failed run: ${dir}`));\n }\n throw error;\n }\n });\n\ncli.command(\"retry <runDir>\", \"Retry a saved run, re-reading the args file\").action(async (runDir: string) => {\n const run = await loadRun(runDir);\n const toolArgs = await readJson(run.argsFile);\n const profile = await loadProfile(run.profile);\n const response = await withClient(profile, (client) => client.callTool(run.tool, toolArgs));\n console.log(JSON.stringify(response, null, 2));\n});\n\ncli.command(\"summarize <profile>\", \"Summarize all tools into compact JSON\").action(async (profileName: string) => {\n const profile = await loadProfile(profileName);\n const result = await withClient(profile, (client) => client.listTools());\n console.log(JSON.stringify(summarizeTools(result.tools), null, 2));\n});\n\ncli\n .command(\"benchmark <profile>\", \"Estimate schema savings for a profile\")\n .option(\"--markdown\", \"Print a Markdown report\")\n .option(\"--out <file>\", \"Write report to a file\")\n .action(async (profileName: string, options: { markdown?: boolean; out?: string }) => {\n const profile = await loadProfile(profileName);\n const result = await withClient(profile, (client) => client.listTools());\n const nativeTokens = roughTokens(result);\n const brief = summarizeTools(result.tools);\n const briefTokens = roughTokens(brief);\n const summary = {\n profile: profileName,\n tools: result.tools.length,\n nativeToolsRoughTokens: nativeTokens,\n summarizedToolsRoughTokens: briefTokens,\n estimatedReductionPct: Number(percentReduction(nativeTokens, briefTokens).toFixed(2)),\n };\n const output = options.markdown\n ? `# ToolCapsule benchmark: ${profileName}\\n\\n| Metric | Value |\\n|---|---:|\\n| MCP tools | ${summary.tools} |\\n| Native MCP schema rough tokens | ${summary.nativeToolsRoughTokens} |\\n| ToolCapsule summary rough tokens | ${summary.summarizedToolsRoughTokens} |\\n| Estimated reduction | ${summary.estimatedReductionPct}% |\\n\\n> Rough tokens are estimated from serialized schema length. Use this report to compare schema footprint before and after capsule summaries.\\n`\n : JSON.stringify(summary, null, 2);\n if (options.out) await writeFile(options.out, output);\n console.log(output);\n});\n\ncli.command(\"render-readme\", \"Print website hero copy snippets\").action(async () => {\n console.log(await readFile(new URL(\"../docs/hero-copy.md\", import.meta.url), \"utf8\"));\n});\n\ncli.help();\ncli.version(packageVersion);\n\ntry {\n cli.parse();\n} catch (error) {\n console.error(pc.red(error instanceof Error ? error.message : String(error)));\n process.exit(1);\n}\n","import { existsSync } from \"node:fs\";\nimport { mkdir, readFile, readdir, rename, writeFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { basename, dirname, join } from \"node:path\";\nimport pc from \"picocolors\";\nimport { discoverMcpServers, type ImportedMcpServer } from \"./importer.js\";\nimport { toolCapsuleHome, workspaceProfilePath } from \"../paths.js\";\nimport type { ProfileConfig } from \"../types.js\";\nimport { readJson, writeJson } from \"../utils/fs.js\";\n\nexport type InventoryItem = {\n name: string;\n status: \"enabled\" | \"disabled\" | \"managed\" | \"error\";\n scope: \"workspace\" | \"user\" | \"managed\";\n source: string;\n mode: \"native\" | \"linked\" | \"snapshot\";\n path: string;\n originalName?: string;\n warnings?: string[];\n};\n\nfunction sourceScope(server: ImportedMcpServer): \"workspace\" | \"user\" | \"managed\" {\n if (server.source.managed) return \"managed\";\n return server.source.userLevel ? \"user\" : \"workspace\";\n}\n\nfunction sourceStatus(server: ImportedMcpServer): \"enabled\" | \"managed\" {\n return server.source.managed ? \"managed\" : \"enabled\";\n}\n\nasync function profileItems(dir: string, scope: \"workspace\" | \"user\"): Promise<InventoryItem[]> {\n if (!existsSync(dir)) return [];\n const entries = await readdir(dir, { withFileTypes: true });\n const items: InventoryItem[] = [];\n for (const entry of entries) {\n if (!entry.isFile() || !entry.name.endsWith(\".json\")) continue;\n const path = join(dir, entry.name);\n try {\n const profile = (await readJson(path)) as ProfileConfig;\n items.push({\n name: profile.name || basename(entry.name, \".json\"),\n status: \"enabled\",\n scope,\n source: \"toolcapsule\",\n mode: profile.kind === \"linked\" ? \"linked\" : \"snapshot\",\n path,\n });\n } catch {\n items.push({ name: basename(entry.name, \".json\"), status: \"error\", scope, source: \"toolcapsule\", mode: \"snapshot\", path });\n }\n }\n return items;\n}\n\nexport async function listMcpInventory(opts: { includeUser?: boolean } = {}): Promise<InventoryItem[]> {\n const nativeServers = await discoverMcpServers(opts.includeUser ? { includeUser: true, includeManaged: true } : {});\n const nativeItems = nativeServers.map((server): InventoryItem => ({\n name: server.name,\n originalName: server.originalName,\n status: sourceStatus(server),\n scope: sourceScope(server),\n source: server.source.tool,\n mode: \"native\",\n path: server.source.path,\n warnings: server.warnings,\n }));\n const workspaceProfiles = await profileItems(join(\".toolcapsule\", \"profiles\"), \"workspace\");\n const userProfiles = await profileItems(join(toolCapsuleHome(), \"profiles\"), \"user\");\n return [...nativeItems, ...workspaceProfiles, ...userProfiles];\n}\n\nfunction colorStatus(status: InventoryItem[\"status\"]): string {\n if (status === \"enabled\") return pc.green(\"● on\");\n if (status === \"disabled\") return pc.gray(\"○ off\");\n if (status === \"managed\") return pc.yellow(\"◆ managed\");\n return pc.red(\"× error\");\n}\n\nfunction colorMode(mode: InventoryItem[\"mode\"]): string {\n if (mode === \"linked\") return pc.cyan(mode);\n if (mode === \"snapshot\") return pc.magenta(mode);\n return pc.gray(mode);\n}\n\nfunction pad(value: string, width: number): string {\n return value.length >= width ? value : `${value}${\" \".repeat(width - value.length)}`;\n}\n\nfunction padDisplay(display: string, raw: string, width: number): string {\n return raw.length >= width ? display : `${display}${\" \".repeat(width - raw.length)}`;\n}\n\nexport function formatInventory(items: InventoryItem[]): string {\n if (items.length === 0) return \"No MCP servers found.\";\n const rows = items.map((item) => ({\n status: colorStatus(item.status),\n statusRaw: item.status === \"enabled\" ? \"● on\" : item.status === \"disabled\" ? \"○ off\" : item.status === \"managed\" ? \"◆ managed\" : \"× error\",\n name: item.originalName && item.originalName !== item.name ? `${item.name} (${item.originalName})` : item.name,\n scope: item.scope,\n source: item.source,\n mode: colorMode(item.mode),\n modeRaw: item.mode,\n path: item.path.replace(`${homedir()}/`, \"~/\"),\n }));\n const widths = {\n status: Math.max(\"STATUS\".length, ...rows.map((row) => row.statusRaw.length)),\n name: Math.max(\"NAME\".length, ...rows.map((row) => row.name.length)),\n scope: Math.max(\"SCOPE\".length, ...rows.map((row) => row.scope.length)),\n source: Math.max(\"SOURCE\".length, ...rows.map((row) => row.source.length)),\n mode: Math.max(\"MODE\".length, ...rows.map((row) => row.modeRaw.length)),\n };\n const lines = [\n `${pad(\"STATUS\", widths.status)} ${pad(\"NAME\", widths.name)} ${pad(\"SCOPE\", widths.scope)} ${pad(\"SOURCE\", widths.source)} ${pad(\"MODE\", widths.mode)} PATH`,\n ...rows.map(\n (row) =>\n `${padDisplay(row.status, row.statusRaw, widths.status)} ${pad(row.name, widths.name)} ${pad(row.scope, widths.scope)} ${pad(row.source, widths.source)} ${padDisplay(row.mode, row.modeRaw, widths.mode)} ${row.path}`,\n ),\n ];\n return lines.join(\"\\n\");\n}\n\ntype DisablePlan = {\n path: string;\n tool: string;\n server: string;\n fromKey: string;\n toKey: string;\n};\n\nfunction disableKeys(tool: string): { fromKey: string; toKey: string } {\n if (tool === \"vscode\" || tool === \"cursor\") return { fromKey: \"servers\", toKey: \"disabledServers\" };\n if (tool === \"opencode\") return { fromKey: \"mcp\", toKey: \"disabledMcp\" };\n return { fromKey: \"mcpServers\", toKey: \"disabledMcpServers\" };\n}\n\nexport async function disableNativeMcp(serverName: string, opts: { includeUser?: boolean; dryRun?: boolean } = {}): Promise<string> {\n const servers = await discoverMcpServers(opts.includeUser ? { includeUser: true } : {});\n const server = servers.find((item) => item.name === serverName || item.originalName === serverName);\n if (!server) throw new Error(`Native MCP server not found: ${serverName}`);\n if (server.source.managed) throw new Error(`Cannot modify managed MCP config: ${server.source.path}`);\n const keys = disableKeys(server.source.tool);\n const plan: DisablePlan = { path: server.source.path, tool: server.source.tool, server: server.originalName, ...keys };\n const message = `Disable native MCP ${plan.server} in ${plan.path}: move ${plan.fromKey}.${plan.server} -> ${plan.toKey}.${plan.server}`;\n if (opts.dryRun !== false) return `${message}\\nDry run only. Re-run with --yes to write changes.`;\n\n const config = (await readJson(plan.path)) as Record<string, unknown>;\n const source = config[plan.fromKey] && typeof config[plan.fromKey] === \"object\" && !Array.isArray(config[plan.fromKey]) ? (config[plan.fromKey] as Record<string, unknown>) : {};\n if (!(plan.server in source)) throw new Error(`Server ${plan.server} not found under ${plan.fromKey} in ${plan.path}`);\n const disabled = config[plan.toKey] && typeof config[plan.toKey] === \"object\" && !Array.isArray(config[plan.toKey]) ? (config[plan.toKey] as Record<string, unknown>) : {};\n disabled[plan.server] = source[plan.server];\n delete source[plan.server];\n config[plan.fromKey] = source;\n config[plan.toKey] = disabled;\n const backup = `${plan.path}.toolcapsule.bak`;\n await mkdir(dirname(backup), { recursive: true }).catch(() => undefined);\n if (existsSync(plan.path)) await writeFile(backup, await readFile(plan.path, \"utf8\"));\n await writeJson(plan.path, config);\n return `${message}\\nBackup: ${backup}`;\n}\n\nexport async function disableToolCapsuleProfile(profileName: string): Promise<string> {\n const candidates = [workspaceProfilePath(profileName), join(toolCapsuleHome(), \"profiles\", `${profileName}.json`)];\n const found = candidates.find((path) => existsSync(path));\n if (!found) throw new Error(`ToolCapsule profile not found: ${profileName}`);\n const disabledPath = `${found}.disabled`;\n await rename(found, disabledPath);\n return `Disabled ToolCapsule profile ${profileName}: ${found} -> ${disabledPath}`;\n}\n","import { existsSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { isAbsolute, join, resolve } from \"node:path\";\nimport type { McpProfileSource, ProfileConfig, SnapshotProfileConfig, TransportConfig } from \"../types.js\";\nimport { readJson } from \"../utils/fs.js\";\n\nexport type McpConfigSource = Omit<McpProfileSource, \"server\">;\n\nexport type ImportedMcpServer = {\n name: string;\n originalName: string;\n source: McpConfigSource;\n profile: SnapshotProfileConfig;\n warnings: string[];\n};\n\ntype ServerRecord = Record<string, unknown>;\n\nconst workspaceSources: McpConfigSource[] = [\n { tool: \"vscode\", path: join(\".vscode\", \"mcp.json\") },\n { tool: \"generic\", path: \"mcp.json\" },\n { tool: \"claude\", path: \".mcp.json\" },\n { tool: \"opencode\", path: \"opencode.json\" },\n { tool: \"gemini\", path: join(\".gemini\", \"settings.json\") },\n { tool: \"cursor\", path: join(\".cursor\", \"mcp.json\") },\n];\n\nconst userSources: McpConfigSource[] = [\n { tool: \"vscode\", path: join(homedir(), \".config\", \"Code\", \"User\", \"mcp.json\"), userLevel: true },\n { tool: \"vscode\", path: join(homedir(), \".config\", \"Code - Insiders\", \"User\", \"mcp.json\"), userLevel: true },\n { tool: \"vscode\", path: join(homedir(), \".vscode-server\", \"data\", \"User\", \"mcp.json\"), userLevel: true },\n { tool: \"vscode\", path: join(homedir(), \".vscode-server-insiders\", \"data\", \"User\", \"mcp.json\"), userLevel: true },\n { tool: \"claude\", path: join(homedir(), \".claude.json\"), userLevel: true },\n { tool: \"opencode\", path: join(homedir(), \".config\", \"opencode\", \"opencode.json\"), userLevel: true },\n { tool: \"gemini\", path: join(homedir(), \".gemini\", \"settings.json\"), userLevel: true },\n { tool: \"cursor\", path: join(homedir(), \".cursor\", \"mcp.json\"), userLevel: true },\n { tool: \"cursor\", path: join(homedir(), \".config\", \"Cursor\", \"User\", \"mcp.json\"), userLevel: true },\n { tool: \"cursor\", path: join(homedir(), \".config\", \"Cursor\", \"User\", \"settings.json\"), userLevel: true },\n];\n\nconst managedSources: McpConfigSource[] = [\n { tool: \"claude\", path: \"/etc/claude-code/managed-mcp.json\", managed: true },\n];\n\nfunction asRecord(value: unknown): ServerRecord | undefined {\n return value && typeof value === \"object\" && !Array.isArray(value) ? (value as ServerRecord) : undefined;\n}\n\nfunction stringArray(value: unknown): string[] | undefined {\n return Array.isArray(value) && value.every((item) => typeof item === \"string\") ? value : undefined;\n}\n\nfunction stringRecord(value: unknown): Record<string, string> | undefined {\n const record = asRecord(value);\n if (!record) return undefined;\n const entries = Object.entries(record).filter((entry): entry is [string, string] => typeof entry[1] === \"string\");\n return entries.length > 0 ? Object.fromEntries(entries) : undefined;\n}\n\nfunction cleanName(name: string): string {\n const cleaned = name\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .replace(/-{2,}/g, \"-\");\n return cleaned || \"imported-mcp\";\n}\n\nfunction mapServer(name: string, source: McpConfigSource, raw: unknown): ImportedMcpServer | undefined {\n const server = asRecord(raw);\n if (!server) return undefined;\n\n const warnings: string[] = [];\n let transport: TransportConfig | undefined;\n const type = typeof server.type === \"string\" ? server.type : undefined;\n const url = typeof server.url === \"string\" ? server.url : typeof server.httpUrl === \"string\" ? server.httpUrl : undefined;\n const commandValue = server.command;\n const headers = stringRecord(server.headers);\n const env = stringRecord(server.env) ?? stringRecord(server.environment);\n const cwd = typeof server.cwd === \"string\" ? server.cwd : undefined;\n\n if (url && (!type || [\"http\", \"streamable-http\", \"remote\", \"sse\", \"ws\"].includes(type))) {\n transport = { type: \"remote\", url, ...(headers ? { headers } : {}), ...(env ? { env } : {}) };\n if (type === \"sse\" || type === \"ws\") warnings.push(`Imported ${type} server as remote URL; verify transport compatibility.`);\n } else if (typeof commandValue === \"string\") {\n transport = {\n type: \"stdio\",\n command: commandValue,\n args: stringArray(server.args) ?? [],\n ...(env ? { env } : {}),\n ...(cwd ? { cwd } : {}),\n };\n } else if (Array.isArray(commandValue) && commandValue.every((item) => typeof item === \"string\") && commandValue.length > 0) {\n transport = { type: \"stdio\", command: commandValue[0]!, args: commandValue.slice(1), ...(env ? { env } : {}), ...(cwd ? { cwd } : {}) };\n }\n\n if (!transport) return undefined;\n if (server.headers && !headers) warnings.push(\"Headers were present but not copied because they were not string values.\");\n if ((server.env || server.environment) && !env) warnings.push(\"Environment variables were present but not copied because they were not string values.\");\n if (server.includeTools || server.excludeTools) warnings.push(\"Tool include/exclude filters were not copied; use ToolCapsule brief/schema commands to choose tools manually.\");\n\n const profileName = cleanName(name);\n return {\n name: profileName,\n originalName: name,\n source,\n warnings,\n profile: {\n name: profileName,\n transport,\n },\n };\n}\n\nexport function linkedProfileForImportedServer(server: ImportedMcpServer, name = server.name): ProfileConfig {\n return {\n name,\n kind: \"linked\",\n source: {\n ...server.source,\n path: isAbsolute(server.source.path) ? server.source.path : resolve(server.source.path),\n server: server.originalName,\n },\n };\n}\n\nexport async function resolveProfileSource(source: McpProfileSource): Promise<SnapshotProfileConfig | undefined> {\n if (!existsSync(source.path)) return undefined;\n const config = asRecord(await readJson(source.path));\n if (!config) return undefined;\n const entry = serverEntries(source, config).find(([name]) => name === source.server);\n if (!entry) return undefined;\n return mapServer(entry[0], source, entry[1])?.profile;\n}\n\nfunction serverEntries(source: McpConfigSource, config: ServerRecord): Array<[string, unknown]> {\n if (source.tool === \"vscode\" || source.tool === \"cursor\") return Object.entries(asRecord(config.servers) ?? {});\n if (source.tool === \"opencode\") return Object.entries(asRecord(config.mcp) ?? {});\n if (source.tool === \"claude\") {\n const projectEntries = Object.entries(asRecord(config.mcpServers) ?? {});\n const projectConfigs = Object.entries(asRecord(config.projects) ?? {}).flatMap(([, project]) =>\n Object.entries(asRecord(asRecord(project)?.mcpServers) ?? {}),\n );\n return [...projectEntries, ...projectConfigs];\n }\n return Object.entries(asRecord(config.mcpServers) ?? {});\n}\n\nexport async function discoverMcpServers(opts: { includeUser?: boolean; includeManaged?: boolean } = {}): Promise<ImportedMcpServer[]> {\n const sources = [\n ...workspaceSources,\n ...(opts.includeUser ? userSources : []),\n ...(opts.includeManaged ? managedSources : []),\n ];\n const discovered: ImportedMcpServer[] = [];\n\n for (const source of sources) {\n if (!existsSync(source.path)) continue;\n const config = asRecord(await readJson(source.path));\n if (!config) continue;\n for (const [name, raw] of serverEntries(source, config)) {\n const imported = mapServer(name, source, raw);\n if (imported) discovered.push(imported);\n }\n }\n\n return discovered;\n}\n\nexport function selectImportedServers(servers: ImportedMcpServer[], name?: string, all?: boolean): ImportedMcpServer[] {\n if (all) return servers;\n if (!name) return servers.length === 1 ? servers : [];\n const normalized = cleanName(name);\n return servers.filter((server) => server.name === normalized || server.name === name);\n}\n","import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname, resolve } from \"node:path\";\n\nexport async function readJson<T>(path: string): Promise<T> {\n return JSON.parse(await readFile(path, \"utf8\")) as T;\n}\n\nexport async function writeJson(path: string, value: unknown): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, `${JSON.stringify(value, null, 2)}\\n`);\n}\n\nexport async function writeText(path: string, value: string): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, value);\n}\n\nexport async function ensureToolCapsuleIgnored(): Promise<void> {\n const gitignorePath = \".gitignore\";\n const entry = \".toolcapsule/\";\n let content = \"\";\n try {\n content = await readFile(gitignorePath, \"utf8\");\n } catch (error) {\n if (!(error instanceof Error && \"code\" in error && error.code === \"ENOENT\")) throw error;\n }\n\n const lines = content.split(/\\r?\\n/).map((line) => line.trim());\n const alreadyIgnored = lines.some((line) => line === entry || line === `/${entry}` || line === \".toolcapsule\");\n if (alreadyIgnored) return;\n\n const prefix = content.length > 0 && !content.endsWith(\"\\n\") ? \"\\n\" : \"\";\n await writeFile(gitignorePath, `${content}${prefix}${entry}\\n`);\n}\n\nexport function abs(path: string): string {\n return resolve(process.cwd(), path);\n}\n","import { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nexport function toolCapsuleHome(): string {\n return process.env.TOOLCAPSULE_HOME || join(homedir(), \".toolcapsule\");\n}\n\nexport function userProfilePath(profileName: string): string {\n return join(toolCapsuleHome(), \"profiles\", `${profileName}.json`);\n}\n\nexport function workspaceProfilePath(profileName: string): string {\n return join(\".toolcapsule\", \"profiles\", `${profileName}.json`);\n}\n\nexport function workspaceRunBaseDir(profileName: string): string {\n return join(\".toolcapsule\", \"runs\", profileName);\n}\n","import { spawn, type ChildProcessWithoutNullStreams } from \"node:child_process\";\nimport { once } from \"node:events\";\nimport { resolve } from \"node:path\";\nimport type { JsonRpcMessage, SnapshotProfileConfig, ToolsListResult } from \"../types.js\";\n\nexport type McpClientOptions = {\n timeoutMs?: number;\n debug?: boolean;\n clientVersion?: string;\n};\n\nexport class McpClient {\n private child: ChildProcessWithoutNullStreams;\n private nextId = 1;\n private buffer = \"\";\n private pending = new Map<\n number,\n { resolve: (value: JsonRpcMessage) => void; reject: (error: Error) => void }\n >();\n private timeoutMs: number;\n private debug: boolean;\n private clientVersion: string;\n\n constructor(profile: SnapshotProfileConfig, opts: McpClientOptions = {}) {\n this.timeoutMs = opts.timeoutMs ?? Number(process.env.TOOLCAPSULE_TIMEOUT_MS || \"45000\");\n this.debug = opts.debug ?? process.env.TOOLCAPSULE_DEBUG === \"1\";\n this.clientVersion = opts.clientVersion ?? \"0.0.0\";\n if (profile.transport.type === \"remote\") {\n this.child = spawn(\"npx\", [\"-y\", \"mcp-remote\", profile.transport.url, ...headersToArgs(profile.transport.headers)], {\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n env: { ...process.env, ...profile.transport.env },\n });\n } else {\n this.child = spawn(profile.transport.command, profile.transport.args ?? [], {\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n env: { ...process.env, ...profile.transport.env },\n cwd: profile.transport.cwd ? resolve(profile.transport.cwd) : undefined,\n });\n }\n this.child.stdout.setEncoding(\"utf8\");\n this.child.stdout.on(\"data\", (chunk: string) => this.onStdout(chunk));\n this.child.stderr.on(\"data\", (chunk: Buffer) => this.onStderr(chunk));\n this.child.on(\"exit\", (code, signal) => {\n const error = new Error(`MCP process exited early (code=${code}, signal=${signal})`);\n for (const waiter of this.pending.values()) waiter.reject(error);\n this.pending.clear();\n });\n }\n\n private onStderr(chunk: Buffer): void {\n if (!this.debug) return;\n process.stderr.write(redactSecrets(chunk.toString(\"utf8\")));\n }\n\n private onStdout(chunk: string): void {\n this.buffer += chunk;\n let newlineIndex: number;\n while ((newlineIndex = this.buffer.indexOf(\"\\n\")) >= 0) {\n const line = this.buffer.slice(0, newlineIndex).trim();\n this.buffer = this.buffer.slice(newlineIndex + 1);\n if (!line) continue;\n let message: JsonRpcMessage;\n try {\n message = JSON.parse(line) as JsonRpcMessage;\n } catch {\n process.stderr.write(`${line}\\n`);\n continue;\n }\n if (typeof message.id === \"number\") {\n const waiter = this.pending.get(message.id);\n if (waiter) {\n this.pending.delete(message.id);\n waiter.resolve(message);\n }\n }\n }\n }\n\n async init(): Promise<void> {\n await this.request(\"initialize\", {\n protocolVersion: \"2025-03-26\",\n capabilities: {},\n clientInfo: { name: \"toolcapsule\", version: this.clientVersion },\n });\n this.notify(\"notifications/initialized\", {});\n }\n\n async request(method: string, params?: unknown): Promise<unknown> {\n const id = this.nextId++;\n const responsePromise = new Promise<JsonRpcMessage>((resolve, reject) => {\n this.pending.set(id, { resolve, reject });\n });\n this.child.stdin.write(`${JSON.stringify({ jsonrpc: \"2.0\", id, method, params })}\\n`);\n const response = await this.withTimeout(responsePromise, method);\n if (response.error) throw new Error(`${method} failed: ${JSON.stringify(response.error, null, 2)}`);\n return response.result;\n }\n\n notify(method: string, params?: unknown): void {\n this.child.stdin.write(`${JSON.stringify({ jsonrpc: \"2.0\", method, params })}\\n`);\n }\n\n async listTools(): Promise<ToolsListResult> {\n return (await this.request(\"tools/list\", {})) as ToolsListResult;\n }\n\n async callTool(name: string, args: unknown): Promise<unknown> {\n return await this.request(\"tools/call\", { name, arguments: args });\n }\n\n async close(): Promise<void> {\n if (!this.child.killed) this.child.kill();\n if (this.child.exitCode === null) await Promise.race([once(this.child, \"exit\"), new Promise((resolve) => setTimeout(resolve, 500))]);\n }\n\n private async withTimeout<T>(promise: Promise<T>, label: string): Promise<T> {\n let timer: NodeJS.Timeout | undefined;\n const timeout = new Promise<never>((_, reject) => {\n timer = setTimeout(() => reject(new Error(`${label} timed out after ${this.timeoutMs}ms`)), this.timeoutMs);\n });\n try {\n return await Promise.race([promise, timeout]);\n } finally {\n if (timer) clearTimeout(timer);\n }\n }\n}\n\nfunction headersToArgs(headers: Record<string, string> | undefined): string[] {\n if (!headers) return [];\n return Object.entries(headers).flatMap(([key, value]) => [\"--header\", `${key}:${value}`]);\n}\n\nfunction redactSecrets(text: string): string {\n return text\n .replace(/https:\\/\\/mcp\\.feishu\\.cn\\/mcp\\/[^\\s\"']+/g, \"https://mcp.feishu.cn/mcp/[redacted]\")\n .replace(/(Bearer\\s+)[A-Za-z0-9._~+/=-]+/gi, \"$1[redacted]\")\n .replace(/(token=)[^\\s&\"']+/gi, \"$1[redacted]\")\n .replace(/(api[_-]?key=)[^\\s&\"']+/gi, \"$1[redacted]\");\n}\n","import { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { z } from \"zod\";\nimport { resolveProfileSource } from \"./mcp/importer.js\";\nimport { userProfilePath, workspaceProfilePath } from \"./paths.js\";\nimport type { ProfileConfig, SnapshotProfileConfig } from \"./types.js\";\nimport { readJson } from \"./utils/fs.js\";\n\nconst transportSchema = z.union([\n z.object({\n type: z.literal(\"remote\"),\n url: z.string().url(),\n headers: z.record(z.string()).optional(),\n env: z.record(z.string()).optional(),\n }),\n z.object({\n type: z.literal(\"stdio\"),\n command: z.string().min(1),\n args: z.array(z.string()).optional(),\n env: z.record(z.string()).optional(),\n cwd: z.string().optional(),\n }),\n]);\n\nconst skillSchema = z\n .object({\n name: z.string().optional(),\n description: z.string().optional(),\n })\n .optional();\n\nconst shortcutsSchema = z\n .record(\n z.object({\n tool: z.string(),\n description: z.string().optional(),\n args: z.record(z.enum([\"string\", \"file\", \"json\", \"boolean\", \"number\"])).optional(),\n }),\n )\n .optional();\n\nconst snapshotProfileSchema = z.object({\n name: z.string().min(1),\n kind: z.literal(\"snapshot\").optional(),\n transport: transportSchema,\n skill: skillSchema,\n shortcuts: shortcutsSchema,\n});\n\nconst linkedProfileSchema = z.object({\n name: z.string().min(1),\n kind: z.literal(\"linked\"),\n source: z.object({\n tool: z.enum([\"vscode\", \"claude\", \"opencode\", \"gemini\", \"cursor\", \"generic\"]),\n path: z.string().min(1),\n server: z.string().min(1),\n userLevel: z.boolean().optional(),\n }),\n skill: skillSchema,\n shortcuts: shortcutsSchema,\n});\n\nconst profileSchema = z.union([snapshotProfileSchema, linkedProfileSchema]);\n\nexport async function loadProfile(profilePathOrName: string): Promise<SnapshotProfileConfig> {\n const candidates = [\n profilePathOrName,\n `${profilePathOrName}.json`,\n workspaceProfilePath(profilePathOrName),\n userProfilePath(profilePathOrName),\n join(\".github\", \"skills\", `${profilePathOrName}-mcp`, \"toolcapsule.config.json\"),\n join(\".claude\", \"skills\", `${profilePathOrName}-mcp`, \"toolcapsule.config.json\"),\n join(\".opencode\", \"skills\", `${profilePathOrName}-mcp`, \"toolcapsule.config.json\"),\n join(\".agents\", \"skills\", `${profilePathOrName}-mcp`, \"toolcapsule.config.json\"),\n ];\n const found = candidates.find((path) => existsSync(path));\n if (!found) throw new Error(`Profile not found: ${profilePathOrName}`);\n const profile = profileSchema.parse(await readJson(found)) as ProfileConfig;\n if (profile.kind !== \"linked\") return profile;\n\n const resolved = await resolveProfileSource(profile.source);\n if (!resolved) {\n throw new Error(`Linked profile source not found: ${profile.source.path}#${profile.source.server}`);\n }\n\n return snapshotProfileSchema.parse({\n ...resolved,\n name: profile.name,\n skill: profile.skill ?? resolved.skill,\n shortcuts: profile.shortcuts ?? resolved.shortcuts,\n }) as SnapshotProfileConfig;\n}\n","import type { McpTool } from \"../types.js\";\n\nexport function toolTitle(tool: McpTool): string {\n return tool.annotations?.title || tool.description?.split(/\\n/)[0]?.slice(0, 100) || tool.name;\n}\n\nexport function briefTool(tool: McpTool): string {\n const schema = tool.inputSchema as any;\n const required = Array.isArray(schema?.required) ? schema.required : [];\n const properties = schema?.properties && typeof schema.properties === \"object\" ? Object.keys(schema.properties) : [];\n const flags = [\n tool.annotations?.readOnlyHint ? \"read-only\" : undefined,\n tool.annotations?.destructiveHint ? \"destructive\" : undefined,\n ].filter(Boolean);\n return `- ${tool.name}: ${toolTitle(tool)}${flags.length ? ` [${flags.join(\", \")}]` : \"\"}${required.length ? ` required=${required.join(\"|\")}` : \"\"}${properties.length ? ` args=${properties.slice(0, 12).join(\"|\")}` : \"\"}`;\n}\n\nexport function briefTools(tools: McpTool[]): string {\n return tools.map(briefTool).join(\"\\n\");\n}\n","import type { McpTool } from \"../types.js\";\n\nexport function summarizeTool(tool: McpTool): unknown {\n const schema = tool.inputSchema as any;\n const properties = schema?.properties && typeof schema.properties === \"object\" ? schema.properties : {};\n return {\n name: tool.name,\n title: tool.annotations?.title,\n description: tool.description?.split(/\\n\\n/)[0]?.slice(0, 500),\n annotations: tool.annotations,\n required: Array.isArray(schema?.required) ? schema.required : [],\n arguments: Object.fromEntries(\n Object.entries(properties).map(([key, value]: [string, any]) => [\n key,\n { type: value?.type, enum: value?.enum, description: value?.description?.slice?.(0, 160) },\n ]),\n ),\n };\n}\n\nexport function summarizeTools(tools: McpTool[]): unknown[] {\n return tools.map(summarizeTool);\n}\n","import { mkdir, writeFile } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\nimport Handlebars from \"handlebars\";\nimport { McpClient } from \"../mcp/client.js\";\nimport type { McpTool } from \"../types.js\";\nimport { summarizeTools } from \"../schema/summarize.js\";\nimport type { ProfileConfig } from \"../types.js\";\nimport { writeJson } from \"../utils/fs.js\";\n\nexport type SkillTarget = \"copilot\" | \"claude\" | \"opencode\" | \"agents\" | \"all\";\n\nexport const defaultSkillTarget: SkillTarget = \"claude\";\n\nexport function skillOutputDir(skillName: string, target: Exclude<SkillTarget, \"all\">): string {\n if (target === \"copilot\") return join(\".github\", \"skills\", skillName);\n if (target === \"claude\") return join(\".claude\", \"skills\", skillName);\n if (target === \"opencode\") return join(\".opencode\", \"skills\", skillName);\n return join(\".agents\", \"skills\", skillName);\n}\n\nexport function expandSkillTargets(target: SkillTarget): Exclude<SkillTarget, \"all\">[] {\n return target === \"all\" ? [\"copilot\", \"claude\", \"opencode\", \"agents\"] : [target];\n}\n\nconst skillTemplate = `---\nname: {{skillName}}\ndescription: '{{description}}'\nargument-hint: 'MCP task, tool name, or args file to run'\n---\n\n# {{title}}\n\nThis skill wraps an MCP server as a lightweight, lazy-loaded, file-first workflow.\n\n## Why use this skill\n\n- Keep full MCP tool schemas out of the model context until needed.\n- Use brief tool summaries for everyday work.\n- Store large payloads in local files such as \\`args.json\\` or \\`content.md\\`.\n- Patch local artifacts and retry failed calls deterministically.\n\n## Commands\n\n\\`\\`\\`bash\ntoolcapsule tools {{profileName}} --brief\ntoolcapsule describe {{profileName}} <tool>\ntoolcapsule call {{profileName}} <tool> @args.json\ntoolcapsule retry .toolcapsule/runs/{{profileName}}/<run-id>\n\\`\\`\\`\n\n{{#if toolsMarkdown}}\n## Tool summary\n\nUse this summary for planning. Only run \\`toolcapsule schema {{profileName}} <tool>\\` when these brief details are insufficient.\n\n{{{toolsMarkdown}}}\n{{else}}\n## Tool discovery\n\nRun \\`toolcapsule tools {{profileName}} --brief\\` once before choosing a tool. Then run \\`toolcapsule schema {{profileName}} <tool>\\` only when the brief summary is insufficient.\n{{/if}}\n\n## Workflow\n\n1. Use \\`tools --brief\\` to find the likely tool.\n2. Use \\`describe <tool>\\` only when the brief schema is insufficient.\n3. Put complex arguments in a local JSON file.\n4. Call with \\`@args.json\\` and save the run.\n5. On failure, patch the local file and run \\`retry\\`.\n\n## Safety\n\n- Do not fabricate IDs, URLs, user IDs, or opaque tokens.\n- Prefer local files for large payloads.\n- Do not print secrets.\n- Review destructive tools before calling.\n`;\n\nexport type GenerateSkillOptions = {\n outputDir?: string;\n target?: SkillTarget;\n embedProfile?: boolean;\n tools?: McpTool[];\n};\n\ntype ToolSummary = {\n name?: string;\n description?: string;\n required?: unknown;\n annotations?: { readOnlyHint?: boolean; destructiveHint?: boolean };\n};\n\nfunction toolsMarkdown(tools: McpTool[] | undefined): string | undefined {\n if (!tools || tools.length === 0) return undefined;\n const summaries = summarizeTools(tools) as ToolSummary[];\n const rows = summaries.slice(0, 40).map((tool) => {\n const required = Array.isArray(tool.required) && tool.required.length > 0 ? tool.required.join(\", \") : \"-\";\n const risk = tool.annotations?.destructiveHint ? \"writes\" : tool.annotations?.readOnlyHint ? \"read\" : \"unknown\";\n const description = (tool.description || \"-\").replace(/\\|/g, \"\\\\|\").slice(0, 120);\n return `| \\`${tool.name || \"unknown\"}\\` | ${description} | ${required} | ${risk} |`;\n });\n return [\"| Tool | Purpose | Required args | Risk |\", \"|---|---|---|---|\", ...rows].join(\"\\n\");\n}\n\nexport async function fetchProfileTools(profile: ProfileConfig, opts: { clientVersion?: string } = {}): Promise<McpTool[] | undefined> {\n if (profile.kind === \"linked\") return undefined;\n const client = new McpClient(profile, { ...(opts.clientVersion ? { clientVersion: opts.clientVersion } : {}), timeoutMs: 15000 });\n try {\n await client.init();\n return (await client.listTools()).tools;\n } catch {\n return undefined;\n } finally {\n await client.close().catch(() => undefined);\n }\n}\n\nasync function generateSkillAt(profile: ProfileConfig, outputDir: string, opts: { embedProfile?: boolean; tools?: McpTool[] } = {}): Promise<string> {\n const skillName = profile.skill?.name || `${profile.name}-mcp`;\n await mkdir(join(outputDir, \"scripts\"), { recursive: true });\n\n const template = Handlebars.compile(skillTemplate);\n const description =\n profile.skill?.description ||\n `Use when operating tools from the ${profile.name} MCP server. Lazy-load schemas, call tools through local files, and retry failed calls by patching artifacts.`;\n const markdown = template({\n skillName,\n profileName: profile.name,\n title: `${profile.name} MCP Skill`,\n description: description.replace(/'/g, \"''\"),\n toolsMarkdown: toolsMarkdown(opts.tools),\n });\n await writeFile(join(outputDir, \"SKILL.md\"), markdown);\n if (opts.embedProfile) await writeJson(join(outputDir, \"toolcapsule.config.json\"), profile);\n await writeFile(\n join(outputDir, \"scripts\", \"README.md\"),\n `# Scripts\\n\\nThis skill uses the \\`toolcapsule\\` CLI and profiles resolved by name.\\n`,\n );\n return outputDir;\n}\n\nexport async function generateSkill(profile: ProfileConfig, opts: GenerateSkillOptions = {}): Promise<string> {\n const skillName = profile.skill?.name || `${profile.name}-mcp`;\n const target = opts.target || defaultSkillTarget;\n const embedProfile = opts.embedProfile === true;\n const atOptions = { embedProfile, ...(opts.tools ? { tools: opts.tools } : {}) };\n const outputs = opts.outputDir\n ? [await generateSkillAt(profile, opts.outputDir, atOptions)]\n : await Promise.all(\n expandSkillTargets(target).map((item) =>\n generateSkillAt(profile, skillOutputDir(skillName, item), atOptions),\n ),\n );\n return outputs.join(\", \");\n}\n\nexport async function writeProfile(path: string, profile: ProfileConfig): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n await writeJson(path, profile);\n}\n","import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { defaultSkillTarget, expandSkillTargets, skillOutputDir, type SkillTarget } from \"./generator.js\";\n\nexport async function installAgentSkill(outputDir?: string, target: SkillTarget = defaultSkillTarget): Promise<string> {\n let agentSkill: string;\n try {\n agentSkill = await readFile(new URL(\"../skills/toolcapsule/SKILL.md\", import.meta.url), \"utf8\");\n } catch {\n agentSkill = await readFile(new URL(\"../../skills/toolcapsule/SKILL.md\", import.meta.url), \"utf8\");\n }\n const outputDirs = outputDir ? [outputDir] : expandSkillTargets(target).map((item) => skillOutputDir(\"toolcapsule\", item));\n await Promise.all(\n outputDirs.map(async (dir) => {\n await mkdir(dir, { recursive: true });\n await writeFile(join(dir, \"SKILL.md\"), agentSkill);\n }),\n );\n return outputDirs.join(\", \");\n}\n","import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type { RunRecord } from \"../types.js\";\nimport { writeJson } from \"../utils/fs.js\";\n\nexport function createRunId(): string {\n return new Date().toISOString().replace(/[:.]/g, \"-\");\n}\n\nexport async function saveRun(baseDir: string, record: RunRecord): Promise<string> {\n const dir = join(baseDir, record.id);\n await mkdir(dir, { recursive: true });\n await writeJson(join(dir, \"run.json\"), record);\n await writeJson(join(dir, \"request.json\"), record.request);\n if (record.response !== undefined) await writeJson(join(dir, \"response.json\"), record.response);\n if (record.error) await writeFile(join(dir, \"error.txt\"), record.error);\n await writeFile(join(dir, \"command.txt\"), `${record.command}\\n`);\n return dir;\n}\n\nexport async function loadRun(runDir: string): Promise<RunRecord> {\n return JSON.parse(await readFile(join(runDir, \"run.json\"), \"utf8\")) as RunRecord;\n}\n","export function roughTokens(value: unknown): number {\n const text = typeof value === \"string\" ? value : JSON.stringify(value);\n return Math.ceil(text.length / 4);\n}\n\nexport function percentReduction(before: number, after: number): number {\n return before === 0 ? 0 : ((before - after) / before) * 100;\n}\n"],"mappings":"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","names":["readFile","pc","existsSync","mkdir","readFile","writeFile","homedir","dirname","join","resolve","resolve","homedir","join","existsSync","join","homedir","mkdir","dirname","writeFile","readFile","resolve","existsSync","join","join","existsSync","mkdir","writeFile","dirname","join","join","mkdir","writeFile","dirname","mkdir","readFile","writeFile","join","readFile","mkdir","writeFile","join","mkdir","readFile","writeFile","join","join","mkdir","writeFile","readFile","writeFile","readFile","pc","writeFile"]}
@@ -57,9 +57,20 @@ Yes. A strong onboarding flow is to import existing MCP config files and convert
57
57
  Initial support exists through:
58
58
 
59
59
  ```bash
60
- tcap import --dry-run
61
- tcap import --name <server> --target claude
62
- tcap import --all --target all
60
+ npx skills add RainSunMe/toolcapsule --skill toolcapsule
61
+ ```
62
+
63
+ After the ToolCapsule Skill is installed, the agent can install/use the CLI and run:
64
+
65
+ ```bash
66
+ tcap mcp list --include-user
67
+ tcap mcp enable <server> --as <profile> --target claude
68
+ ```
69
+
70
+ For all compatible skill targets:
71
+
72
+ ```bash
73
+ tcap mcp enable <server> --as <profile> --target all
63
74
  ```
64
75
 
65
76
  The importer currently reads workspace MCP config by default and only reads user-level config with `--include-user`.
@@ -38,7 +38,7 @@ This is a lazy MCP workflow: agents discover compact summaries first and load fu
38
38
 
39
39
  ```text
40
40
  .mcp.json / .vscode/mcp.json / opencode.json / .gemini/settings.json / .cursor/mcp.json
41
- .toolcapsule/profiles/<server>.json
41
+ ~/.toolcapsule/profiles/<server>.json
42
42
  → .claude/skills/<server>-mcp/SKILL.md by default
43
43
  ```
44
44
 
@@ -114,9 +114,11 @@ Heavy MCP server
114
114
  使用 ToolCapsule,可以这样开始:
115
115
 
116
116
  ```bash
117
- npm i -g toolcapsule
117
+ npx skills add RainSunMe/toolcapsule --skill toolcapsule
118
118
  ```
119
119
 
120
+ AI 读到 ToolCapsule Skill 后,会在需要时安装 CLI,并扫描已有 MCP 配置。
121
+
120
122
  初始化一个 MCP profile,并生成对应的 Agent Skill:
121
123
 
122
124
  ```bash
@@ -126,8 +128,8 @@ tcap init feishu --url <remote-mcp-url> --target claude
126
128
  或者,如果你已经在 Claude Code、VS Code / GitHub Copilot、OpenCode、Gemini CLI、Cursor 等工具里配置过 MCP,可以直接导入:
127
129
 
128
130
  ```bash
129
- tcap import --dry-run
130
- tcap import --name feishu --target claude
131
+ tcap mcp list --include-user
132
+ tcap mcp enable docs --as feishu --target claude
131
133
  ```
132
134
 
133
135
  查看工具列表时,只加载简短摘要:
@@ -278,17 +280,18 @@ ToolCapsule 不是说 Native MCP 不好。
278
280
  ```text
279
281
  .claude/skills/feishu-mcp/
280
282
  SKILL.md # lightweight Agent Skill entrypoint
281
- toolcapsule.config.json # MCP transport/profile config
282
283
  scripts/README.md
283
284
 
285
+ ~/.toolcapsule/
286
+ profiles/feishu.json # user-level MCP profile, reusable across projects
287
+
284
288
  .toolcapsule/
285
- profiles/feishu.json # local MCP profile
286
- runs/feishu/ # auditable tool call records
289
+ runs/feishu/ # workspace-local auditable tool call records
287
290
  ```
288
291
 
289
292
  `SKILL.md` 是 Agent 看到的轻量入口。
290
293
 
291
- `toolcapsule.config.json` 保存 MCP profile 信息。
294
+ `~/.toolcapsule/profiles/` 保存可跨项目复用的 MCP profile 信息。
292
295
 
293
296
  `.toolcapsule/runs/` 保存每次工具调用的记录。
294
297
 
@@ -329,14 +332,14 @@ ToolCapsule 目前是 early alpha,API 可能在 v1.0 前变化。
329
332
  如果你愿意尝试,可以这样安装:
330
333
 
331
334
  ```bash
332
- npm i -g toolcapsule
335
+ npx skills add RainSunMe/toolcapsule --skill toolcapsule
333
336
  ```
334
337
 
335
338
  常用命令:
336
339
 
337
340
  ```bash
338
- tcap import --dry-run
339
- tcap import --name feishu --target claude
341
+ tcap mcp list --include-user
342
+ tcap mcp enable docs --as feishu --target claude
340
343
  tcap tools feishu --brief
341
344
  tcap schema feishu create-doc
342
345
  tcap call feishu create-doc @args.json --save-run
@@ -0,0 +1,69 @@
1
+ # Comparison: ToolCapsule, native MCP, lazy-mcp, and MCP-to-Skill generators
2
+
3
+ ToolCapsule is not a replacement for MCP. It is an AI-first workflow manager for heavy MCP tools.
4
+
5
+ It overlaps with lazy MCP proxies and MCP-to-Skill generators, but the product shape is different: ToolCapsule inventories existing MCPs, links selected heavy servers into Agent Skills, keeps payloads in files, and records runs for patch-and-retry recovery.
6
+
7
+ ## Summary
8
+
9
+ | Approach | Best for | What the agent sees | Main trade-off |
10
+ |---|---|---|---|
11
+ | Native MCP | Small, frequent tools | Full MCP tools exposed by the host | Heavy servers can add context and retry cost |
12
+ | `lazy-mcp` style proxy | Aggregating many MCP servers behind a few meta-tools | Meta-tools such as list/describe/invoke | Requires adding a proxy MCP server and meta-tool calling discipline |
13
+ | `mcp2skill` / `mcp-to-skill` style generators | One-time conversion of an MCP server into a Skill folder | Generated Skill and local executor/config | Often copies config into the Skill and is more generator-oriented |
14
+ | ToolCapsule | Heavy SaaS/document/workflow MCPs used by AI coding agents | Official ToolCapsule Skill plus generated MCP-specific Skills with tool summaries | Requires `tcap` CLI for file-first calls and run artifacts |
15
+
16
+ ## Native MCP vs ToolCapsule
17
+
18
+ Native MCP is the source of truth. ToolCapsule keeps it that way.
19
+
20
+ The difference is workflow:
21
+
22
+ - native MCP exposes tools directly to the host;
23
+ - ToolCapsule lets the agent inventory MCPs, enable selected heavy ones as Skills, and call them through local files;
24
+ - failed calls become patchable run artifacts instead of regenerated prompts.
25
+
26
+ Use native MCP directly for small, high-frequency tools. Use ToolCapsule for heavy, low-frequency, document/workflow-oriented MCPs.
27
+
28
+ ## `lazy-mcp` style proxy vs ToolCapsule
29
+
30
+ `lazy-mcp` is a client-agnostic MCP proxy. It aggregates MCP servers and exposes a small number of meta-tools such as list, describe, and invoke.
31
+
32
+ ToolCapsule is not a proxy. It is a Skill and file workflow:
33
+
34
+ - no replacement MCP proxy is required;
35
+ - existing MCP configs can be linked instead of copied;
36
+ - generated Skills include compact tool summaries;
37
+ - calls use `@args.json` and saved run directories;
38
+ - retry is done by patching local artifacts.
39
+
40
+ Use a proxy when you want one MCP endpoint that aggregates many servers. Use ToolCapsule when you want the coding agent to manage heavy MCP workflows through Skills and files.
41
+
42
+ ## `mcp2skill` / `mcp-to-skill` generators vs ToolCapsule
43
+
44
+ MCP-to-Skill generators convert a server into a Skill folder. That overlaps with one part of ToolCapsule.
45
+
46
+ ToolCapsule adds a broader workflow:
47
+
48
+ - AI-first onboarding via `npx skills add RainSunMe/toolcapsule --skill toolcapsule`;
49
+ - `tcap mcp list` inventory across workspace, user, and ToolCapsule profiles;
50
+ - `tcap mcp enable <server> --as <profile>` for selected heavy servers;
51
+ - linked profiles by default, so private MCP URLs are not copied into generated Skills;
52
+ - generated Skills with embedded tool summaries;
53
+ - file-first calls through `tcap call <profile> <tool> @args.json --save-run`;
54
+ - run artifacts under `.toolcapsule/runs/<profile>/<run-id>/`;
55
+ - deterministic patch-and-retry.
56
+
57
+ Use a generator when you only need a static Skill folder. Use ToolCapsule when you need an ongoing workflow for discovery, enabling, calling, auditing, and retrying heavy MCP tools.
58
+
59
+ ## Positioning
60
+
61
+ ToolCapsule should be described as:
62
+
63
+ > AI-first workflow manager for heavy MCP tools.
64
+
65
+ Expanded:
66
+
67
+ > ToolCapsule inventories your existing MCPs, turns selected heavy servers into lazy Agent Skills, and keeps calls file-first with auditable runs and patch-and-retry recovery.
68
+
69
+ Related terms such as lazy MCP, MCP-to-Skill, and Agent Skills for MCP are useful search terms, but ToolCapsule is broader than a proxy or one-shot Skill generator.
package/docs/concept.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Concept
2
2
 
3
- **ToolCapsule** is an MCP-to-Skill workflow layer for heavy MCP tools.
3
+ **ToolCapsule** is an AI-first workflow manager for heavy MCP tools.
4
4
 
5
5
  MCP connects agents to tools. Skills package repeatable agent workflows. ToolCapsule sits between them: it keeps MCP as the source of truth, but turns schema-heavy tools into compact, lazy-loaded, file-first Agent Skills.
6
6
 
@@ -21,11 +21,11 @@ MCP tool schema → compact Skill guidance → local capsule files → auditable
21
21
  ToolCapsule can start from MCP servers users already registered in their coding tools:
22
22
 
23
23
  ```bash
24
- tcap import --dry-run
25
- tcap import --name <server> --target claude
24
+ tcap mcp list --include-user
25
+ tcap mcp enable <server> --as <profile> --target claude
26
26
  ```
27
27
 
28
- The import flow reads common workspace MCP config files, creates a ToolCapsule profile, and writes an Agent Skill for the selected target. This makes onboarding a conversion step instead of a manual reconfiguration step.
28
+ The inventory flow reads common workspace and opted-in user MCP config files, links or snapshots a ToolCapsule profile, and writes an Agent Skill for the selected target. This makes onboarding a conversion step instead of a manual reconfiguration step.
29
29
 
30
30
  Supported target outputs:
31
31
 
package/docs/hero-copy.md CHANGED
@@ -4,7 +4,7 @@ Heavy MCP tools don't belong in your prompt.
4
4
 
5
5
  Put them in a ToolCapsule.
6
6
 
7
- ToolCapsule is MCP-to-Skill for heavy MCP tools. It turns schema-heavy MCP servers into lightweight, lazy-loaded Agent Skills with file-first calls and patch-and-retry recovery.
7
+ ToolCapsule is an AI-first workflow manager for heavy MCP tools. It inventories existing MCPs, turns selected heavy tools into lightweight, lazy-loaded Agent Skills, and keeps calls file-first with patch-and-retry recovery.
8
8
 
9
9
  If you are searching for lazy MCP, ToolCapsule is the workflow: keep MCP as the capability layer, expose an Agent Skill as the workflow layer, and load schemas only when needed.
10
10