Skip to main content
Glama

suggest-headings

Generate structured headings for Things 3 projects based on project goals and work type to organize tasks effectively.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
project_uuidNoOptional project UUID to inspect existing headings first
project_titleNoProject title if project_uuid is not available
goalNoShort description of what the project is trying to achieve
work_typeNoOptional category like design, software, content, workshop, personal
preferred_countNoPreferred number of headings to suggest

Implementation Reference

  • The "suggest-headings" tool implementation, which generates suggested headings for a project based on its title, goal, and work type, while taking existing headings into account if a project UUID is provided.
      "suggest-headings",
      {
        project_uuid: z
          .string()
          .optional()
          .describe("Optional project UUID to inspect existing headings first"),
        project_title: z
          .string()
          .optional()
          .describe("Project title if project_uuid is not available"),
        goal: z
          .string()
          .optional()
          .describe("Short description of what the project is trying to achieve"),
        work_type: z
          .string()
          .optional()
          .describe("Optional category like design, software, content, workshop, personal"),
        preferred_count: z
          .number()
          .int()
          .min(3)
          .max(8)
          .optional()
          .describe("Preferred number of headings to suggest"),
      },
      async ({ project_uuid, project_title, goal, work_type, preferred_count }) => {
        const data = await withDatabase((db) => {
          const tasks = getAllTasks(db);
          const project = project_uuid
            ? tasks.find((task) => task.type === "project" && task.id === project_uuid)
            : undefined;
          const existingHeadings = project_uuid
            ? tasks
                .filter(
                  (task) =>
                    task.type === "heading" &&
                    task.projectId === project_uuid &&
                    !task.trashed
                )
                .map((task) => task.title)
            : [];
    
          return {
            projectTitle: project?.title ?? project_title ?? "",
            existingHeadings,
          };
        }).catch(() => ({
          projectTitle: project_title ?? "",
          existingHeadings: [] as string[],
        }));
    
        const baseSuggestions = inferHeadingTemplate({
          projectTitle: data.projectTitle,
          goal,
          workType: work_type,
        });
        const suggestedHeadings = uniqueHeadingNames(
          preferred_count ? baseSuggestions.slice(0, preferred_count) : baseSuggestions
        );
        const existingNormalized = new Set(
          data.existingHeadings.map((heading) => normalizeHeadingName(heading))
        );
        const missingHeadings = suggestedHeadings.filter(
          (heading) => !existingNormalized.has(normalizeHeadingName(heading))
        );
    
        const isExistingProject = Boolean(project_uuid);
    
        return buildTextResponse("Suggested heading structure for the project", {
          projectUuid: project_uuid ?? null,
          projectTitle: data.projectTitle || project_title || null,
          goal: goal ?? null,
          workType: work_type ?? null,
          existingHeadings: data.existingHeadings,
          suggestedHeadings,
          missingHeadings,
          creationMode: isExistingProject ? "existing-project" : "new-project",
          requiresManualCreation: isExistingProject && missingHeadings.length > 0,
          preferredCreationTool: isExistingProject ? null : "create-project-with-headings",
          userInstruction: isExistingProject
            ? (missingHeadings.length === 0
                ? "The existing project already has the suggested heading structure. You can continue creating or moving tasks into those headings."
                : buildHeadingCreationPrompt({
                    projectTitle: data.projectTitle || project_title,
                    suggestedHeadings,
                    missingHeadings,
                  }))
            : buildNewProjectStructurePrompt({
                projectTitle: data.projectTitle || project_title,
                suggestedHeadings,
              }),
          followUpInstruction: isExistingProject
            ? "If headings are missing in an existing project, ask the user to create them manually, then call get-headings or validate-headings before creating or moving tasks into them."
            : "For a new project, prefer create-project-with-headings or the JSON tool to create the project, headings, and optional to-dos in one operation.",
        });
      }
    );

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/soycanopa/SupaThings-MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server