Skip to main content
Glama
cloudcwfranck

@cloudcraftwithfranck/govcloud-mcp

bicep_analyze

Analyze Azure Bicep code to assess NIST 800-53 compliance, identify security gaps, and calculate FedRAMP/IL4 readiness score.

Instructions

Analyze Azure Bicep IaC code for NIST 800-53 Rev 5 compliance coverage. Returns controls addressed, gaps, security findings, and overall FedRAMP/IL4 readiness score.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
bicepCodeYesThe Bicep code to analyze
targetLevelNoCompliance target level (default: fedramp-high)

Implementation Reference

  • Main handler function for bicep_analyze. Validates input via Zod schema, calls the external site API with bicepCode and targetLevel, and formats the analysis result as a markdown string.
    export async function handleBicepAnalyze(args: unknown): Promise<string> {
      return runTool('bicep_analyze', args, Schema, async ({ bicepCode, targetLevel }) => {
        const data = (await callSiteApi('/api/bicep-analyze', {
          bicepCode,
          targetLevel,
        })) as AnalysisResult;
    
        return formatAnalysis(data, targetLevel ?? 'fedramp-high');
      });
    }
  • Zod validation schema for bicep_analyze: bicepCode (required, 1-20000 chars) and targetLevel (optional enum, defaults to fedramp-high).
    const Schema = z.object({
      bicepCode: z.string().min(1).max(20000),
      targetLevel: z
        .enum(['fedramp-moderate', 'fedramp-high', 'il4', 'il5'])
        .default('fedramp-high'),
    });
  • Tool dispatch registration: routes the 'bicep_analyze' tool name to handleBicepAnalyze in the main tool handler switch statement.
    export async function handleToolCall(name: string, args: unknown): Promise<string> {
      switch (name) {
        case 'bicep_analyze':         return handleBicepAnalyze(args);
        case 'bicep_remediate':       return handleBicepRemediate(args);
        case 'control_lookup':        return handleControlLookup(args);
        case 'control_narrative':     return handleControlNarrative(args);
        case 'poam_generate':         return handlePoamGenerate(args);
        case 'ato_readiness':         return handleAtoReadiness(args);
        case 'oscal_fragment':        return handleOscalFragment(args);
        case 'landing_zone_design':   return handleLandingZone(args);
        case 'landing_zone_reference': return handleLandingZoneReference(args);
        case 'azure_service_selector': return handleServiceSelect(args);
        case 'gcc_high_guidance':     return handleGccHigh(args);
        case 'private_endpoint_map':  return handlePrivateEndpoint(args);
        case 'bigbang_validate':      return handleBigbangValidate(args);
        case 'bigbang_harden':        return handleBigbangHarden(args);
        case 'ironbank_lookup':       return handleIronbankLookup(args);
        case 'addon_configurator':    return handleAddonConfigurator(args);
        case 'pipeline_audit':        return handlePipelineAudit(args);
        case 'signing_config':        return handleSigningConfig(args);
        case 'devsecops_scorecard':   return handleDevsecopsScorecard(args);
        case 'ssp_section':           return handleSspSection(args);
        case 'contingency_plan':      return handleContingencyPlan(args);
        case 'govcloud_quickstart':   return handleGovcloudQuickstart(args);
        default:
          throw new Error(`Unknown tool: ${name}`);
      }
    }
  • Tool list registration: bicepAnalyzeTool is included in the allTools array that populates the MCP server's tool list.
    export const allTools = [
      // Compliance
      bicepAnalyzeTool,
  • Helper function that formats the AnalysisResult (controls covered/partial/missing, security findings, overall score) into a markdown table for the MCP response.
    function formatAnalysis(data: AnalysisResult, targetLevel: string): string {
      const { controlsCovered, controlsPartial, controlsMissing, securityFindings, overallScore } = data;
      const lines: string[] = [];
    
      lines.push(`## Bicep Compliance Analysis — ${targetLevel.toUpperCase()}`);
      lines.push('');
      lines.push(`### Overall Score: ${overallScore.score}/100 — ${overallScore.fedrampReadiness}`);
      lines.push(`**IL4 Ready:** ${overallScore.il4Ready ? 'Yes ✓' : 'No ✗'}`);
      lines.push('');
      lines.push(`> ${overallScore.summary}`);
      lines.push('');
    
      if (controlsCovered.length > 0) {
        lines.push(`### Controls Addressed (${controlsCovered.length})`);
        lines.push('');
        lines.push('| Control ID | Control Name | Azure Service |');
        lines.push('|-----------|-------------|--------------|');
        for (const c of controlsCovered) {
          lines.push(`| ${c.controlId} | ${c.controlName} | ${c.azureService ?? '—'} |`);
        }
        lines.push('');
      }
    
      if (controlsPartial.length > 0) {
        lines.push(`### Partial Controls — Gaps Present (${controlsPartial.length})`);
        lines.push('');
        lines.push('| Control ID | Gap | Remediation | Severity |');
        lines.push('|-----------|-----|-------------|----------|');
        for (const c of controlsPartial) {
          lines.push(`| ${c.controlId} | ${c.gap ?? '—'} | ${c.remediation ?? '—'} | ${c.severity ?? '—'} |`);
        }
        lines.push('');
      }
    
      if (controlsMissing.length > 0) {
        const critical = controlsMissing.filter((c) => c.severity === 'critical');
        const others = controlsMissing.filter((c) => c.severity !== 'critical');
    
        if (critical.length > 0) {
          lines.push(`### Missing Controls — Critical (${critical.length})`);
          lines.push('');
          lines.push('| Control ID | Control Name | Reason | Remediation |');
          lines.push('|-----------|-------------|--------|-------------|');
          for (const c of critical) {
            lines.push(`| ${c.controlId} | ${c.controlName} | ${c.reason ?? '—'} | ${c.remediation ?? '—'} |`);
          }
          lines.push('');
        }
    
        if (others.length > 0) {
          lines.push(`### Missing Controls — Other (${others.length})`);
          lines.push('');
          lines.push('| Control ID | Control Name | Severity | Remediation |');
          lines.push('|-----------|-------------|----------|-------------|');
          for (const c of others) {
            lines.push(`| ${c.controlId} | ${c.controlName} | ${c.severity ?? '—'} | ${c.remediation ?? '—'} |`);
          }
          lines.push('');
        }
      }
    
      if (securityFindings.length > 0) {
        lines.push(`### Security Findings (${securityFindings.length})`);
        lines.push('');
        lines.push('| Severity | Finding | Affected Resource | Fix |');
        lines.push('|----------|---------|------------------|-----|');
        for (const f of securityFindings) {
          lines.push(`| ${f.severity.toUpperCase()} | ${f.finding} | ${f.affectedResource} | ${f.fix} |`);
        }
        lines.push('');
      }
    
      return lines.join('\n');
    }
Behavior3/5

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

No annotations are provided, so the description bears full responsibility. It discloses outputs (controls addressed, gaps, findings, readiness score) but does not mention side effects, authorization requirements, rate limits, or whether the operation is read-only. As an analysis tool, read-only is likely, but not stated.

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, focused sentence that front-loads the purpose and key outputs. Every word is necessary; no extraneous content.

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 explains what the tool returns (controls, gaps, findings, readiness score), compensating for the lack of an output schema. It covers the core functionality. Minor omission: does not mention output format or severity levels, but it is adequate for a compliance analysis tool.

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

Parameters3/5

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

Schema coverage is 100% with both parameters documented. The description does not add additional meaning beyond the schema; it only provides broader context of compliance analysis. Baseline 3 is appropriate as the description does not compensate for any gaps.

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's purpose: 'Analyze Azure Bicep IaC code for NIST 800-53 Rev 5 compliance coverage.' It specifies the resource (Bicep code) and action (analyze) and mentions specific outputs (controls addressed, gaps, security findings, readiness score). This distinguishes it from sibling tools like bicep_remediate (likely remediation) and others.

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 you need compliance analysis of Bicep code, but it does not explicitly state when to use this versus alternatives (e.g., bicep_remediate for fixes). There is no when-not-to-use guidance. The sibling list provides context, but the description itself lacks explicit usage boundaries.

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/cloudcwfranck/govcloud-mcp'

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