> ## Documentation Index
> Fetch the complete documentation index at: https://nango.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Tools

> Build, test, deploy, and call tools from your backend or AI agent.

A tool is a function for on-demand reads, writes, or operations that combine multiple API calls. Call tools from your backend with the [tool-call API](https://nango.dev/docs/reference/backend/http-api/tools/call.md), the [Node SDK](https://nango.dev/docs/reference/backend/backend-sdk/node.md#call-a-tool), or an [agent session](https://nango.dev/docs/guides/agent-sessions.md).

Nango catalog tools are available without deploying code. Build your own when you need custom logic or a stable contract you control.

## Create a tool

In your [functions project](https://nango.dev/docs/guides/functions/functions-guide.md#build-locally-with-the-cli), add a tool and import it from `index.ts`:

```typescript github/tools/create-issue.ts theme={null}
import { createTool, scopes } from 'nango';
import * as z from 'zod';

export default createTool({
    description: 'Creates a GitHub issue',
    input: z.object({
        owner: z.string(),
        repo: z.string(),
        title: z.string(),
        body: z.string().optional()
    }),
    output: z.object({ id: z.number(), url: z.string().url() }),
    meta: {
        instructions: 'Use when the user asks to create an issue. Confirm the repository and title first.',
        requiredScopes: scopes.any('repo', 'public_repo')
    },
    exec: async (nango, trigger) => {
        const { owner, repo, title, body } = trigger.input;
        const response = await nango.post({
            endpoint: `/repos/${owner}/${repo}/issues`,
            data: { title, body }
        });
        return { id: response.data.id, url: response.data.html_url };
    }
});
```

```typescript index.ts theme={null}
import './github/tools/create-issue';
```

The tool name defaults to its file name. Read input from `trigger.input`. Nango validates the input against the schema before execution. `meta.requiredScopes` documents provider permissions with `scopes.all(...)`, `scopes.any(...)`, or `scopes.none()`; Nango does not enforce them. Tools can also read connection metadata and save checkpoints when you declare `data.metadata` or `data.checkpoint` schemas. See [`createTool`](https://nango.dev/docs/reference/functions/functions-sdk#createtool) for all options.

To fail a call with a custom payload, throw `new nango.Error({ ... })`. The tool-call API returns it as `error.payload` with the `function_runtime_error` code.

## Test and deploy

Create a test connection in the **Connections** tab, then dry run the tool with realistic input:

```bash theme={null}
nango dryrun create-issue '<CONNECTION-ID>' -e dev --input '{"owner":"NangoHQ","repo":"interactive-demo","title":"Bug report"}' --validate
nango deploy dev github/tools/create-issue.ts
```

A dry run calls real provider APIs and can create or change data. See [Testing](https://nango.dev/docs/guides/functions/testing.md) and [CI/CD](https://nango.dev/docs/guides/functions/ci-cd.md).

## Call a tool

Use a Nango Environment API key from **Environment Settings > API Keys**. Scoped keys need `environment:tools:call`.

> [tab] cURL
>
> ```bash theme={null}
> curl --request POST \
>   --url 'https://api.nango.dev/connections/<CONNECTION-ID>/tools/create-issue/calls' \
>   --header 'Authorization: Bearer <NANGO-API-KEY>' \
>   --header 'Content-Type: application/json' \
>   --data '{"input":{"owner":"NangoHQ","repo":"interactive-demo","title":"Bug report"}}'
> ```

> [tab] TypeScript
>
> ```typescript theme={null}
> import { Nango } from '@nangohq/node';
>
> const nango = new Nango({ apiKey: process.env.NANGO_API_KEY! });
> const result = await nango.callTool(
>     { connectionId: '<CONNECTION-ID>', name: 'create-issue' },
>     { input: { owner: 'NangoHQ', repo: 'interactive-demo', title: 'Bug report' } }
> );
> ```

Calls are synchronous and return the tool's output directly. Omit `input` for tools that take no input, sending `{}` as the request body.

## Expose tools to an agent

Use [agent sessions](https://nango.dev/docs/guides/agent-sessions.md) to scope tools and connections to a tenant. Tools participate in `toolset`, `allow`, `deny`, and `pinned_tools` policies and can be discovered through `nango_tool_search`.

For coding agents managing Nango, the [Management MCP server](https://nango.dev/docs/reference/backend/management-mcp.md#functions) exposes `tools_call`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.