# Work with your network

Source: https://docs.havilo.ai/mcp/network

Use the MCP as a set of small building blocks. The safe path is to inspect the actual workspace, form a concrete plan, preview each mutation, apply the smallest coherent change, and read the result back.

The protocol uses the `crm_records_*` names and `record_id` for compatibility. In Havilo, those records are Entities: people, companies, programs, investments, projects, or any other type in your workspace.

## 1. Confirm the connection

Call `workspace_whoami` and `workspace_capabilities`. Record the workspace ID for the plan even though customer tools will not accept it as input.

Stop if the connected workspace or effective permissions are not the ones the task requires.

## 2. Inspect the model

Call `crm_schema_get` before inventing fields or relationship types. It returns the active entity types, their fields with how many values each one holds, relationship types, and Entity counts.

Prefer an existing type or field when it already carries the intended meaning. If the model needs to change, use:

* `crm_entity_types_ensure`;
* `crm_fields_ensure`;
* `crm_relationship_types_ensure`.

Each tool is idempotent and previews by default. Review the existing match and intended values before applying it.

## 3. Find the target Entities

Use `crm_records_search` to search by text, entity type, or external ID. Use `crm_records_get` when you already know the Entity's `record_id` and need its fields, relationships, and recent Notes.

External IDs are the best stable identity when data originates in another system. Do not match a large import only by display name when the source provides a durable identifier.

## 4. Preview the write

`crm_records_upsert`, `crm_relationships_ensure`, and `crm_notes_upsert` all default to `apply: false`.

A useful plan identifies:

* the Entities and entity types being changed;
* the source of each value;
* stable external IDs or idempotency keys;
* the relationship type and direction;
* the Notes and Entity links being written;
* the read-back calls that will prove the result.

Review the preview for conflicts, inferred matches, and target IDs. Change the input before applying if any target is ambiguous.

## 4b. Edit a Note precisely

To change part of a Note rather than replace it, read it and then name the text you are changing.

`crm_notes_read` returns the whole Note as markdown, with custom blocks as `:::` fences, plus a `revision`. `crm_notes_edit` takes `edits`, each naming the exact `old_string` to replace. Copy that string from what the read returned — an edit that does not match exactly once fails rather than guessing which occurrence you meant.

```jsonc
{
  "note_id": "a1b2c3",
  "revision": "sha256:9f2e…",
  "edits": [
    {
      "old_string": "Pre-seed specialist.",
      "new_string": "Pre-seed specialist. Co-invests with Madrona.",
    },
  ],
  "apply": true,
}
```

Pass `revision` back so the edit is refused if the Note changed after you read it, rather than overwriting someone's work. Use `append` to add to the end, which needs no anchor. Use `crm_notes_upsert` only when replacing a whole Note.

Editing inside a `:::` fence is ordinary text editing — the block survives, because the server confirms it before writing. See [Tool reference](https://docs.havilo.ai/mcp/tools.md) for the exact failure modes.

## 5. Apply and verify

Repeat the reviewed input with `apply: true`. Then read back the affected Entities or Notes.

For a relationship change, inspect both Entities if direction or labels matter. For a Note, confirm the saved markdown and linked Entity IDs. A successful write response confirms that the mutation returned; the verification read confirms what is now in the workspace.

For more than 100 Entities or a source file that should be auditable as one job, use [Import data](https://docs.havilo.ai/mcp/imports.md).
