How The Local Read Database Works

How The Local Read Database Works

The Daeda AI Automation Suite keeps a local read database for each connected HubSpot portal (via the @daeda/mcp-pro client).
That database is DuckDB.
It lives on your machine.
The local mirror is not one single data source.
It is made from two different systems:
    Artifact-backed data
    Lightweight plugin-backed data
This distinction is very important.

The Simple Rule

Data type
Freshness rule
Artifact-backed data
Usually handled automatically for normal reads
Lightweight plugin-backed data
Not automatically current; refresh it yourself when current values matter

Where The Local Data Lives

Each connected portal gets its own local folder.
File
Purpose
hubspot.duckdb
Main writable DuckDB database
hubspot.replica.duckdb
Published read replica for safe reads
portal_data.json
Local artifact and plugin sync state

What Counts As Artifact-Backed Data

Artifact-backed data is the main CRM mirror.
It comes from full exports, stored snapshots, and automated follow-up sync flows.

Artifact-Backed Tables

Kind
Examples
CRM object tables
contacts, companies, deals, tickets, custom object tables, and other enabled object tables
Shared association table
associations
Artifact-backed metadata
association_schema, workflows

How Artifact-Backed Data Arrives

Step
What happens
1
The server decides which artifacts exist for the portal
2
The client requests the latest artifact inventory
3
The client downloads missing or changed artifacts
4
It loads those artifacts into the local DuckDB database
5
It runs catch-up diff logic and selected-portal watch behaviour

What Counts As Lightweight Plugin-Backed Data

Plugins are small metadata sync jobs.
They populate metadata tables that do not ride on the main artifact flow.
These tables are useful, but they are not treated as live real-time data.

Active Lightweight Plugin Tables

Plugin name
Local table or tables
property-definitions
property_definitions, property_groups, property_definition_object_state
pipelines
pipelines, pipeline_stages
owners
owners
portal-info
portal_info
action-type-catalog
action_type_catalog
workflow-enrollment-triggers
workflow_enrollment_triggers, workflow_event_types
lists
lists
sequences
sequences, sequence_steps
communication-subscriptions
communication_subscription_definitions
conversation-inboxes
conversation_inboxes, conversation_channels, conversation_channel_accounts
forms
forms, form_fields
user-teams-permissions
provisioning_users, provisioning_teams, provisioning_roles

Disabled Bridge-Backed Plugins

These plugin names exist in the codebase, but they are currently disabled and not part of the normal active sync surface.
Disabled plugin
Table
snippets
snippets
email-templates
email_templates
account-settings
account_settings
record-views
record_views

Why Plugins Need Manual Refresh

The Automation Suite client does not keep lightweight plugin tables continuously current.
It can auto-skip plugin sync when data looks fresh enough.
The built-in freshness window is 24 hours.
That means plugin tables can be correct enough for many tasks, but still not current enough for operational work.

Which System Should You Trust For Freshness

Need
What to trust
CRM records and associations
Artifact-backed local mirror
Workflow snapshot plus selected-portal workflow deltas
Artifact-backed workflows table
Lists, owners, pipelines, forms, inboxes, sequences, and similar metadata
Plugin freshness in status(section="schema")

Real-Time And Near-Real-Time Behaviour

Selected Portal

The selected portal gets the strongest freshness behaviour.
Data type
Behaviour
CRM object records
Catch-up diff plus live watch behaviour
Associations
Updated through the same diff/watch path
Workflows
Snapshot artifact plus selected-portal workflow delta messages
Plugin-backed metadata
Still manual refresh when current values matter

Non-Selected Enabled Portals

Non-selected portals do not get the same live behaviour as the selected portal.
Reads can still use the local mirror.
For enabled portals, the client can wait for artifact queue work to drain before reading.
That helps artifact freshness.
It does not make plugin metadata current.

Disabled Portals

If portal sync is disabled, the Automation Suite only uses stale local data for that portal.
If no local database exists yet, reads fail.

The Main Mental Model

Use this model:
Question
Answer
Is this table a CRM object table, associations, association_schema, or workflows?
Treat it as artifact-backed
Is this table owned by a named lightweight plugin such as lists or owners?
Treat it as plugin-backed and manually refresh when needed

How To Check Freshness

Always use:
status(section="schema")
This is the authoritative freshness view.

What To Look For In status(section="schema")

Field
Meaning
lightweightPlugins.<plugin>.status
Plugin state such as NOT_STARTED, SYNCED, or FAILED
lightweightPlugins.<plugin>.lastRefreshedAt
Replica-backed last refresh time
lightweightPlugins.<plugin>.ageSeconds
Age of that plugin data
refreshJobs
Active and recent plugin refresh jobs

When You Must Run refresh_plugins

Run refresh_plugins before any task that depends on current plugin-backed metadata.

Common Cases

If you need current...
Refresh these plugins first
owners
owners
deal or ticket pipelines
pipelines
lists
lists
workflow trigger catalog
workflow-enrollment-triggers
supported workflow action metadata
action-type-catalog
forms
forms
inboxes and channels
conversation-inboxes
sequences
sequences
communication subscription definitions
communication-subscriptions
provisioning users, teams, and roles
user-teams-permissions
If a task needs several of these, refresh them together in one call.

The Correct Refresh Workflow

Step
Action
1
Call status(section="schema")
2
Decide which plugin-backed metadata you need
3
Call refresh_plugins(pluginNames=[...])
4
Poll status(section="schema") again
5
Wait until the matching refresh job is COMPLETED
6
Also confirm the plugin lastRefreshedAt values have advanced
7
Only then run query, chart, or plan-building work that depends on those tables

Why COMPLETED Matters

COMPLETED does not just mean the remote work finished.
It means the writable client has also published and verified the updated read replica.
That is why status(section="schema") is the real gate.

Refresh Job States

State
Meaning
QUEUED
Job created but not started
RUNNING
Refresh logic is executing
REPLICATING
The local read replica is being published and verified
COMPLETED
Refresh finished and the replica is verified
FAILED
Refresh failed; use the error message

Safe Examples

Safe To Query Without Plugin Refresh

Question
Why
Which deals are in closedwon?
CRM object data
Which contacts belong to which companies?
CRM object data plus associations
How many workflows are enabled?
Artifact-backed workflows table

Refresh First

Question
Why
Which owners exist today?
owners is plugin-backed
What are the current deal stage IDs?
pipelines is plugin-backed
What is the latest list ID for a static list?
lists is plugin-backed
What forms exist right now?
forms is plugin-backed

A Few Important Nuances

Nuance
What it means
workflows is not a plugin table
It is artifact-backed
property-definitions is a plugin
Refresh it manually when schema freshness matters
Read-only MCP clients can still serve reads
They use the published local replica
Plugin refresh can be relayed
A read-only client can request refresh through the writable master client

Recommended Habit

Use this rule before every serious query:
If your task depends on...
Do this
CRM records only
status(section="schema"), then query
CRM records plus plugin metadata
status(section="schema"), then refresh_plugins, then wait for replica-verified completion, then query

Related Guide