AdmissibleAI

Anthropic Quickstart

Route Claude client-side Tool Use through Admissible before local tools run. This quickstart shows an allowed read and a durable email tool blocked at commit admission before the side effect executes.

Status: Experimental. Admissible governs client-side Claude Tool Use, not Anthropic server-executed tools.

Ready to integrate this into a real app? Read the full docs.

Prerequisites

This quickstart is for the experimental Anthropic integration preview. The package is published under @admissible-ai/anthropic.

  • Node.js 18 or later and npm
  • An Anthropic API key
  • Admissible API URL
  • ADMISSIBLE_API_KEY
  • Claude client-side Tool Use in your application

Need an API key? Create a Sandbox account.

Quickstart

Start with the native helper. It owns the Claude tool_use and tool_result loop for client-side tools.

  1. Confirm integration preview status

    Status: @admissible-ai/anthropic is published and remains experimental. Treat this page as integration preview guidance.

    Command

    # @admissible-ai/anthropic is published and experimental.# Treat this page as integration preview guidance.
  2. Install dependencies

    This package is published, but the Anthropic integration remains experimental.

    Command

    npm install @admissible-ai/anthropic @admissible-ai/sdk @anthropic-ai/sdk
  3. Set environment variables

    ADMISSIBLE_API_URL must include http:// or https://. Compatibility fallbacks are ADMISSIBLE_BASE_URL, then BASELINE_BASE_URL.

    Command

    export ANTHROPIC_API_KEY="your-anthropic-api-key"export ADMISSIBLE_API_URL="https://api.admissible.io"export ADMISSIBLE_API_KEY="your-admissible-api-key"
  4. Create the Admissible Anthropic client

    The native helper owns the Claude tool_use -> tool_result loop for client-side tools.

    Command

    const client = createAdmissibleAnthropic({  anthropic,  admissible,  agentId: "claude-tool-agent",  sessionId: "session-123",  environmentName: "staging",  tools: [readReleaseStatus, sendCustomerEmail],});
  5. Define a safe read tool

    Read-only tools are evaluated through /v2/execute before the local run function executes.

    Command

    const readReleaseStatus = {  name: "read_release_status",  description: "Read the current release status for a service.",  input_schema: {    type: "object",    properties: { service: { type: "string" } },    required: ["service"],  },  async run(input) {    return { service: input.service, status: "ready" };  },};
  6. Define a durable tool

    The commit plan makes the external side effect explicit, so /v2/commit can admit, defer, or deny before the side effect runs.

    Command

    const sendCustomerEmail = {  name: "send_customer_email",  description: "Send a customer-facing email.",  input_schema: {    type: "object",    properties: {      to: { type: "string" },      body: { type: "string" },    },    required: ["to", "body"],  },  commit: {    type: "external",    system: "email",    payload: (input) => input,    rollbackRef: "email:not-sent-yet",  },  async run(input) {    return { accepted: true, to: input.to };  },};
  7. Run Claude client-side Tool Use through Admissible

    The helper forwards tool definitions to Claude, handles tool_use blocks, and sends tool_result blocks back to Claude.

    Command

    const response = await client.messages.create({  model: "claude-sonnet-4-5",  max_tokens: 1024,  messages: [    {      role: "user",      content: "Check payments and send the customer email if it is ready.",    },  ],});
  8. Observe allowed execute

    The read tool should show execute allow before the local read returns data.

    Command

    for (const execution of response.admissible.toolExecutions) {  console.log(execution.toolName, execution.executeResponse?.decision);}
  9. Observe commit denial before side effect

    A denied or deferred commit produces a Claude tool_result with is_error: true and the durable run function is not called.

    Command

    console.log(  response.admissible.toolExecutions.map((execution) => ({    tool: execution.toolName,    execute: execution.executeResponse?.decision,    commit: execution.commitResponse?.decision ?? "n/a",    error: execution.toolResult.is_error === true,  })),);
  10. Inspect the result and audit trail

    Claude sees the blocked tool_result, and your app keeps the Admissible execution and commit records.

    Command

    console.log(response.content);console.log(client.getToolExecutionHistory());
  11. Use the low-level helper only when you own the loop

    Most applications should start with createAdmissibleAnthropic. The low-level helper is for custom message-loop control.

    Command

    const managed = createAdmissibleAnthropicTools(tools, { admissible });const executions = await managed.handleToolUses(toolUses);// Send these as the immediate next user message after Claude's tool_use response.const toolResults = executions.map((execution) => execution.toolResult);

What this run does

This example creates an Admissible Anthropic client, defines one safe read tool and one durable external tool, then lets Claude request those tools through the native message-loop helper.

  • Claude returns tool_use blocks for client-side tools.
  • Admissible evaluates each proposed tool call through /v2/execute before local application code runs.
  • Durable tools call /v2/commit before the external side effect, so commit deny or defer returns an error tool_result to Claude.

Anthropic integration surface

const client = createAdmissibleAnthropic({  anthropic,  admissible,  tools: [readReleaseStatus, sendCustomerEmail],});const response = await client.messages.create({  model: "claude-sonnet-4-5",  messages,});

What you should see

A successful first run should make the allowed path and the runtime decision easy to spot.

  • read_release_status execute decision is allow
  • send_customer_email execute decision is allow
  • send_customer_email commit decision is deny or defer in restricted staging policy
  • the local fake email side effect does not run when commit is denied
  • Claude receives the blocked tool_result and explains the commit denial