Get a single ISM control
get_controlRetrieve detailed information for a specific ISM control by providing its OSCAL ID or label. Includes title, group path, applicability, and statement.
Instructions
Returns the full detail (title, group path, applicability, statement) for a single ISM control. Accepts either the OSCAL id (e.g. ism-principle-gov-01) or the human label (e.g. GOV-01).
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| controlId | Yes | Either OSCAL id (e.g. "ism-principle-gov-01") or label (e.g. "GOV-01"). | |
| version | No | ||
| format | No |
Implementation Reference
- src/index.ts:295-340 (handler)The get_control tool handler: resolves the version, loads flattened controls, matches by controlId (OSCAL id or label), and returns full control detail in JSON or Markdown format.
server.registerTool( "get_control", { title: "Get a single ISM control", description: "Returns the full detail (title, group path, applicability, statement) for a single ISM control. Accepts either the OSCAL id (e.g. ism-principle-gov-01) or the human label (e.g. GOV-01).", inputSchema: { controlId: z .string() .describe( 'Either OSCAL id (e.g. "ism-principle-gov-01") or label (e.g. "GOV-01").', ), version: z.string().optional(), format: z.enum(["json", "markdown"]).optional(), }, }, async ({ controlId, version, format }) => { const v = await resolveVersion(version); const flat = await loadFlat(v.tag); const match = findControlMatch(flat, controlId); if (!match) { return { isError: true, content: [ { type: "text", text: `No control matched "${controlId}" in ISM ${v.id}.`, }, ], }; } if (format === "markdown") { return txt(controlToMarkdown(match, v.id)); } return txt({ version: v.id, id: match.id, label: match.label, title: match.title, section: match.groupPath, applicability: match.applicability, statement: match.statement, raw: match.raw, }); }, ); - src/index.ts:295-340 (registration)Registration of the get_control tool with the MCP server, including title, description, and input schema.
server.registerTool( "get_control", { title: "Get a single ISM control", description: "Returns the full detail (title, group path, applicability, statement) for a single ISM control. Accepts either the OSCAL id (e.g. ism-principle-gov-01) or the human label (e.g. GOV-01).", inputSchema: { controlId: z .string() .describe( 'Either OSCAL id (e.g. "ism-principle-gov-01") or label (e.g. "GOV-01").', ), version: z.string().optional(), format: z.enum(["json", "markdown"]).optional(), }, }, async ({ controlId, version, format }) => { const v = await resolveVersion(version); const flat = await loadFlat(v.tag); const match = findControlMatch(flat, controlId); if (!match) { return { isError: true, content: [ { type: "text", text: `No control matched "${controlId}" in ISM ${v.id}.`, }, ], }; } if (format === "markdown") { return txt(controlToMarkdown(match, v.id)); } return txt({ version: v.id, id: match.id, label: match.label, title: match.title, section: match.groupPath, applicability: match.applicability, statement: match.statement, raw: match.raw, }); }, ); - src/index.ts:301-309 (schema)Input schema for get_control: requires controlId string, optional version string, and optional format enum (json/markdown).
inputSchema: { controlId: z .string() .describe( 'Either OSCAL id (e.g. "ism-principle-gov-01") or label (e.g. "GOV-01").', ), version: z.string().optional(), format: z.enum(["json", "markdown"]).optional(), }, - src/index.ts:84-91 (helper)Helper used by get_control to match a control by OSCAL id or human label (case-insensitive).
function findControlMatch(flat: FlatControl[], controlId: string): FlatControl | undefined { const needle = controlId.toLowerCase(); return ( flat.find((c) => c.id.toLowerCase() === needle) ?? flat.find((c) => c.label.toLowerCase() === needle) ?? flat.find((c) => c.id.toLowerCase().endsWith(needle)) ); } - src/store.ts:233-253 (helper)Renders a FlatControl as Markdown, used by get_control when format is 'markdown'.
export function controlToMarkdown(c: FlatControl, version: string): string { const lines: string[] = []; lines.push(`# ${c.label} — ${c.title}`); lines.push(""); lines.push(`- **Control ID:** \`${c.id}\``); lines.push(`- **ISM version:** ${version}`); if (c.groupPath.length > 0) { lines.push(`- **Section:** ${c.groupPath.join(" › ")}`); } if (c.applicability.length > 0) { lines.push(`- **Applicability:** ${c.applicability.join(", ")}`); } lines.push(""); if (c.statement) { lines.push("## Statement"); lines.push(""); lines.push(c.statement); lines.push(""); } return lines.join("\n"); }