Skip to content
1Claw Academy
Curriculum/Integrations & Ecosystem3 minIntermediate · Lesson 7 of 11

Give a LangChain agent vault access

Wrap the 1Claw SDK in a LangChain tool so an agent fetches a vault secret on demand.

This example lets a LangChain agent decide when to list and fetch vault secrets. You define custom tools that wrap @1claw/sdk, and the LLM calls them just in time so raw values never sit in the prompt.

Concept

Prerequisites: Node.js 20+, a 1Claw account with a vault containing at least one secret, and one LLM key (OPENAI_API_KEY or a Gemini free tier GOOGLE_API_KEY).

  1. 1

    Clone the examples repository and install dependencies.

    bash
    git clone https://github.com/1clawAI/1claw-examples.git
    cd 1claw-examples/langchain-agent
    npm install
    cp .env.example .env
  2. 2

    Fill in .env with your 1Claw and LLM credentials. npm start uses ONECLAW_API_KEY (user key), while npm run mcp uses ONECLAW_AGENT_API_KEY (agent key).

    text
    ONECLAW_API_KEY=1ck_your_user_key_here
    ONECLAW_VAULT_ID=your-vault-uuid
    ONECLAW_AGENT_API_KEY=ocv_your_agent_key_here
    GOOGLE_API_KEY=your-gemini-key
  3. 3

    If your vault is empty, add a test secret with the CLI.

    bash
    1claw secret set demo/hello-world --vault $ONECLAW_VAULT_ID --value "Hello from 1Claw!" --type generic
  4. 4

    Note the tool pattern: a DynamicStructuredTool wraps the SDK client so the agent can list secrets. BASE_URL, API_KEY, and VAULT_ID are defined from environment variables at the top of the file.

    typescript
    import { DynamicStructuredTool } from "@langchain/core/tools";
    import { createClient } from "@1claw/sdk";
    import { z } from "zod";
    
    const BASE_URL = process.env.ONECLAW_BASE_URL || "https://api.1claw.co";
    const API_KEY = process.env.ONECLAW_API_KEY!;
    const VAULT_ID = process.env.ONECLAW_VAULT_ID!;
    
    const client = createClient({ baseUrl: BASE_URL, apiKey: API_KEY });
    
    const listSecretsTool = new DynamicStructuredTool({
      name: "list_vault_secrets",
      description: "List all secrets in the vault (metadata only, never values).",
      schema: z.object({}),
      func: async () => {
        const res = await client.secrets.list(VAULT_ID);
        return res.data.secrets.map(s => `${s.path} (${s.type})`).join("\n");
      },
    });
  5. 5

    Run the tool-calling agent.

    bash
    npm start
Tip

Run npm run mcp instead to connect LangChain to the hosted 1Claw MCP server, which loads all 141 tools with zero manual tool definitions. That path needs ONECLAW_AGENT_API_KEY and OPENAI_API_KEY.

Your LangChain agent now lists vault secrets through the SDK tool and reports paths and types without leaking the value.

What this gives you, and what it does not. Wrapping the SDK in tools lets the model decide when to fetch a secret, which is a real capability and a real widening.

  • A tool the model can call is a tool an injection can call. Tool-calling moves the decision from your code to the model, so tool scope becomes the security boundary.
  • Returning a value puts it in context. A tool that fetches a secret and returns it has published that secret to the conversation, its history and the provider. Prefer tools that act rather than tools that reveal.
  • The published package exists. langchain-1claw ships ready-made tools with names like oneclaw_get_secret and oneclaw_list_secrets, so hand-written wrappers are a choice rather than a requirement.
Tip

The safest LangChain tool for a vault is one that lists metadata rather than one that returns values. If the agent needs a credential to make a call, an Execution Intents binding does that without the value entering context.

Decide

You are giving a LangChain agent the ability to use a partner API key. Two designs are on the table: a get_secret tool that returns the key so the agent can build the call itself, or a call_partner_api tool that makes the request and returns only the result.

Which do you build, and what is the deciding factor?

Check your understanding

3 questions
1

How does the agent avoid putting raw secret values in the prompt?

2

Which package do the custom LangChain tools wrap?

3

What does npm run mcp do differently from npm start?