Skip to main content
Glama

get_minimal_context

Read-onlyIdempotent

Get a project's orientation context in one call: project shape, top risk hotspots, central files, communities, and task-aligned next steps. Use at session start instead of chaining multiple tools.

Instructions

Single-call orientation context (~150 tokens). Returns project shape, top 3 risk hotspots, top 3 PageRank-central files, top 3 communities, and 3-5 task-routed next-tool suggestions. Use at session start instead of chaining get_project_map + get_pagerank + get_risk_hotspots + get_communities. The optional task argument biases the suggestions toward review / refactor / debug / add_feature / understand. Read-only. Returns JSON: { project, health, communities, next_steps }.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
taskNoNatural-language description of what you are about to do — drives the next_steps ranking. If omitted, returns the "understand" suggestion set.
intentNoExplicit intent override. Wins over keyword inference from `task`.

Implementation Reference

  • Core handler function that aggregates project shape, health (hotspots + PageRank), communities, and task-routed next_steps into a ~150 token minimal context response.
    export function getMinimalContext(
      store: Store,
      registry: PluginRegistry,
      config: TraceMcpConfig,
      projectRoot: string,
      ctx: ProjectContext,
      options: { task?: string; intent?: NonNullable<MinimalContextTask> } = {},
    ): MinimalContext {
      // 1. Project shape — frameworks + counts.
      const summary = getProjectMap(store, registry, true, ctx);
      const frameworks = (summary.frameworks ?? []).slice(0, 3);
    
      // 2. Health — hotspots + PageRank.
      let topHotspots: Array<{ file: string; score: number }> = [];
      try {
        const hotspotsResult = getHotspots(store, projectRoot, { limit: 3 });
        if (Array.isArray(hotspotsResult)) {
          topHotspots = hotspotsResult.map((h: { file: string; score: number }) => ({
            file: h.file,
            score: Math.round(h.score * 100) / 100,
          }));
        } else if (
          hotspotsResult &&
          typeof hotspotsResult === 'object' &&
          'hotspots' in hotspotsResult
        ) {
          const arr = (hotspotsResult as { hotspots: Array<{ file: string; score: number }> }).hotspots;
          topHotspots = arr.slice(0, 3).map((h) => ({
            file: h.file,
            score: Math.round(h.score * 100) / 100,
          }));
        }
      } catch {
        /* git unavailable — leave empty */
      }
    
      let topCentral: Array<{ file: string; pagerank: number }> = [];
      try {
        const pageRankResult = getPageRank(store, 3);
        const ranked = Array.isArray(pageRankResult) ? pageRankResult : [];
        topCentral = ranked.slice(0, 3).map((r: { file: string; score: number }) => ({
          file: r.file,
          pagerank: Math.round(r.score * 10000) / 10000,
        }));
      } catch {
        /* PageRank not yet computed */
      }
    
      // 3. Communities — already detected; ignore if not yet run.
      let communitiesSummary: MinimalContext['communities'] = { total: 0, top: [] };
      try {
        const c = getCommunities(store);
        if (c.isOk()) {
          const data = c.value;
          communitiesSummary = {
            total: data.communities.length,
            top: data.communities.slice(0, 3).map((cc) => ({
              label: cc.label,
              fileCount: cc.fileCount,
              cohesion: cc.cohesion,
            })),
          };
        }
      } catch {
        /* not detected yet */
      }
    
      // 4. Task-routed next steps. Explicit `intent` wins; otherwise infer from
      //    the natural-language `task` field; otherwise default to `understand`.
      const inferred = options.intent ?? inferTask(options.task);
      const taskKey: NonNullable<MinimalContextTask> = inferred ?? 'understand';
      const next_steps = SUGGESTIONS_BY_TASK[taskKey];
    
      return {
        project: {
          name: summary.name ?? '<unknown>',
          fileCount: summary.fileCount ?? 0,
          symbolCount: summary.symbolCount ?? 0,
          frameworks,
        },
        health: {
          top_hotspots: topHotspots,
          top_central: topCentral,
        },
        communities: communitiesSummary,
        next_steps,
        _meta: {
          task: inferred,
          intent_inferred: !options.intent && !!inferred,
        },
      };
    }
  • Type definitions for MinimalContext interface and MinimalContextTask union type, defining the output shape (project, health, communities, next_steps, _meta).
    export type MinimalContextTask =
      | 'understand'
      | 'review'
      | 'refactor'
      | 'debug'
      | 'add_feature'
      | undefined;
    
    export interface MinimalContext {
      project: {
        name: string;
        fileCount: number;
        symbolCount: number;
        frameworks: string[];
      };
      health: {
        top_hotspots: Array<{ file: string; score: number }>;
        top_central: Array<{ file: string; pagerank: number }>;
      };
      communities: {
        total: number;
        top: Array<{ label: string; fileCount: number; cohesion: number }>;
      };
      next_steps: Array<{ tool: string; args?: Record<string, unknown>; hint: string }>;
      _meta: {
        task: MinimalContextTask;
        intent_inferred: boolean;
      };
    }
  • Task-routed suggestion maps (SUGGESTIONS_BY_TASK) defining next_tool recommendations for each task type (understand/review/refactor/debug/add_feature).
    const SUGGESTIONS_BY_TASK: Record<NonNullable<MinimalContextTask>, MinimalContext['next_steps']> = {
      understand: [
        {
          tool: 'get_task_context',
          args: { task: '<paste the user request verbatim>', focus: 'broad' },
          hint: 'One-call execution context for an unfamiliar task',
        },
        {
          tool: 'get_outline',
          hint: 'Read a file by path — signatures only, ~80% cheaper than Read',
        },
        {
          tool: 'search',
          args: { fusion: true, detail_level: 'minimal' },
          hint: 'Locate a symbol by name; minimal mode keeps the response under 100 tokens',
        },
      ],
      review: [
        {
          tool: 'compare_branches',
          hint: 'Symbol-level diff for the current branch vs main',
        },
        {
          tool: 'get_changed_symbols',
          hint: 'List of changed functions/classes/methods since the merge-base',
        },
        {
          tool: 'check_quality_gates',
          args: { scope: 'changed' },
          hint: 'CI-grade quality check on just the changed surface',
        },
        {
          tool: 'scan_security',
          args: { rules: ['all'] },
          hint: 'OWASP Top-10 sweep before requesting review',
        },
      ],
      refactor: [
        {
          tool: 'assess_change_risk',
          hint: 'Risk score + factors before touching the symbol',
        },
        {
          tool: 'get_change_impact',
          hint: 'Reverse dependency report — what breaks if you change X',
        },
        {
          tool: 'get_refactor_candidates',
          hint: 'High-complexity, multi-caller functions worth extracting',
        },
        {
          tool: 'plan_refactoring',
          hint: 'Preview rename/move/extract/signature changes before applying',
        },
      ],
      debug: [
        {
          tool: 'predict_bugs',
          hint: 'Multi-signal prediction of which files are likely to contain a bug',
        },
        {
          tool: 'get_risk_hotspots',
          hint: 'Files with both high cyclomatic complexity and high git churn',
        },
        {
          tool: 'taint_analysis',
          hint: 'Data-flow trace from untrusted sources to dangerous sinks',
        },
        {
          tool: 'get_call_graph',
          hint: 'Bidirectional view of what reaches the suspect symbol',
        },
      ],
      add_feature: [
        {
          tool: 'plan_turn',
          args: { task: '<one-line description of the feature>' },
          hint: 'Opening-move router — verdict, confidence, scaffolding hints',
        },
        {
          tool: 'check_duplication',
          hint: 'Before creating new functions, check no equivalent already exists',
        },
        {
          tool: 'get_feature_context',
          args: { description: '<feature description>' },
          hint: 'Ranked source snippets relevant to a natural-language description',
        },
      ],
    };
  • inferTask helper function that uses keyword-matching against regex patterns to infer the user's intent (review/refactor/debug/add_feature) from a natural-language task string.
    const INTENT_KEYWORDS: Array<[NonNullable<MinimalContextTask>, RegExp]> = [
      ['review', /\b(review|pr|pull request|approve|merge)\b/i],
      ['refactor', /\b(refactor|rename|extract|move|cleanup|deduplicate)\b/i],
      ['debug', /\b(bug|fix|broken|error|crash|fail|regression|investigate)\b/i],
      ['add_feature', /\b(add|implement|create|new feature|wire up|introduce)\b/i],
    ];
    
    export function inferTask(query: string | undefined): MinimalContextTask {
      if (!query) return undefined;
      for (const [task, re] of INTENT_KEYWORDS) {
        if (re.test(query)) return task;
      }
      return undefined;
    }
  • Tool registration via server.tool() with Zod schemas for 'task' and 'intent' input parameters, and the async handler that calls buildProjectContext + getMinimalContext.
    server.tool(
      'get_minimal_context',
      'Single-call orientation context (~150 tokens). Returns project shape, top 3 risk hotspots, top 3 PageRank-central files, top 3 communities, and 3-5 task-routed next-tool suggestions. Use at session start instead of chaining get_project_map + get_pagerank + get_risk_hotspots + get_communities. The optional `task` argument biases the suggestions toward review / refactor / debug / add_feature / understand. Read-only. Returns JSON: { project, health, communities, next_steps }.',
      {
        task: z
          .string()
          .max(500)
          .optional()
          .describe(
            'Natural-language description of what you are about to do — drives the next_steps ranking. If omitted, returns the "understand" suggestion set.',
          ),
        intent: z
          .enum(['understand', 'review', 'refactor', 'debug', 'add_feature'])
          .optional()
          .describe('Explicit intent override. Wins over keyword inference from `task`.'),
      },
      async ({ task, intent }) => {
        const projectCtx = buildProjectContext(projectRoot);
        const result = getMinimalContext(store, registry, config, projectRoot, projectCtx, {
          task,
          intent,
        });
        return { content: [{ type: 'text', text: j(result) }] };
      },
    );
Behavior4/5

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

Annotations already indicate read-only and idempotent. Description adds return format and details on task-driven behavior, providing useful behavioral context beyond 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?

Two sentences, front-loaded with purpose, then details. No wasted words, efficient and clear.

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

Completeness5/5

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

For a context tool with no output schema, the description adequately specifies return format and covers all key behavioral aspects. With rich annotations, it is complete.

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%, but description adds meaning by explaining task biases next_steps and intent overrides keyword inference. Adds value beyond schema descriptions.

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 clearly states the tool provides 'Single-call orientation context' with specific components (project shape, risk hotspots, etc.) and distinguishes itself from chaining multiple tools.

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

Usage Guidelines4/5

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

Explicitly recommends use 'at session start instead of chaining...' and explains how the task parameter biases suggestions. Does not explicitly list when not to use, but context is clear enough.

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/nikolai-vysotskyi/trace-mcp'

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