UNPKG

systemprompt-mcp-reddit

Version:

A specialized Model Context Protocol (MCP) server that enables you to search, read, and interact with Reddit content, leveraging an AI Agent to help with each operation.

161 lines 7.14 kB
import { formatToolResponse } from "./types.js"; import { RedditError } from "../../types/reddit.js"; import { CREATE_REDDIT_POST_PROMPT } from "../../constants/sampling/index.js"; import { sendSamplingRequest } from "../../handlers/sampling.js"; import { handleGetPrompt } from "../../handlers/prompt-handlers.js"; import { injectVariables } from "../../utils/message-handlers.js"; import { TOOL_ERROR_MESSAGES } from "../../constants/tools.js"; import { createRedditPostSuccessMessage } from "../../constants/tool/create-post.js"; const responseSchema = { type: "object", properties: { status: { type: "string", enum: ["success", "error"] }, message: { type: "string" }, result: { type: "object", properties: { status: { type: "string", enum: ["pending"] }, subreddit: { type: "string" }, post: { type: "object", properties: { subreddit: { type: "string", description: "Subreddit to post to (without r/ prefix)", }, title: { type: "string", description: "Post title (1-300 characters)", minLength: 1, maxLength: 300, }, content: { type: "string", description: "Text content for the post", }, flair: { type: "object", description: "Flair information for the post", properties: { id: { type: "string", description: "ID of the selected flair", }, text: { type: "string", description: "Text of the selected flair", }, }, required: ["id", "text"], }, sendreplies: { type: "boolean", description: "Whether to send replies to inbox", default: true, }, nsfw: { type: "boolean", description: "Whether to mark as NSFW", default: false, }, spoiler: { type: "boolean", description: "Whether to mark as spoiler", default: false, }, }, required: ["subreddit", "title", "content"], }, availableFlairs: { type: "array", description: "List of available flairs for the subreddit", items: { type: "object", properties: { id: { type: "string" }, text: { type: "string" }, type: { type: "string", enum: ["text", "richtext", "image"] }, textEditable: { type: "boolean" }, backgroundColor: { type: "string" }, textColor: { type: "string" }, modOnly: { type: "boolean" }, }, required: ["id", "text", "type"], }, }, }, required: ["status", "subreddit", "post", "availableFlairs"], }, }, required: ["status", "message", "result"], }; export const handleCreateRedditPost = async (args, { systemPromptService, redditService }) => { try { const configBlocks = await systemPromptService.listBlocks(); const instructionsBlock = configBlocks.find((block) => block.prefix === "reddit_instructions"); if (!instructionsBlock) { throw new RedditError("Reddit configuration or instructions not found", "VALIDATION_ERROR"); } // Fetch subreddit info including flairs const subredditInfo = await redditService.getSubredditInfo(args.subreddit); const flairs = await redditService.getSubredditFlairs(args.subreddit); // Convert all values to strings and include configs const stringArgs = { ...Object.fromEntries(Object.entries(args).map(([k, v]) => [k, String(v)])), type: "post", flairRequired: String(subredditInfo.flairRequired || false), availableFlairs: JSON.stringify(flairs), subredditRules: JSON.stringify(subredditInfo), redditInstructions: instructionsBlock.content, redditConfig: JSON.stringify({ allowedPostTypes: subredditInfo.allowedPostTypes, rules: subredditInfo.rules, titleRequirements: subredditInfo.titleRequirements, bodyRequirements: subredditInfo.bodyRequirements, flairRequired: subredditInfo.flairRequired, }), }; const prompt = await handleGetPrompt({ method: "prompts/get", params: { name: CREATE_REDDIT_POST_PROMPT.name, arguments: stringArgs, }, }); const promptResponseSchema = prompt._meta?.responseSchema; if (!promptResponseSchema) { throw new Error(`${TOOL_ERROR_MESSAGES.TOOL_CALL_FAILED} No response schema found`); } await sendSamplingRequest({ method: "sampling/createMessage", params: { messages: CREATE_REDDIT_POST_PROMPT.messages.map((msg) => injectVariables(msg, stringArgs)), maxTokens: 100000, temperature: 0.7, _meta: { callback: "create_post_callback", responseSchema: promptResponseSchema, }, arguments: stringArgs, }, }); return formatToolResponse({ message: createRedditPostSuccessMessage, type: "sampling", title: "Create Reddit Message", }); } catch (error) { return formatToolResponse({ status: "error", message: `Failed to create Reddit post: ${error instanceof Error ? error.message : "Unknown error"}`, error: { type: error instanceof RedditError ? error.type : "API_ERROR", details: error, }, type: "sampling", title: "Error Creating Post", }); } }; //# sourceMappingURL=create-post.js.map