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

# Search Tools

> Search the Paragon catalog for relevant Tools to use for a conversation turn.

Use this endpoint to find the most relevant Tools for a given query, rather than loading all available Tools.

This is especially useful for AI agent implementations where your user may have hundreds of available Tools — Search lets you dynamically select only the Tools relevant to the current task.

### Filtering

You can narrow search results using the request body parameters:

* **`integrations`** — Restrict results to specific integrations (e.g. `["salesforce", "hubspot"]`).
* **`categories`** — Restrict results to integration categories (e.g. `["crm"]`).
* **`topK`** — Set the number of Tools to return. Defaults to 8.
* **`maxSideEffect`** — Exclude Tools that can change data beyond a given level. See [Side Effects](#side-effects).

### Token Budget

Use `maxToolTokens` to constrain the total token size of returned Tool schemas. Tools are included in relevance order until the budget is exhausted. This is useful for fitting tool schemas into your LLM's context window without manual truncation.

When `maxToolTokens` is set:

* If `topK` is also set, at most `topK` tools are returned, further constrained by the token budget.
* If `topK` is omitted, as many tools as fit within the budget are returned (up to 50).

### Side Effects

Every Tool in the results has a `sideEffect` that describes what it does in the connected app:

| `sideEffect` | Meaning | Example |
| - | - | - |
| `read` | Reads data without changing anything. | Search emails, list contacts |
| `write` | Creates or updates data. | Create a contact, update a deal |
| `delete` | Deletes data. | Delete a file |
| `send` | Sends something to other people. | Send a Slack message |
| `unknown` | The Tool has not been classified. | |

Each Tool also has an `approvalRequired` flag. It is `false` for `read` Tools and `true` for everything else, including `unknown`. Use it to decide when your agent should ask the user to confirm before running a Tool.

#### Limiting results by side effect

Set `maxSideEffect` to the most impactful kind of Tool you want returned. Each level includes the levels below it:

| `maxSideEffect` | Tools returned |
| - | - |
| `read` | `read` |
| `write` | `read`, `write` |
| `delete` | `read`, `write`, `delete` |
| `send` | `read`, `write`, `delete`, `send` |

Tools with a `sideEffect` of `unknown` are excluded whenever `maxSideEffect` is set. The number of Tools removed by this setting is returned in `usage.omittedForSideEffect`, so you can tell the difference between a search that matched nothing and one where results were filtered out.

```json theme={null}
{
  "query": "find a contact in the CRM",
  "maxSideEffect": "read"
}
```

#### Running Tools

[Run Tool](https://docs.useparagon.com/agent-os/tools/create-execution.md) currently only runs `read` Tools. Running any other Tool, including `unknown` Tools, returns a `403` with the error code `EXEC_SIDE_EFFECT_NOT_PERMITTED`. Pass `maxSideEffect: "read"` when searching if you want to return only Tools your agent can run.


## OpenAPI

````yaml agent-os/openapi/tools.json POST /api/tools/projects/{projectId}/tools/search
openapi: 3.1.0
info:
  title: Agent OS Tools API
  version: 1.0.0
  description: Enable your agent to take action in 130+ different apps with Agent OS Tools.
servers:
  - url: https://agentos.useparagon.com
    description: Production US Cloud
  - url: https://agentos.eu.paragon.so
    description: Production EU Cloud
security:
  - bearerAuth: []
paths:
  /api/tools/projects/{projectId}/tools/search:
    post:
      summary: Search Tools
      operationId: searchTools
      parameters:
        - $ref: '#/components/parameters/ProjectId'
        - name: diagnostics
          in: query
          schema:
            type: string
            enum:
              - '1'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ToolSearchRequest'
            example:
              query: list open issues
              topK: 8
              connectedOnly: true
              maxSideEffect: read
      responses:
        '200':
          description: Ranked tools.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ToolSearchResponse'
              example:
                tools:
                  - intentName: EXAMPLE_LIST_RECORDS
                    integration: example
                    sideEffect: read
                    approvalRequired: false
                    schemaSource: static
                    relevancy: 1
                    tool:
                      type: function
                      function:
                        name: EXAMPLE_LIST_RECORDS
                        description: List records.
                        parameters:
                          type: object
                          properties:
                            limit:
                              type: integer
                searchQuery: list open issues
                errors: []
                usage:
                  strategy: hybrid
                  candidates: 4
                  returned: 1
                  toolTokens: 120
                  omittedForBudget: 0
                  omittedForSideEffect: 0
                  hydratedIntegrations: []
                  degraded: null
                  visibility:
                    mode: filtered
                    entitledIntegrations: 2
                    candidatesBeforeFilter: 4
                    candidatesAfterFilter: 1
        '400':
          $ref: '#/components/responses/Error'
        '401':
          $ref: '#/components/responses/Error'
        '403':
          $ref: '#/components/responses/Error'
        '404':
          $ref: '#/components/responses/Error'
components:
  parameters:
    ProjectId:
      name: projectId
      in: path
      required: true
      schema:
        type: string
        format: uuid
  schemas:
    ToolSearchRequest:
      type: object
      required:
        - query
      additionalProperties: false
      properties:
        query:
          type: string
          minLength: 1
          maxLength: 1024
        topK:
          type: integer
          minimum: 1
          maximum: 50
          default: 8
        maxToolTokens:
          type: integer
          minimum: 1
          maximum: 100000
        integrations:
          type: array
          minItems: 1
          items:
            type: string
        categories:
          type: array
          minItems: 1
          items:
            type: string
        maxSideEffect:
          type: string
          enum:
            - read
            - write
            - delete
            - send
        connectedOnly:
          type: boolean
          default: false
        rerank:
          type: boolean
          default: true
          description: >-
            Opt out only. true cannot enable reranking when the deployment has
            it off.
    ToolSearchResponse:
      type: object
      required:
        - tools
        - searchQuery
        - errors
        - usage
      properties:
        tools:
          type: array
          items:
            allOf:
              - $ref: '#/components/schemas/ToolDescriptor'
              - type: object
                required:
                  - relevancy
                properties:
                  relevancy:
                    type: number
        searchQuery:
          type: string
        errors:
          type: array
          items:
            type: object
            required:
              - integration
              - code
              - message
            properties:
              integration:
                type: string
              code:
                type: string
              message:
                type: string
        usage:
          type: object
          required:
            - strategy
            - candidates
            - returned
            - toolTokens
            - omittedForBudget
            - omittedForSideEffect
            - hydratedIntegrations
            - degraded
            - visibility
          properties:
            strategy:
              type: string
              enum:
                - hybrid
                - semantic_failed_open
                - lexical_failed_open
            candidates:
              type: integer
            returned:
              type: integer
            toolTokens:
              type: integer
            omittedForBudget:
              type: integer
            omittedForSideEffect:
              type: integer
            hydratedIntegrations:
              type: array
              items:
                type: string
            degraded:
              oneOf:
                - type: string
                  enum:
                    - lexical_only
                    - dense_only
                    - static_schema
                - type: 'null'
            visibility:
              type: object
              required:
                - mode
                - entitledIntegrations
                - candidatesBeforeFilter
                - candidatesAfterFilter
              properties:
                mode:
                  type: string
                  enum:
                    - filtered
                entitledIntegrations:
                  type: integer
                candidatesBeforeFilter:
                  type: integer
                candidatesAfterFilter:
                  type: integer
        trace:
          type: object
          description: Present only when diagnostics=1.
          properties:
            totalMs:
              type: number
            steps:
              type: array
              items:
                type: object
                properties:
                  label:
                    type: string
                  durationMs:
                    type: number
    ToolDescriptor:
      type: object
      required:
        - intentName
        - integration
        - sideEffect
        - approvalRequired
        - schemaSource
        - tool
      properties:
        intentName:
          type: string
        integration:
          type: string
        sideEffect:
          $ref: '#/components/schemas/SideEffect'
        approvalRequired:
          type: boolean
        schemaSource:
          type: string
          enum:
            - static
            - hydrated
        tool:
          $ref: '#/components/schemas/ModelTool'
    ErrorEnvelope:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - code
            - message
            - hint
            - retryable
            - requestId
          properties:
            code:
              type: string
            message:
              type: string
            hint:
              type: string
            retryable:
              type: boolean
            retryAfterMs:
              type: integer
            requestId:
              type: string
            details:
              type: array
              items:
                type: object
                required:
                  - field
                  - issue
                properties:
                  field:
                    type: string
                  issue:
                    type: string
    SideEffect:
      type: string
      enum:
        - read
        - write
        - delete
        - send
        - unknown
    ModelTool:
      type: object
      required:
        - type
        - function
      properties:
        type:
          type: string
          enum:
            - function
        function:
          type: object
          required:
            - name
            - description
            - parameters
          properties:
            name:
              type: string
            description:
              type: string
            parameters:
              type: object
              additionalProperties: true
  responses:
    Error:
      description: Error envelope.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          example:
            error:
              code: REQUEST_INVALID
              message: The request payload failed validation.
              hint: Correct the fields named in details and retry.
              retryable: false
              requestId: req_01hxyz
              details:
                - field: query
                  issue: query should not be empty
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: >-
        Your [Paragon User
        Token](/getting-started/installing-the-connect-sdk#setup) (JWT), which
        you can generate using your project's signing keys.

````