Skip to content

Notes

Notes provide persistent key-value storage scoped to each user. Data saved in notes survives across workflow executions, enabling preferences, accumulated results, and cross-workflow data pipelines.

Use Cases

  • User preferences: Store commit style, preferred region, coding conventions
  • Data accumulation: Weekly analysis results compared over time
  • Cross-workflow pipelines: Collector workflow saves data, Reporter workflow reads it
  • Session continuity: Intermediate results survive session archiving

MCP Tool

The notes MCP tool provides these actions for agent access:

notes({ action: "save", key: "commit-style", value: "conventional", tags: ["preferences"] })
notes({ action: "get", key: "commit-style" })
notes({ action: "list", tag: "preferences" })
notes({ action: "history", key: "commit-style" })
notes({ action: "delete", key: "commit-style" })
notes({ action: "stats" })
ActionPurpose
saveCreate or update a note
getRead note content by key
listList a page of notes with tag/key filters
historyView version history of a note
deleteSoft delete a note
statsUsage statistics and quota info

Key Format

Keys accept alphanumeric characters, underscore, and hyphen. Length: 1-100 characters.

my-config # valid
project_settings # valid
2024-report # valid

Limits and pagination

Per-note size, total storage, and retained-version limits come from the active server policy. Use notes({ action: "stats" }) for the current total storage limit and usage; rejected writes report the enforced size or quota boundary. The fixed key and tag syntax limits remain visible in the MCP schema and validation errors.

list returns a page rather than the complete collection. Use limit and offset, and compare the returned notes with total to determine whether another page is needed.

Automatic Node Types

Three node types execute note operations without agent interaction. They run server-side and continue to the next node automatically.

read-note

Reads notes matching filter criteria into a context variable:

{
"type": "read-note",
"id": "load-metrics",
"outputVariable": "metricsNotes",
"filter": {
"tag": "metrics",
"keyPattern": "metrics-"
},
"connections": {
"default": "process-data",
"error": "no-data-handler"
}
}
PropertyRequiredDescription
outputVariableYesContext variable to store results
filter.tagNoFilter by exact tag
filter.keyPatternNoFilter by key prefix
filter.keySearchNoSearch in key (contains)
singleModeNoReturn object instead of array
connections.errorNoError handler node

write-note

Writes data from context to a note:

{
"type": "write-note",
"id": "save-results",
"key": "results-{{projectName}}-{{date}}",
"source": "{{analysisData}}",
"tags": ["analysis", "{{projectName}}"],
"connections": {
"default": "next-step"
}
}
PropertyRequiredDescription
keyNo*Note key (required in single mode)
sourceYesContext variable or template with value
tagsNoTags to assign
batchModeNoProcess array of [{key, value, tags}]

When source resolves to an object or array, the value is auto-serialized to a JSON string. Strings pass through unchanged, numbers and booleans convert to their string form.

upsert-note

Finds existing note by search criteria or creates a new one:

{
"type": "upsert-note",
"id": "update-latest",
"search": { "tag": "latest-metrics" },
"keyTemplate": "latest-metrics-{{projectName}}",
"value": "{{metricsData}}",
"tags": ["metrics", "latest-metrics"],
"connections": {
"default": "next-step"
}
}
PropertyRequiredDescription
search.tagNoSearch by tag
search.keyPatternNoSearch by key prefix
keyTemplateYesKey for new note if not found
valueYesContext variable with note value
tagsNoTags to assign
outputVariableNoStore upsert result in context

When value resolves to an object or array, the value is auto-serialized to a JSON string.

All filter, key, and tag parameters support {"{{variable}}"} template expressions resolved from execution context.

Template Syntax

Reference note content in directive and completionCondition fields using {{note:KEY}} syntax:

Analyze the project using this configuration: {{note:project-config}}

Note content is injected before the agent sees the directive. Missing notes produce [NOTE NOT FOUND: KEY].

Template variables inside note content are resolved after injection:

// Note "greeting" contains: "Hello, {{userName}}!"
// Directive: {{note:greeting}}
// Agent sees: "Hello, Alice!" (when userName="Alice")

Tutorial: Cross-Workflow Data Pipeline

This example shows two workflows communicating through Notes: a Collector saves project metrics, a Reporter reads and analyzes them.

Workflow 1: Metrics Collector

Collects metrics and saves them as notes:

flowchart LR
    A[start] --> B[gather-metrics]
    B --> C[write-note]
    C --> D[upsert-note]
    D --> E[confirm-saved]
    E --> F[end]

Key nodes:

write-note saves raw metrics with a timestamped key. The source field references agent output using dot-path syntax — objects and arrays are auto-serialized to JSON:

{
"type": "write-note",
"id": "write-metrics-note",
"key": "metrics-{{gather-metrics.projectName}}-{{gather-metrics.collectionDate}}",
"source": "{{gather-metrics.metrics}}",
"tags": ["metrics", "{{gather-metrics.projectName}}", "raw-data"]
}

upsert-note maintains a “latest” reference:

{
"type": "upsert-note",
"id": "upsert-latest-summary",
"search": { "tag": "latest-metrics" },
"keyTemplate": "latest-metrics-{{gather-metrics.projectName}}",
"value": "{{gather-metrics.metrics}}",
"tags": ["metrics", "{{gather-metrics.projectName}}", "latest-metrics"]
}

Workflow 2: Metrics Reporter

Reads saved metrics and generates a report:

flowchart LR
    A[start] --> B[ask-project]
    B --> C[read-note]
    C --> D[generate-report]
    D --> E[end]
    C -->|error| F[no-data]
    F --> G[end-no-data]

read-note loads all metrics by tag and key prefix:

{
"type": "read-note",
"id": "load-all-metrics",
"outputVariable": "metricsNotes",
"filter": {
"tag": "metrics",
"keyPattern": "metrics-"
}
}

The report directive uses {{note:KEY}} to inject the latest snapshot. Dot-path syntax references agent output from previous nodes:

Generate a metrics report.
Latest metrics snapshot:
{{note:latest-metrics-{{ask-project.projectName}}}}
All collected metrics:
{{metricsNotes}}

Running the Pipeline

  1. Start the Metrics Collector workflow and provide project metrics 2. Notes are saved automatically via write-note and upsert-note nodes 3. Start the Metrics Reporter workflow for the same project 4. read-note loads all metrics, {{ note: KEY }} injects the latest snapshot 5. Agent generates a report comparing data across collection dates

The Collector can run multiple times — each run adds a new timestamped note while upsert-note keeps the “latest” reference current.

Web UI

Notes are managed through the web interface at the Notes page (accessible from sidebar navigation):

  • Browse notes with key, tags, size, and preview
  • Filter by tag or search by key name
  • Create, edit, and delete notes
  • View version history — a past version on its own, beside the current one, or as a line-by-line difference — and restore it; the history dialog is the same one playbooks and global settings use
  • Monitor quota usage