> ## Documentation Index
> Fetch the complete documentation index at: https://langchain-5e9cc07a-preview-contex-1789468204-c45d5ed.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Add custom tools to Managed Deep Agents

> Define authored tools for managed deep agents projects.

Custom tools are application code the agent can call for fetching real-time data, querying databases, executing code, and taking actions. Unlike [instructions](/langsmith/javascript/managed-deep-agents-instructions) and [skills](/langsmith/javascript/managed-deep-agents-skills), MDA does not discover them automatically.

To load tools from a remote MCP server, see [Connect to MCP servers](/langsmith/javascript/managed-deep-agents-mcp-connectors).

<Note>
  Managed Deep Agents is in **public [beta](/langsmith/release-stages)** and available on [LangSmith Cloud](/langsmith/cloud) in the US region only.
</Note>

Put authored tools under `tools/`, import them into the agent entry, and pass them to the agent definition:

```text theme={null}
my-agent/
  agent.ts
  tools/
    customer.ts
```

For the full project layout, see [Project structure](/langsmith/javascript/managed-deep-agents-project-structure).

To load tools from a remote MCP server without importing them into the agent entry, use an [MCP connector](/langsmith/javascript/managed-deep-agents-mcp-connectors) instead.

## Add a tool

Use authored tools for business logic, private APIs, database access, and other code that belongs in your agent project.

<Steps>
  <Step title="Define a tool module" id="define-a-tool-module">
    ```ts tools/customer.ts theme={null}
    import { tool } from "langchain";
    import { z } from "zod";

    export const lookupCustomer = tool(
      async ({ customerId }) => `Customer ${customerId} is on the enterprise plan.`,
      {
        name: "lookup_customer",
        description: "Look up a customer record by ID.",
        schema: z.object({
          customerId: z.string().describe("Customer ID from the CRM."),
        }),
      },
    );
    ```

    Use clear, unique tool names to avoid collisions. For more about LangChain tool definitions, see [Tools](/oss/javascript/langchain/tools).
  </Step>

  <Step title="Attach the tool to the agent" id="attach-the-tool">
    Import the tool into the project-root agent entry and pass it in the `tools` list:

    ```ts agent.ts theme={null}
    import { defineDeepAgent } from "managed-deepagents";

    import { lookupCustomer } from "./tools/customer";

    export const agent = defineDeepAgent({
      name: "support-agent",
      model: "openai:gpt-5.5",
      tools: [lookupCustomer],
    });
    ```

    Your imports should work the same way they do in a normal local TypeScript project.
  </Step>

  <Step title="Add human-in-the-loop (Optional)" id="human-in-the-loop">
    Pause the agent before sensitive tool calls so a person can approve, edit, or reject them.

    Set `interruptOn` in the agent definition, and optionally set `permissions` to gate tool and filesystem access:

    ```ts agent.ts theme={null}
    import { defineDeepAgent } from "managed-deepagents";

    import { lookupCustomer } from "./tools/customer";

    export const agent = defineDeepAgent({
      name: "support-agent",
      model: "openai:gpt-5.5",
      tools: [lookupCustomer],
      interruptOn: {
        lookup_customer: true,
      },
    });
    ```

    The `interruptOn` field applies the same interrupt behavior as LangChain's [human-in-the-loop middleware](/oss/javascript/langchain/guardrails#human-in-the-loop).

    For decision types (approve, edit, reject), conditional interrupts, and permission rules, see the Deep Agents [Human-in-the-loop](/oss/javascript/deepagents/human-in-the-loop) and [Permissions](/oss/javascript/deepagents/permissions) guides.

    To resume a paused run, see [Respond to an interrupt](#respond-to-an-interrupt).
  </Step>
</Steps>

## Use secrets and context

Tools can read deployment secrets from environment variables. Put local values in `.env` for `mda dev`; `mda deploy` forwards non-reserved `.env` values as hosted deployment secrets.

For per-run values such as request metadata or feature flags, use the normal LangChain runtime context patterns for tools. See [how to access context from within your tools](/oss/javascript/langchain/tools#access-context).

## Deployment

`mda dev` and `mda deploy` copy project files into the compiled build, including modules under `tools/`. Tools are not synced to Context Hub; they ship with the agent code.

## When to use tools

| Concept                                                                        | Kind                  | How it reaches the agent                                     |
| ------------------------------------------------------------------------------ | --------------------- | ------------------------------------------------------------ |
| **Tools**                                                                      | Application code      | Import and pass in the agent definition                      |
| **[MCP connectors](/langsmith/javascript/managed-deep-agents-mcp-connectors)** | Managed configuration | Declared under `connectors/`; no import into the agent entry |
| **[Skills](/langsmith/javascript/managed-deep-agents-skills)**                 | Managed context       | Procedures the agent loads when relevant                     |
| **[Instructions](/langsmith/javascript/managed-deep-agents-instructions)**     | Managed context       | Always-on system prompt                                      |

For more information, see [Project structure](/langsmith/javascript/managed-deep-agents-project-structure).

## Respond to an interrupt

When a run hits an interrupt, it pauses and waits for a human response before continuing.

* **During local development**, `mda dev` runs the agent in LangSmith Studio, which surfaces the interrupt so you can inspect the pending tool call and resume the run.

* **On a deployed agent**, resume the paused run through the LangGraph server API with a resume payload. See [Human-in-the-loop using server API](/langsmith/add-human-in-the-loop).

<Note>
  During public beta, Managed Deep Agents is CLI-first and programmatic invocation is not yet documented. To resume runs programmatically from your own application, contact your LangChain team.
</Note>

Human-in-the-loop needs durable thread state to pause and resume. The managed runtime owns the checkpointer, so no extra setup is required.

## Use tools that require authentication

If a tool requires an API key or OAuth token, use a connection to resolve the credential at runtime. See [Manage connections](/langsmith/javascript/managed-deep-agents-connections).

## Access runtime context

For per-run values such as request metadata or feature flags, use the normal LangChain runtime context patterns for tools. See [how to access context from within your tools](/oss/javascript/langchain/tools#access-context).

***

<div className="source-links">
  <Callout icon="terminal-2">
    [Connect these docs](/use-these-docs) to Claude, VSCode, and more via MCP for real-time answers.
  </Callout>

  <Callout icon="edit">
    [Edit this page on GitHub](https://github.com/langchain-ai/docs/edit/main/src/langsmith/managed-deep-agents-tools.mdx) or [file an issue](https://github.com/langchain-ai/docs/issues/new/choose).
  </Callout>
</div>
