Skip to content

Quickstart

This page gets you from installed package to a working, invoked tool in a few minutes. It assumes you've already run through Installation.

1. The simplest possible usage — no restrictions

If you don't pass a SecurityContext, every tool behaves like a normal, unrestricted LangChain tool with full filesystem access. This is the fastest way to try things out locally.

from langchain_mero_tools import get_tools

tools = get_tools()  # [file_tool, directory_tool, file_search_tool, process_tool, rsync_tool]

file_tool = tools[0]
result = file_tool.invoke({
    "operation": "write",
    "path": "hello.txt",
    "content": "Hello from langchain_mero_tools!",
})
print(result)
# Wrote 33 chars to 'hello.txt' (mode=overwrite).

result = file_tool.invoke({"operation": "read", "path": "hello.txt"})
print(result)
# Hello from langchain_mero_tools!

Heads up: process_tool built with no SecurityContext prints a Python warnings.warn(...) at build time — running arbitrary shell commands with zero limits is worth an explicit heads-up even if it's allowed. See Process Tool.

In practice you almost always want to hand an LLM agent tools that are boxed into a specific directory, with only the permissions it actually needs. This is what SecurityContext is for.

from langchain_mero_tools import SecurityContext, PathEntry, Permission, get_tools

ctx = SecurityContext(
    name="worker_1",
    paths=[
        PathEntry(
            path="./workspace",
            slug="root",                                 # can't touch anything outside this
            allowed_permission=Permission.READ | Permission.WRITE,  # no DELETE, no EXECUTE
        ),
    ],
    # Blocks .env files anywhere under the mount — no extra PathEntry needed
    # just to carve out one exception. See Security & Sandboxing for the
    # full gitignore-style pattern syntax.
    denied_path_regex=[".env"],
)

tools = get_tools(ctx)  # file, directory, search, process, rsync — all scoped to ./workspace

Any attempt to read/write outside ./workspace, to delete anything at all (since DELETE isn't in the root entry's allowed_permission), or to touch .env at all, is rejected before it touches disk — see Core Concepts for exactly how that check happens, and Security & Sandboxing for the full SecurityContext/PathEntry reference.

3. Building just the tools you need

get_tools() accepts an include list if you don't want all five tools — useful when you want to keep an agent's toolset small and predictable:

tools = get_tools(ctx, include=["file", "directory", "search"])
# process and rsync are omitted entirely

Or build a single tool directly with its factory function:

from langchain_mero_tools import make_file_tool

file_tool = make_file_tool(ctx)

Every tool follows the same make_<name>_tool(ctx=None) convention — see Tools Overview for the full list.

4. Wiring into an agent

tools is a plain list of StructuredTool objects, so it plugs into any LangChain-compatible agent the normal way. For example, with LangGraph's prebuilt ReAct agent:

from langchain.chat_models import init_chat_model
from langgraph.prebuilt import create_react_agent
from langchain_mero_tools import SecurityContext, PathEntry, Permission, get_tools

ctx = SecurityContext(
    paths=[
        PathEntry(
            path="./workspace",
            slug="root",
            allowed_permission=Permission.READ | Permission.WRITE,
        ),
    ],
)
tools = get_tools(ctx)

model = init_chat_model("anthropic:claude-sonnet-4-5")
agent = create_react_agent(model, tools)

result = agent.invoke({
    "messages": [{"role": "user", "content": "List the files in the workspace."}]
})

The agent can now only see/write inside ./workspace, no matter what the model tries to do — the sandboxing happens inside the tool itself, not in the prompt.

5. Turning on approval for sensitive actions

Before shipping an agent that can delete or execute things, you'll usually want a human (or another agent) to sign off first:

from langchain_mero_tools import SecurityContext, PathEntry, Permission, CLIApproval

ctx = SecurityContext(
    paths=[
        PathEntry(
            path="./workspace",
            slug="root",
            allowed_permission=Permission.READ | Permission.WRITE | Permission.DELETE,
        ),
    ],
    require_approval_for=Permission.WRITE | Permission.DELETE,
    approval=CLIApproval(),   # blocking terminal y/N prompt
)

See Approval Workflows for all four built-in approval backends (including a non-blocking LangGraph one) and how to write your own.

Where to go next