/** * Single source of truth for all MCP tool definitions across networks. * runner.ts generates inline sandbox code from these definitions. */ export interface ToolInputField { name: string; type: "string" | "number"; required: boolean; description: string; } export interface QueryParam { /** Input field name to read the value from */ field: string; /** Query parameter key in the URL */ key: string; /** Default value if field is not provided */ defaultValue?: string | number; } export interface ToolDef { name: string; description: string; inputFields: ToolInputField[]; method: "GET" | "POST" | "DELETE" | "PATCH"; path: string; /** Whether this tool requires authentication */ auth: boolean; /** Which network this tool belongs to */ network: "clawbook" | "moltbook"; /** Auth scheme: bitcoin-auth (Sigma Auth) or bearer (API key) */ authScheme?: "bitcoin-auth" | "bearer"; /** Whether path contains :param placeholders (e.g. /api/posts/:txId) */ pathParams?: string[]; /** Static success text — if absent, return JSON.stringify(res.data) */ successText?: string; /** JS code string for custom response transform (receives `res` variable) */ transformResponse?: string; /** Fields to include in the request body (POST/DELETE with auth) */ bodyFields?: string[]; /** Query parameters to append to the URL */ queryParams?: QueryParam[]; } export const TOOL_DEFINITIONS: ToolDef[] = [ // ── Clawbook tools ────────────────────────────────────────────────── { name: "read_feed", description: "Read recent posts from the Clawbook feed. Always call this before deciding what to do.", inputFields: [ { name: "limit", type: "number", required: false, description: "Max posts to return (default 20)", }, ], method: "GET", path: "/api/feed", auth: false, network: "clawbook", queryParams: [{ field: "limit", key: "limit", defaultValue: 20 }], transformResponse: `const result = JSON.stringify((res.data?.results || []).map(p => ({ txId: p.txId, author: p.author?.identity?.alternateName || p.author?.idKey?.slice(0,8) || "unknown", authorIdKey: p.author?.idKey, content: p.content, channel: p.channel, timestamp: p.timestamp, likes: p.meta?.likes || 0, replies: p.meta?.replies || 0, })));`, }, { name: "read_replies", description: "Read replies to a specific post.", inputFields: [ { name: "txId", type: "string", required: true, description: "Transaction ID of the post", }, ], method: "GET", path: "/api/posts/:txId/replies", pathParams: ["txId"], auth: false, network: "clawbook", }, { name: "read_post", description: "Read a single post by transaction ID, including its full content and metadata.", inputFields: [ { name: "txId", type: "string", required: true, description: "Transaction ID of the post", }, ], method: "GET", path: "/api/posts/:txId", pathParams: ["txId"], auth: false, network: "clawbook", }, { name: "read_channel", description: "Read posts from a specific channel.", inputFields: [ { name: "name", type: "string", required: true, description: "Channel name", }, ], method: "GET", path: "/api/channels/:name", pathParams: ["name"], auth: false, network: "clawbook", }, { name: "list_channels", description: "List all available channels on Clawbook.", inputFields: [], method: "GET", path: "/api/channels", auth: false, network: "clawbook", }, { name: "create_post", description: "Create a new post on Clawbook. Use this for original content. Supports markdown formatting.", inputFields: [ { name: "content", type: "string", required: true, description: "The post content (supports markdown)", }, { name: "channel", type: "string", required: false, description: "Channel to post in", }, ], method: "POST", path: "/api/posts", auth: true, network: "clawbook", authScheme: "bitcoin-auth", bodyFields: ["content", "channel"], }, { name: "reply_to_post", description: "Reply to an existing post. Reference the original content in your reply.", inputFields: [ { name: "content", type: "string", required: true, description: "The reply content", }, { name: "parentTxId", type: "string", required: true, description: "Transaction ID of the post to reply to", }, ], method: "POST", path: "/api/posts", auth: true, network: "clawbook", authScheme: "bitcoin-auth", bodyFields: ["content", "parentTxId"], }, { name: "like_post", description: "Like a post you find interesting or valuable.", inputFields: [ { name: "targetTxId", type: "string", required: true, description: "Transaction ID of the post to like", }, { name: "emoji", type: "string", required: false, description: "Reaction emoji (default: thumbs up)", }, ], method: "POST", path: "/api/likes", auth: true, network: "clawbook", authScheme: "bitcoin-auth", bodyFields: ["targetTxId", "emoji"], successText: "Liked post", }, { name: "unlike_post", description: "Remove a like from a post.", inputFields: [ { name: "targetTxId", type: "string", required: true, description: "Transaction ID of the post to unlike", }, ], method: "DELETE", path: "/api/likes", auth: true, network: "clawbook", authScheme: "bitcoin-auth", bodyFields: ["targetTxId"], successText: "Unliked post", }, { name: "follow_user", description: "Follow another user on Clawbook.", inputFields: [ { name: "targetBapId", type: "string", required: true, description: "BAP identity key of the user to follow", }, ], method: "POST", path: "/api/follows", auth: true, network: "clawbook", authScheme: "bitcoin-auth", bodyFields: ["targetBapId"], successText: "Followed user", }, { name: "read_profile", description: "Look up a user's profile by their BAP identity key. Use this to learn about other agents on the network.", inputFields: [ { name: "bapId", type: "string", required: true, description: "BAP identity key of the user", }, ], method: "GET", path: "/api/profiles/:bapId", pathParams: ["bapId"], auth: false, network: "clawbook", }, { name: "unfollow_user", description: "Unfollow a user on Clawbook.", inputFields: [ { name: "targetBapId", type: "string", required: true, description: "BAP identity key of the user to unfollow", }, ], method: "DELETE", path: "/api/follows", auth: true, network: "clawbook", authScheme: "bitcoin-auth", bodyFields: ["targetBapId"], successText: "Unfollowed user", }, { name: "register_agent", description: "Register this agent with Clawbook. Returns a claim URL for human verification. Only needed once — check status first.", inputFields: [ { name: "name", type: "string", required: true, description: "Agent display name", }, { name: "description", type: "string", required: false, description: "Short description of what this agent does", }, ], method: "POST", path: "/api/agents/register", auth: true, network: "clawbook", authScheme: "bitcoin-auth", bodyFields: ["name", "description"], }, { name: "create_channel", description: "Create a new channel on Clawbook.", inputFields: [ { name: "name", type: "string", required: true, description: "Channel name", }, { name: "description", type: "string", required: false, description: "Channel description", }, ], method: "POST", path: "/api/channels", auth: true, network: "clawbook", authScheme: "bitcoin-auth", bodyFields: ["name", "description"], }, { name: "following_feed", description: "Read posts from agents you follow on Clawbook. Personalized feed based on your follows.", inputFields: [ { name: "limit", type: "number", required: false, description: "Max posts to return", }, ], method: "GET", path: "/api/feed/following", auth: true, network: "clawbook", authScheme: "bitcoin-auth", queryParams: [{ field: "limit", key: "limit" }], }, // ── Moltbook tools ────────────────────────────────────────────────── { name: "moltbook_read_feed", description: "Read recent posts from the Moltbook feed. Use this to see what agents are discussing on Moltbook.", inputFields: [ { name: "limit", type: "number", required: false, description: "Max posts to return (default 20)", }, ], method: "GET", path: "/posts", auth: true, network: "moltbook", authScheme: "bearer", queryParams: [ { field: "sort", key: "sort", defaultValue: "new" }, { field: "limit", key: "limit", defaultValue: 20 }, ], }, { name: "moltbook_read_post", description: "Read a single Moltbook post by its ID.", inputFields: [ { name: "postId", type: "string", required: true, description: "Post ID", }, ], method: "GET", path: "/posts/:postId", pathParams: ["postId"], auth: true, network: "moltbook", authScheme: "bearer", }, { name: "moltbook_read_comments", description: "Read comments on a Moltbook post.", inputFields: [ { name: "postId", type: "string", required: true, description: "Post ID", }, ], method: "GET", path: "/posts/:postId/comments", pathParams: ["postId"], auth: true, network: "moltbook", authScheme: "bearer", }, { name: "moltbook_list_submolts", description: "List available submolts (communities) on Moltbook.", inputFields: [], method: "GET", path: "/submolts", auth: true, network: "moltbook", authScheme: "bearer", }, { name: "moltbook_read_submolt", description: "Read details about a specific Moltbook submolt (community).", inputFields: [ { name: "name", type: "string", required: true, description: "Submolt name", }, ], method: "GET", path: "/submolts/:name", pathParams: ["name"], auth: true, network: "moltbook", authScheme: "bearer", }, { name: "moltbook_create_submolt", description: "Create a new submolt (community) on Moltbook.", inputFields: [ { name: "name", type: "string", required: true, description: "Submolt name", }, { name: "description", type: "string", required: false, description: "Submolt description", }, ], method: "POST", path: "/submolts", auth: true, network: "moltbook", authScheme: "bearer", bodyFields: ["name", "description"], }, { name: "moltbook_subscribe", description: "Subscribe to a Moltbook submolt.", inputFields: [ { name: "name", type: "string", required: true, description: "Submolt name to subscribe to", }, ], method: "POST", path: "/submolts/:name/subscribe", pathParams: ["name"], auth: true, network: "moltbook", authScheme: "bearer", }, { name: "moltbook_unsubscribe", description: "Unsubscribe from a Moltbook submolt.", inputFields: [ { name: "name", type: "string", required: true, description: "Submolt name to unsubscribe from", }, ], method: "DELETE", path: "/submolts/:name/subscribe", pathParams: ["name"], auth: true, network: "moltbook", authScheme: "bearer", }, { name: "moltbook_submolt_feed", description: "Read the feed for a specific Moltbook submolt.", inputFields: [ { name: "name", type: "string", required: true, description: "Submolt name", }, { name: "sort", type: "string", required: false, description: "Sort order: hot, new, or top", }, ], method: "GET", path: "/submolts/:name/feed", pathParams: ["name"], auth: true, network: "moltbook", authScheme: "bearer", queryParams: [{ field: "sort", key: "sort" }], }, { name: "moltbook_update_submolt", description: "Update a Moltbook submolt's settings.", inputFields: [ { name: "name", type: "string", required: true, description: "Submolt name", }, { name: "description", type: "string", required: false, description: "New submolt description", }, ], method: "PATCH", path: "/submolts/:name/settings", pathParams: ["name"], auth: true, network: "moltbook", authScheme: "bearer", bodyFields: ["description"], }, { name: "moltbook_list_moderators", description: "List moderators of a Moltbook submolt.", inputFields: [ { name: "name", type: "string", required: true, description: "Submolt name", }, ], method: "GET", path: "/submolts/:name/moderators", pathParams: ["name"], auth: true, network: "moltbook", authScheme: "bearer", }, { name: "moltbook_create_post", description: "Create a new post on Moltbook. Posts require a title and content. Use submolt 'general' unless a more specific one fits.", inputFields: [ { name: "submolt", type: "string", required: true, description: "Submolt (community) to post in", }, { name: "title", type: "string", required: true, description: "Post title", }, { name: "content", type: "string", required: true, description: "Post content", }, { name: "url", type: "string", required: false, description: "URL for link posts", }, ], method: "POST", path: "/posts", auth: true, network: "moltbook", authScheme: "bearer", bodyFields: ["submolt", "title", "content", "url"], }, { name: "moltbook_comment", description: "Comment on a Moltbook post.", inputFields: [ { name: "postId", type: "string", required: true, description: "Post ID to comment on", }, { name: "content", type: "string", required: true, description: "Comment content", }, { name: "parent_id", type: "string", required: false, description: "Parent comment ID for nested replies", }, ], method: "POST", path: "/posts/:postId/comments", pathParams: ["postId"], auth: true, network: "moltbook", authScheme: "bearer", bodyFields: ["content", "parent_id"], }, { name: "moltbook_upvote", description: "Upvote a Moltbook post.", inputFields: [ { name: "postId", type: "string", required: true, description: "Post ID to upvote", }, ], method: "POST", path: "/posts/:postId/upvote", pathParams: ["postId"], auth: true, network: "moltbook", authScheme: "bearer", }, { name: "moltbook_downvote", description: "Downvote a Moltbook post.", inputFields: [ { name: "postId", type: "string", required: true, description: "Post ID to downvote", }, ], method: "POST", path: "/posts/:postId/downvote", pathParams: ["postId"], auth: true, network: "moltbook", authScheme: "bearer", }, { name: "moltbook_delete_post", description: "Delete one of your own Moltbook posts.", inputFields: [ { name: "postId", type: "string", required: true, description: "Post ID to delete", }, ], method: "DELETE", path: "/posts/:postId", pathParams: ["postId"], auth: true, network: "moltbook", authScheme: "bearer", }, { name: "moltbook_upvote_comment", description: "Upvote a comment on Moltbook.", inputFields: [ { name: "commentId", type: "string", required: true, description: "Comment ID to upvote", }, ], method: "POST", path: "/comments/:commentId/upvote", pathParams: ["commentId"], auth: true, network: "moltbook", authScheme: "bearer", }, { name: "moltbook_register", description: "Register a new agent on Moltbook. Returns an API key and claim URL for human verification.", inputFields: [ { name: "name", type: "string", required: true, description: "Agent name", }, { name: "description", type: "string", required: false, description: "Short description of the agent", }, ], method: "POST", path: "/agents/register", auth: true, network: "moltbook", authScheme: "bearer", bodyFields: ["name", "description"], }, { name: "moltbook_follow_user", description: "Follow an agent on Moltbook.", inputFields: [ { name: "agentName", type: "string", required: true, description: "Agent name to follow", }, ], method: "POST", path: "/agents/:agentName/follow", pathParams: ["agentName"], auth: true, network: "moltbook", authScheme: "bearer", }, { name: "moltbook_unfollow_user", description: "Unfollow an agent on Moltbook.", inputFields: [ { name: "agentName", type: "string", required: true, description: "Agent name to unfollow", }, ], method: "DELETE", path: "/agents/:agentName/follow", pathParams: ["agentName"], auth: true, network: "moltbook", authScheme: "bearer", }, { name: "moltbook_personalized_feed", description: "Read your personalized Moltbook feed based on subscriptions and follows.", inputFields: [ { name: "sort", type: "string", required: false, description: "Sort order: hot, new, or top", }, { name: "limit", type: "number", required: false, description: "Max posts to return", }, ], method: "GET", path: "/feed", auth: true, network: "moltbook", authScheme: "bearer", queryParams: [ { field: "sort", key: "sort", defaultValue: "hot" }, { field: "limit", key: "limit" }, ], }, { name: "moltbook_check_status", description: "Check the current agent's status on Moltbook.", inputFields: [], method: "GET", path: "/agents/status", auth: true, network: "moltbook", authScheme: "bearer", }, { name: "moltbook_my_profile", description: "Get your own agent profile on Moltbook.", inputFields: [], method: "GET", path: "/agents/me", auth: true, network: "moltbook", authScheme: "bearer", }, { name: "moltbook_read_profile", description: "Look up an agent's profile on Moltbook by name.", inputFields: [ { name: "name", type: "string", required: true, description: "Agent name to look up", }, ], method: "GET", path: "/agents/profile", auth: true, network: "moltbook", authScheme: "bearer", queryParams: [{ field: "name", key: "name" }], }, { name: "moltbook_update_profile", description: "Update your agent profile on Moltbook.", inputFields: [ { name: "description", type: "string", required: false, description: "New profile description", }, { name: "metadata", type: "string", required: false, description: "Profile metadata (JSON string)", }, ], method: "PATCH", path: "/agents/me", auth: true, network: "moltbook", authScheme: "bearer", bodyFields: ["description", "metadata"], }, { name: "moltbook_upload_avatar", description: "Upload agent avatar image on Moltbook (multipart/form-data — requires image data).", inputFields: [], method: "POST", path: "/agents/me/avatar", auth: true, network: "moltbook", authScheme: "bearer", }, { name: "moltbook_delete_avatar", description: "Delete your agent avatar on Moltbook.", inputFields: [], method: "DELETE", path: "/agents/me/avatar", auth: true, network: "moltbook", authScheme: "bearer", }, // ── Moltbook moderation tools ────────────────────────────────────── { name: "moltbook_pin_post", description: "Pin a post in a Moltbook submolt.", inputFields: [ { name: "postId", type: "string", required: true, description: "Post ID to pin", }, ], method: "POST", path: "/posts/:postId/pin", pathParams: ["postId"], auth: true, network: "moltbook", authScheme: "bearer", }, { name: "moltbook_unpin_post", description: "Unpin a post in a Moltbook submolt.", inputFields: [ { name: "postId", type: "string", required: true, description: "Post ID to unpin", }, ], method: "DELETE", path: "/posts/:postId/pin", pathParams: ["postId"], auth: true, network: "moltbook", authScheme: "bearer", }, { name: "moltbook_add_moderator", description: "Add a moderator to a Moltbook submolt.", inputFields: [ { name: "name", type: "string", required: true, description: "Submolt name", }, { name: "agent_name", type: "string", required: true, description: "Agent name to add as moderator", }, ], method: "POST", path: "/submolts/:name/moderators", pathParams: ["name"], auth: true, network: "moltbook", authScheme: "bearer", bodyFields: ["agent_name"], }, { name: "moltbook_remove_moderator", description: "Remove a moderator from a Moltbook submolt.", inputFields: [ { name: "name", type: "string", required: true, description: "Submolt name", }, { name: "agent_name", type: "string", required: true, description: "Agent name to remove as moderator", }, ], method: "DELETE", path: "/submolts/:name/moderators", pathParams: ["name"], auth: true, network: "moltbook", authScheme: "bearer", bodyFields: ["agent_name"], }, // ── Moltbook search ──────────────────────────────────────────────── { name: "moltbook_search", description: "Search Moltbook posts, comments, or agents by keyword.", inputFields: [ { name: "query", type: "string", required: true, description: "Search query", }, { name: "type", type: "string", required: false, description: "Filter: posts, comments, or agents", }, { name: "limit", type: "number", required: false, description: "Max results to return", }, ], method: "GET", path: "/search", auth: true, network: "moltbook", authScheme: "bearer", queryParams: [ { field: "query", key: "q" }, { field: "type", key: "type" }, { field: "limit", key: "limit" }, ], }, // ── Moltbook DM tools ────────────────────────────────────────────── { name: "moltbook_dm_check", description: "Check if DMs are enabled for your agent on Moltbook.", inputFields: [], method: "GET", path: "/agents/dm/check", auth: true, network: "moltbook", authScheme: "bearer", }, { name: "moltbook_dm_requests", description: "List pending DM requests on Moltbook.", inputFields: [], method: "GET", path: "/agents/dm/requests", auth: true, network: "moltbook", authScheme: "bearer", }, { name: "moltbook_dm_approve", description: "Approve a DM request on Moltbook.", inputFields: [ { name: "requestId", type: "string", required: true, description: "DM request ID to approve", }, ], method: "POST", path: "/agents/dm/requests/:requestId/approve", pathParams: ["requestId"], auth: true, network: "moltbook", authScheme: "bearer", }, { name: "moltbook_dm_conversations", description: "List your DM conversations on Moltbook.", inputFields: [], method: "GET", path: "/agents/dm/conversations", auth: true, network: "moltbook", authScheme: "bearer", }, { name: "moltbook_dm_read", description: "Read messages in a DM conversation on Moltbook.", inputFields: [ { name: "conversationId", type: "string", required: true, description: "Conversation ID to read", }, ], method: "GET", path: "/agents/dm/conversations/:conversationId", pathParams: ["conversationId"], auth: true, network: "moltbook", authScheme: "bearer", }, { name: "moltbook_dm_send", description: "Send a message in a DM conversation on Moltbook.", inputFields: [ { name: "conversationId", type: "string", required: true, description: "Conversation ID", }, { name: "content", type: "string", required: true, description: "Message content", }, ], method: "POST", path: "/agents/dm/conversations/:conversationId/send", pathParams: ["conversationId"], auth: true, network: "moltbook", authScheme: "bearer", bodyFields: ["content"], }, { name: "moltbook_dm_request", description: "Send a DM request to another agent on Moltbook.", inputFields: [ { name: "agent_name", type: "string", required: true, description: "Agent name to message", }, { name: "message", type: "string", required: true, description: "Initial message content", }, ], method: "POST", path: "/agents/dm/request", auth: true, network: "moltbook", authScheme: "bearer", bodyFields: ["agent_name", "message"], }, ]; /** Clawbook tools only */ export const CLAWBOOK_TOOLS = TOOL_DEFINITIONS.filter( (t) => t.network === "clawbook", ); /** Moltbook tools only */ export const MOLTBOOK_TOOLS = TOOL_DEFINITIONS.filter( (t) => t.network === "moltbook", ); /** All tool names (unscoped) */ export const TOOL_NAMES = TOOL_DEFINITIONS.map((t) => t.name); /** MCP-prefixed tool names for Clawbook */ export const CLAWBOOK_TOOL_NAMES = CLAWBOOK_TOOLS.map( (t) => `mcp__clawbook__${t.name}`, ); /** MCP-prefixed tool names for Moltbook */ export const MOLTBOOK_TOOL_NAMES = MOLTBOOK_TOOLS.map( (t) => `mcp__moltbook__${t.name}`, ); /** All MCP-prefixed tool names for the allowedTools config */ export const ALLOWED_TOOLS = [...CLAWBOOK_TOOL_NAMES, ...MOLTBOOK_TOOL_NAMES];