MCP TypeScript SDK
@autociso/mcp-client is the first-party TypeScript SDK for the AutoCISO MCP server. It gives you a typed method per tool, autocomplete, and built-in retries — no raw JSON-RPC.
Install
npm install @autociso/mcp-client
Create a client
baseUrl is required — there is no default, because AutoCISO runs in multiple environments. Pass the full URL including /mcp:
import { AutocisoMcpClient } from '@autociso/mcp-client';
const client = new AutocisoMcpClient({
baseUrl: 'https://api.autociso.io/mcp',
token: process.env.AUTOCISO_MCP_TOKEN!, // mcp:read scope
});First call
Every tool maps to a namespaced, camelCase method. Here’s posture_summary:
import { AutocisoMcpClient } from '@autociso/mcp-client';
const client = new AutocisoMcpClient({
baseUrl: 'https://api.autociso.io/mcp',
token: process.env.AUTOCISO_MCP_TOKEN!,
});
const posture = await client.posture.summary();
console.log('Overall score:', posture.overallScore);
const stale = await client.access.staleAccounts();
console.log('Stale accounts:', stale.length);Results are PII-masked — emails appear as a***@domain.com and personal names are redacted (to resolve an employeeId to a name, see Employee identity):
{
"overallScore": 72,
"staleAccounts": 14,
"openRisks": 6,
"isoGapsOpen": 23,
"topConcern": "14 stale accounts pending review"
}
Typed results
Methods for typed tools return ToolResult<XResult>, for example ToolResult<UarStatusResult>; the .data you read is now typed. Tools without a published schema stay unknown. The client reads structuredContent when the server sends it and falls back to the text block otherwise.
If a result does not match its type the SDK throws ResultShapeError. It names the tool and the received typeof only, never values. The client no longer runs the upstream MCP client’s schema validation, which could put result values in error text.
One type-level change: casting .data straight to an unrelated type, such as res.data as MyType, now fails to compile with TS2352. Cast through unknown (res.data as unknown as MyType) or use the generated result type.
Patterns
- Typed method per tool.
client.access.staleAccounts(),client.risk.get({ id }),client.iso.gapStatus()— autocomplete shows every tool and its arguments. See the Tool Catalog for the full list. - No
org_id, ever. Your org is bound to the token on the server (see Org binding). The method signatures don’t accept an org argument — there’s no way to query another tenant. This is by design. - Retries on reads. Idempotent read calls retry automatically on
429and transient errors with exponential backoff and jitter (capped at ~3 attempts). - Writes are not auto-retried. There are five write tools (
risk_create_draft,iso_audit_simulate,supplier_questionnaire_clone,supplier_questionnaire_update_question,supplier_questionnaire_update_option), for exampleclient.risk.createDraft({ title }). None is ever retried automatically: the server has no idempotency key, so a blind retry could create a duplicate or spend a second AI request. - Timeout override. Pass a per-call timeout if a tool is slow:
const risks = await client.risk.registerList({ timeoutMs: 10_000 });callRawescape hatch. For a tool the typed surface doesn’t cover yet, call it by name. The result is untyped (unknown):
const raw = await client.callRaw('audit_trail_search', { limit: 25, offset: 0 });
// raw is unknown — validate before useError handling
Tool failures surface as typed exceptions (e.g. AutocisoScopeError, AutocisoRateLimitError). See MCP Errors and Retries for the full code-to-exception mapping and retry behavior.
Was this page helpful?