# Coco Tools

> Built-in Coco tools for creating and organizing resources in your Cotera library — agents, documents, and folders — with automatic deduplication and a staged organize workflow.

Source: https://cotera.co/docs/reference/tools/individual-tools/coco

---

**Authentication Type:** No Authentication\
**Description:** Built-in Coco tools for creating and organizing resources in your Cotera library — agents, documents, and folders — with automatic deduplication and a staged organize workflow.

***

## Authentication

Coco tools are built into the Cotera platform and require no external credentials or API keys. They operate in the context of the authenticated Cotera user.

***

## Create Operations

Create agents and documents in your Cotera library. Both tools run a pre-create similarity check to prevent duplicates and support an optional `folderId` to place the resource immediately.

### Create Agent

Create a new Cotera agent with instructions (TipTap-style document) and an optional model. Before writing anything, the tool checks whether a similar agent already exists that the user can access; if any are found, it returns a confirmation prompt instead of creating.

**Operation Type:** Mutation (Write)

**Parameters:**

* **document** `object` (nullable): The agent's instructions as a TipTap editor document. Type must be `"doc"` with a `content` array of nodes (heading, paragraph, etc.). The agent's title is derived from the first H1 heading. Pass `null` to create a model-only agent without instructions.
* **model** `string` (nullable): LLM model for the new agent. Defaults to Cotera's default agent model when omitted or `null`. Only override when the user or parent agent explicitly requests a specific model.
* **folderId** `string` (nullable): UUID of the folder to place the agent in. When omitted, falls back to the current conversation's folder if the chat is inside one.
* **confirmedDespiteSimilar** `boolean` (nullable, default: `false`): Set to `true` only after the user has been shown similar existing resources and explicitly chose to create a new one anyway. Leave `false` (or omit) on the first call.

**Returns (normal):**

* **artifactType** `string`: `"agent"`
* **artifactId** `string`: UUID of the created agent.
* **data** `object`:
  * **agentId** `string`: UUID of the created agent.
  * **agentKey** `string`: The tool key for invoking the agent (e.g. `coco/agent-<id>`).
* **verb** `string`: `"created"`

**Returns (similarity gate — dedup check):**

When similar agents exist and `confirmedDespiteSimilar` is not `true`, the tool returns this object instead of creating anything:

* **confirmationRequired** `boolean`: Always `true`.
* **reason** `string`: `"similar-resources-exist"`
* **message** `string`: Instructions for Coco to relay the similar titles to the user and ask whether to reuse one or create anyway.
* **similarResources** `array of objects`: Up to 3 similar existing agents the user can access.
  * **id** `string`: Resource UUID.
  * **type** `string`: Resource type (e.g. `"agent"`).
  * **title** `string`: Display title of the similar resource.

**Behavior Notes:**

* The dedup gate is best-effort: if the similarity check itself fails, the failure is swallowed and creation proceeds normally.
* On "create anyway", re-call with `confirmedDespiteSimilar: true` to skip the gate.
* Requires at least edit permission on the target folder (if a folder is specified).

**Example Usage:**

First call — gate fires and returns similar agents:

```json
{
  "document": {
    "type": "doc",
    "content": [
      {
        "type": "heading",
        "attrs": { "level": 1 },
        "content": [{ "type": "text", "text": "Support Triage Agent" }]
      },
      {
        "type": "paragraph",
        "content": [{ "type": "text", "text": "Classify and route incoming support tickets." }]
      }
    ]
  }
}
```

Re-call after user confirms "create anyway":

```json
{
  "document": {
    "type": "doc",
    "content": [
      {
        "type": "heading",
        "attrs": { "level": 1 },
        "content": [{ "type": "text", "text": "Support Triage Agent" }]
      },
      {
        "type": "paragraph",
        "content": [{ "type": "text", "text": "Classify and route incoming support tickets." }]
      }
    ]
  },
  "confirmedDespiteSimilar": true
}
```

***

### Create Document

Create a new Cotera document resource using TipTap editor state. The document's title is automatically derived from its first H1 heading. Like `create-agent`, this tool runs a pre-create dedup gate (ranking on title + body + description) before writing anything.

**Operation Type:** Mutation (Write)

**Parameters:**

* **document** `object` (required): TipTap document with `type: "doc"` and a `content` array. Pass at least `{ "type": "doc", "content": [] }` for an empty document. The title is derived from the first H1 heading.
* **description** `string` (nullable): Optional short description of the document. Also used as a similarity signal during the dedup gate check.
* **folderId** `string` (nullable): UUID of the folder to place the document in. When omitted, falls back to the current conversation's folder if the chat is inside one.
* **confirmedDespiteSimilar** `boolean` (nullable, default: `false`): Set to `true` only after the user has been shown similar existing documents and explicitly chose to create a new one anyway.

**Returns (normal):**

* **artifactType** `string`: `"document"`
* **artifactId** `string`: UUID of the created document.
* **data** `object`:
  * **documentId** `string`: UUID of the created document.
* **verb** `string`: `"created"`

**Returns (similarity gate — dedup check):**

Same shape as `create-agent`'s gate response:

* **confirmationRequired** `boolean`: Always `true`.
* **reason** `string`: `"similar-resources-exist"`
* **message** `string`: Instructions for Coco to relay the similar titles and ask the user to reuse one or create anyway.
* **similarResources** `array of objects`: Up to 3 similar existing documents the user can access.
  * **id** `string`: Resource UUID.
  * **type** `string`: Resource type (e.g. `"document"`).
  * **title** `string`: Display title of the similar resource.

**Behavior Notes:**

* The dedup gate is best-effort and never blocks creation — a failed similarity check is silently ignored and creation proceeds.
* The gate ranks on title + body + description together, so a document with no H1 but a matching description can still be flagged.
* Requires at least edit permission on the target folder (if specified).

**Example Usage:**

Create a document and place it in a folder:

```json
{
  "document": {
    "type": "doc",
    "content": [
      {
        "type": "heading",
        "attrs": { "level": 1 },
        "content": [{ "type": "text", "text": "Q4 Onboarding Checklist" }]
      },
      {
        "type": "paragraph",
        "content": [{ "type": "text", "text": "Steps for onboarding new team members in Q4." }]
      }
    ]
  },
  "description": "Onboarding checklist for Q4 new hires",
  "folderId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
```

***

## Find Similar Resources

### Find Similar Resources

Pre-flight deduplication check. Call this before `create-agent` or `create-document` to surface existing resources the user can access that are semantically or title-similar to the one they are about to create.

**Operation Type:** Query (Read)

**Parameters:**

* **kind** `string` (required): The type of resource about to be created. Must be `"document"` or `"agent"`. Only existing resources of the same kind are checked.
* **title** `string` (required): The intended title or name of the new resource (or a short phrase describing it). Used as the primary similarity signal.
* **description** `string` (nullable): Optional short description of the intended resource. Combined with the title when searching.

**Returns:**

* **similarResources** `array of objects`: Existing resources similar to the intended new one. Empty when nothing similar is found or when the check fails. Up to 3 results.
  * **id** `string`: UUID of the existing resource.
  * **type** `string`: Resource type (`"agent"` or `"document"`).
  * **title** `string`: Display title of the existing resource.
* **message** `string`: Human-readable summary. Explains whether similar resources were found and, if so, instructs Coco to surface them to the user before creating.

**Behavior Notes:**

* Results are permission-filtered: only resources the user owns, that are org-shared, or that have been explicitly shared with them are returned. A teammate's private draft never surfaces.
* This is an informational nudge, never a block. A failed check returns `similarResources: []` with an explanatory message rather than an error.
* The `create-agent` and `create-document` tools run the same check internally as a server-side backstop, so calling `find-similar-resources` first is the recommended pre-flight but not strictly required.

**Example Usage:**

```json
{
  "kind": "agent",
  "title": "Customer Feedback Summarizer",
  "description": "Reads support tickets and summarizes recurring themes"
}
```

***

## Organize Library Operations

Tools for staging a library reorganization plan. All changes are staged — nothing moves until the user confirms by pressing **Move** in the Organize review panel.

### Organize Library

Entry point when the user asks Coco to organize, tidy, or sort their library from chat. Builds (or reuses) the staged folder plan server-side and opens the Organize review panel as a chat artifact.

**Operation Type:** Mutation (Write)

**Parameters:** None.

**Returns:**

* **artifactType** `string`: The organize artifact type.
* **data** `object`:
  * **conversationId** `string`: The conversation ID — the key shared by the review panel and the draft tools.
  * **summary** `string`: A one-line description of the staged plan (e.g. `"Staged 12 items across 4 folders. Review in the panel; nothing moves until the user presses Move."`). Relay this to the user.
* **verb** `string`: `"opened"`

**Behavior Notes:**

* The plan is built server-side, so the draft is guaranteed to exist when Coco reads it and stages moves immediately afterward — no client round-trip to race against.
* If the library is already tidy the summary reads: `"Nothing needs organizing — the library is already tidy."`
* After this call, use `organize-read-draft`, `organize-stage-move`, `organize-add-folder`, and `organize-remove-folder` to inspect and refine the draft.
* **Admin-only for Shared library:** Organizing the Shared library (`org` scope) is restricted to org admins. Non-admin users who attempt to open or commit a shared-library organize draft receive a `Forbidden` error: `"Only an org admin can organize the shared library."`

**Example Usage:**

```json
{}
```

***

### Read Organize Draft

Read the current staged organize draft — the folders and items shown in the Organize review panel. Use this to inspect the plan before suggesting or staging changes.

**Operation Type:** Query (Read)

**Parameters:** None.

**Returns (draft exists):**

* **exists** `boolean`: `true` when a draft is open.
* **scope** `string`: `"user"` for the user's personal library ("My library"), `"org"` for the organization's shared library ("Shared library"). The `org` scope is admin-only — only org admins can open or commit a shared-library draft.
* **sharedLibrary** `boolean`: `true` when `scope` is `"org"`.
* **folders** `array of objects`: The folders in the staged plan.
  * **name** `string`: Display name of the folder.
  * **draftId** `string`: Unique identifier for this folder within the draft. Use this as `folderId` in `organize-stage-move` and `organize-remove-folder`.
  * **parentFolderId** `string` (nullable): `draftId` of this folder's parent, or `null` for top-level folders.
  * **existing** `boolean`: `true` if this folder already exists in the library; `false` if it will be created when the user confirms.
  * **items** `array of objects`: Resources staged into this folder.
    * **type** `string`: Resource type (`"agent"` or `"document"`).
    * **id** `string`: Resource UUID. Use this as `resourceId` in `organize-stage-move`.
    * **title** `string`: Display title of the resource.

**Returns (no draft):**

* **exists** `boolean`: `false`.
* **message** `string`: Explanation that no draft is open. The user opens one from the Library "Organize" action or via `organize-library`.

**Example Usage:**

```json
{}
```

***

### Stage Move

Stage moving a resource into a folder in the organize draft. The destination folder must already exist in the draft — create it first with `organize-add-folder` if needed. Nothing moves for real until the user confirms.

**Operation Type:** Mutation (Write)

**Parameters:**

* **resourceType** `string` (required): The kind of resource to move. Must be `"document"` or `"agent"`.
* **resourceId** `string` (required): UUID of the resource to move. Use an item `id` from `organize-read-draft`.
* **folderId** `string` (required): The `draftId` of the destination folder from `organize-read-draft` or the `folderId` returned by `organize-add-folder`. This is a draft folder ID, not a name — do not invent values.

**Returns:**

* **ok** `boolean`: `true` if the resource was staged successfully; `false` if it was not found in the draft or the folder doesn't exist.
* **message** `string`: Human-readable result (e.g. `"Staged into \"Onboarding\". It will move when the user confirms."`).
* **draft** `object`: Updated draft view (same shape as `organize-read-draft`).

**Behavior Notes:**

* The folder must already exist in the draft. Pass the `draftId` from a prior `organize-read-draft` or `organize-add-folder` call — never pass a name.
* Returns `ok: false` when the resource is not in the current draft (already moved, not in scope, etc.) — this is not an error.

**Example Usage:**

```json
{
  "resourceType": "document",
  "resourceId": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
  "folderId": "draft-folder-uuid-from-add-folder"
}
```

***

### Add Folder

Add an empty folder to the organize draft. The folder is staged only — it is created for real when the user confirms. Returns a `folderId` to use with `organize-stage-move`.

**Operation Type:** Mutation (Write)

**Parameters:**

* **name** `string` (required): Name for the new folder. 1–3 plain words; no em dashes, colons, or parent-topic prefixes. The name is sanitized server-side.
* **parentFolderId** `string` (nullable): The `draftId` of an existing draft folder to nest this new folder under. Omit for a top-level folder.

**Returns:**

* **ok** `boolean`: `true` when the folder was added successfully.
* **folderId** `string`: The `draftId` assigned to the new folder. Reuse this value with `organize-stage-move` to move items into the folder.
* **message** `string`: Confirmation including the folder name and its `folderId`.
* **draft** `object`: Updated draft view (same shape as `organize-read-draft`).

**Behavior Notes:**

* Do not add a second folder for the same topic — reuse the `folderId` returned by the first call.
* The name is sanitized server-side: overly long or formatted names are trimmed to a short plain form.

**Example Usage:**

```json
{
  "name": "Onboarding",
  "parentFolderId": null
}
```

Subfolder example:

```json
{
  "name": "Templates",
  "parentFolderId": "draft-folder-uuid-of-onboarding"
}
```

***

### Remove Folder

Remove a folder from the organize draft. Use this to clean up folders that were emptied by consolidating their items elsewhere. Staged only — nothing is deleted for real until the user confirms.

**Operation Type:** Mutation (Write)

**Parameters:**

* **folderId** `string` (required): The `draftId` of the folder to remove from the draft (from `organize-read-draft`).

**Returns:**

* **ok** `boolean`: `true` when the folder was removed; `false` when no folder with that `draftId` exists in the draft.
* **message** `string`: Result description.
* **draft** `object`: Updated draft view (same shape as `organize-read-draft`).

**Behavior Notes:**

* Never remove a folder that items are being moved into, one you just created to fill, or one the user explicitly asked to keep.
* Use only to tidy up folders that were emptied by a consolidation step.

**Example Usage:**

```json
{
  "folderId": "draft-folder-uuid-to-remove"
}
```

***

## Common Use Cases

**Creating resources without duplicates:**

* Call `find-similar-resources` before starting to draft an agent or document to surface existing ones
* When similar resources are found, show the user the titles and ask whether to reuse one or create a new one
* Re-call `create-agent` or `create-document` with `confirmedDespiteSimilar: true` after the user confirms they want a new resource

**Library organization:**

* When the user says "organize my library", call `organize-library` to build the staged plan and open the review panel
* Read the draft with `organize-read-draft` to understand the current proposed layout
* Add new folders with `organize-add-folder` and move items with `organize-stage-move` to refine the plan
* Remove empty folders with `organize-remove-folder` after consolidating their contents
* Remind the user that nothing moves until they press **Move** in the Organize panel

**Building structured folder hierarchies:**

* Add a top-level folder with `organize-add-folder` and note its `folderId`
* Add subfolders using the top-level folder's `folderId` as `parentFolderId`
* Stage moves using the appropriate `folderId` at each level

**Reusing draft folder IDs correctly:**

* Always read the `folderId` (draftId) from `organize-read-draft` or the `folderId` returned by `organize-add-folder`
* Never invent or guess folder IDs — `organize-stage-move` will return `ok: false` for unknown IDs

