goalstory_read_stories
Retrieve personalized stories for a specific goal and step to enhance reflection and motivation, supporting achievement through structured storytelling.
Instructions
Access the collection of personalized stories created for a specific goal/step pair, supporting reflection and motivation.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| goal_id | Yes | Unique identifier of the goal whose stories to retrieve. | |
| limit | No | Maximum number of stories to return per page. | |
| page | No | Page number for viewing subsets of stories (starts at 1). | |
| step_id | Yes | Unique identifier of the step whose stories to retrieve. |
Implementation Reference
- src/index.ts:678-700 (handler)The MCP tool handler implementation for 'goalstory_read_stories'. It constructs query parameters for goal_id and step_id (with optional pagination), makes a GET request to the backend API /stories endpoint using the doRequest helper, and returns the stories data formatted as text content.server.tool( READ_STORIES_TOOL.name, READ_STORIES_TOOL.description, READ_STORIES_TOOL.inputSchema.shape, async (args) => { const params = new URLSearchParams(); params.set("goal_id", args.goal_id); params.set("step_id", args.step_id); if (args.page) params.set("page", `${args.page}`); if (args.limit) params.set("limit", `${args.limit}`); const url = `${GOALSTORY_API_BASE_URL}/stories?${params.toString()}`; const result = await doRequest(url, "GET"); return { content: [ { type: "text", text: `Stories:\n${JSON.stringify(result, null, 2)}`, }, ], isError: false, }; }, );
- src/tools.ts:375-395 (schema)Zod input schema definition and tool metadata (name, description) for the 'goalstory_read_stories' tool, used during registration in index.ts.export const READ_STORIES_TOOL = { name: "goalstory_read_stories", description: "Access the collection of personalized stories created for a specific goal/step pair, supporting reflection and motivation.", inputSchema: z.object({ goal_id: z .string() .describe("Unique identifier of the goal whose stories to retrieve."), step_id: z .string() .describe("Unique identifier of the step whose stories to retrieve."), page: z .number() .optional() .describe("Page number for viewing subsets of stories (starts at 1)."), limit: z .number() .optional() .describe("Maximum number of stories to return per page."), }), };
- src/types.ts:108-113 (schema)TypeScript interface defining the input shape for the 'goalstory_read_stories' tool, matching the Zod schema.export interface GoalstoryReadStoriesInput { goal_id: string; step_id: string; page?: number; limit?: number; }
- src/index.ts:36-43 (registration)Imports the READ_STORIES_TOOL constant from tools.ts, which is then used to register the tool in the MCP server.READ_STORIES_TOOL, SET_STEPS_ORDER_TOOL, UPDATE_GOAL_TOOL, UPDATE_SCHEDULED_STORY_TOOL, UPDATE_SELF_USER_TOOL, UPDATE_STEP_NOTES_TOOL, UPDATE_STEP_TOOL, } from "./tools.js";
- src/index.ts:62-122 (helper)Generic HTTP request helper function used by all tool handlers, including 'goalstory_read_stories', to make authenticated API calls to the GoalStory backend.async function doRequest<T = any>( url: string, method: string, body?: unknown, ): Promise<T> { console.error("Making request to:", url); console.error("Method:", method); console.error("Body:", body ? JSON.stringify(body) : "none"); try { const response = await axios({ url, method, headers: { "Content-Type": "application/json", Authorization: `Bearer ${GOALSTORY_API_TOKEN}`, }, data: body, timeout: 10000, // 10 second timeout validateStatus: function (status) { return status >= 200 && status < 500; // Accept all status codes less than 500 }, }); console.error("Response received:", response.status); return response.data as T; } catch (err) { console.error("Request failed with error:", err); if (axios.isAxiosError(err)) { if (err.code === "ECONNABORTED") { throw new Error( `Request timed out after 10 seconds. URL: ${url}, Method: ${method}`, ); } if (err.response) { // The request was made and the server responded with a status code // that falls out of the range of 2xx throw new Error( `HTTP Error ${ err.response.status }. URL: ${url}, Method: ${method}, Body: ${JSON.stringify( body, )}. Error text: ${JSON.stringify(err.response.data)}`, ); } else if (err.request) { // The request was made but no response was received throw new Error( `No response received from server. URL: ${url}, Method: ${method}`, ); } else { // Something happened in setting up the request that triggered an Error throw new Error(`Request setup failed: ${err.message}`); } } else { // Something else happened throw new Error( `Unexpected error: ${err instanceof Error ? err.message : String(err)}`, ); } } }