Skip to main content
Glama
Connectry-io

Connectry Architect Cert

Official

scaffold_project

Get instructions for a hands-on reference project to practice certification concepts. Specify a project ID or leave blank to see available projects.

Instructions

Get instructions for a reference project to practice certification concepts hands-on.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
projectIdNoProject ID (e.g. "capstone", "d1-agentic"). Omit to see available projects.

Implementation Reference

  • The registerScaffoldProject function registers the 'scaffold_project' tool on the MCP server. The handler logic: if no projectId is provided, lists available projects; otherwise it looks up the project in a predefined list, reads its README.md and lists all files recursively, then returns a formatted response with the project info, README content, file listing, and next steps guidance.
    export function registerScaffoldProject(server: McpServer, _db: Database.Database, _userConfig: UserConfig): void {
      server.tool(
        'scaffold_project',
        'Get instructions for a reference project to practice certification concepts hands-on.',
        { projectId: z.string().optional().describe('Project ID (e.g. "capstone", "d1-agentic"). Omit to see available projects.') },
        async ({ projectId }) => {
          if (!projectId) {
            const lines = [
              '═══ REFERENCE PROJECTS ═══',
              '',
              ...PROJECTS.map(p => `  ${p.id}: ${p.name} (Domains: ${p.domains.join(', ')})`),
            ];
            return { content: [{ type: 'text' as const, text: lines.join('\n') }] };
          }
    
          const project = PROJECTS.find(p => p.id === projectId);
          if (!project) {
            return {
              content: [{ type: 'text' as const, text: `Project "${projectId}" not found. Use scaffold_project without arguments to see available projects.` }],
              isError: true,
            };
          }
    
          const projectDir = path.join(PROJECTS_DIR, projectId);
          if (!fs.existsSync(projectDir)) {
            return {
              content: [{ type: 'text' as const, text: `Project directory for "${project.name}" not found. The project files may not be installed yet.` }],
              isError: true,
            };
          }
    
          const readmePath = path.join(projectDir, 'README.md');
          const readme = fs.existsSync(readmePath)
            ? fs.readFileSync(readmePath, 'utf-8')
            : null;
    
          const files = listFilesRecursive(projectDir);
    
          const sections = [
            `═══ ${project.name} ═══`,
            '',
            `Domains: ${project.domains.join(', ')}`,
            '',
          ];
    
          if (readme) {
            sections.push('--- README ---', '', readme, '');
          }
    
          sections.push(
            '--- Project Files ---',
            '',
            ...files.map(f => `  ${f}`),
            '',
            '--- Next Steps ---',
            '',
            'Explore the project files above to understand the architecture.',
            'Each file demonstrates certification concepts in practice.',
            `Project root: projects/${projectId}/`,
          );
    
          return {
            content: [{ type: 'text' as const, text: sections.join('\n') }],
          };
        }
      );
    }
  • Input schema: projectId is an optional string described as 'Project ID (e.g. "capstone", "d1-agentic"). Omit to see available projects.' Defined via Zod with z.string().optional().
    { projectId: z.string().optional().describe('Project ID (e.g. "capstone", "d1-agentic"). Omit to see available projects.') },
  • The tool is registered by calling registerScaffoldProject(server, db, userConfig) inside the registerTools() function, which is the central registration point for all tools.
    registerScaffoldProject(server, db, userConfig);
  • Import statement for registerScaffoldProject from './scaffold-project.js'.
    import { registerScaffoldProject } from './scaffold-project.js';
  • Helper function listFilesRecursive that recursively walks a directory and returns a flat list of relative file paths, used to list all project files.
    function listFilesRecursive(dir: string, prefix = ''): readonly string[] {
      if (!fs.existsSync(dir)) return [];
      const entries = fs.readdirSync(dir, { withFileTypes: true });
      return entries.flatMap((entry): readonly string[] => {
        const relativePath = prefix ? `${prefix}/${entry.name}` : entry.name;
        if (entry.isDirectory()) {
          return listFilesRecursive(path.join(dir, entry.name), relativePath);
        }
        return [relativePath];
      });
    }
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are present, so the description carries full burden. It indicates a read-only operation ('Get instructions'), but does not disclose behavior for invalid projectId or any side effects. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence with no wasted words. It conveys the tool's purpose and parameter usage efficiently.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description is adequate for a simple tool with one parameter. It lacks details about the return format or what 'instructions' entail, but given no output schema, the description provides sufficient context for an agent to understand its basic function.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% for the single parameter 'projectId'. The description adds the instruction 'Omit to see available projects', which clarifies a special behavior not evident from the schema alone.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description specifies the verb 'Get', resource 'instructions for a reference project', and purpose 'to practice certification concepts hands-on'. It clearly distinguishes from siblings like get_curriculum or get_dashboard.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies use when needing hands-on practice but does not explicitly state when to use this tool versus alternatives like get_curriculum or get_practice_question. No exclusions or alternative tool names are provided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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/Connectry-io/connectrylab-architect-cert-mcp'

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