Back to Nodes

@tpsdev-ai/n8n-nodes-flair

v0.58.0
Last updated Sep 30, 2026

n8n community node โ€” use Flair as your AI Agent's memory backend. Includes FlairChatMemory (Memory port) and FlairSearch (Tool port).

697 Weekly Downloads
2,113 Monthly Downloads

Description

๐ŸŽ–๏ธ Flair

![CI](https://github.com/tpsdev-ai/flair/actions/workflows/test.yml)
![Docker Test](https://github.com/tpsdev-ai/flair/actions/workflows/docker-test.yml)
![License: Apache 2.0](https://opensource.org/licenses/Apache-2.0)

> The identity and memory substrate for AI agents. Crypto-pinned. Federated. Self-hosted.

Every agent framework gives you chat history. None give you identity. Flair gives an agent three things that survive a restart and follow it between orchestrators: an identity it proves with an Ed25519 keypair, memory it searches by meaning rather than by keyword, and a soul โ€” the personality, values and procedures that make it that agent.

Quick start

Runs on a laptop, a VPS, or anywhere Node does. Needs Node.js 22+.

1. Install the CLI (no sudo)

npm install -g @tpsdev-ai/flair

2. Verify the command is on your PATH

flair --version

3. Bootstrap the instance and register an agent

flair init --agent mybot

4. Write a memory

flair memory add --agent mybot "Harper v5 sandbox blocks node:module but process.dlopen works"

5. Find it back by meaning, not by keyword

flair search --agent mybot "native addon loading in sandboxed runtimes"

If flair --version prints command not found, your npm global bin directory is not on PATH:

export PATH="$(npm prefix -g)/bin:$PATH"

Re-run flair --version to confirm, then continue.

Step 5 finds the memory you never keyword-matched:

  Harper v5 sandbox blocks node:module but process.dlopen works
  ( 2026-07-28 ยท standard ยท 100% )

By default, that percentage displays semantic similarity with a small keyword-match
boost. Hybrid search combines semantic and lexical ranks to order results, so the
first result need not have the highest percentage or be near 100%. The percentage
is not a probability that the memory answers your question correctly.

flair init --agent installs or reuses Harper, creates or reuses the agent’s Ed25519 keypair, and checks semantic search. When wiring is enabled, it attempts to wire detected clients and may run an MCP smoke test for MCP client wiring.

> Pass --agent. A bare flair init bootstraps the instance and stops there โ€” no agent, no keypair, no MCP wiring.

Full walkthrough with expected output at every step: docs/quickstart.md.

One install, one binary

npm install -g @tpsdev-ai/flair puts a single command on your PATH: flair. That is the whole install, and it needs a user-writable npm global prefix โ€” which is why step 1 says no sudo. A root-owned install can’t write the embedding model into its own package directory, so semantic search silently degrades to keyword-only. Use nvm, or point npm at your home directory โ€” npm config set prefix ~/.npm-global, then add ~/.npm-global/bin to PATH. flair init and flair doctor both check for this and say so loudly.

> Known install-size issue. npm install -g @tpsdev-ai/flair currently pulls roughly 130 MB of React Native tooling that a Node install never uses โ€” an optional dependency of Harper’s SQL engine. It is inert and Flair runs normally. The durable fix is upstream (harperfast/harper#1937). Do not install with --omit=optional to avoid it: that also drops Harper’s platform RocksDB binding, and Flair will not start.

Two MCP paths, on purpose. A client on this machine and a remote connector are different trust situations, and each has its own mechanism. The write-up that joins them is docs/mcp-clients.md โ€” Two MCP paths.

  • Local client: the npx stdio adapter. @tpsdev-ai/flair-mcp is a separate package and is not installed globally. flair init --agent attempts to wire detected clients when wiring is enabled, using npx -y @tpsdev-ai/flair-mcp@ pinned to the CLI’s version. The adapter sends requests to FLAIRURL, signing with an Ed25519 key when one resolves and otherwise using configured administrator Basic credentials when available. Loopback HTTP is the right scheme on this machine (the default is http://127.0.0.1:19926). A remote FLAIRURL should use HTTPS. This is the path for Claude Code, Cursor, Codex, Gemini, and every other local MCP client.
  • Remote client: native /mcp. A JSON-RPC endpoint inside the server, OAuth bearer, exposing the curated tools that the JSON-RPC tools/list method on /mcp returns. It is off by default: an unset FLAIRMCPOAUTH leaves /mcp unregistered; a truthy flag and a configured issuer make Flair attempt to mount it, while only the literal value true also enables the OAuth component. true is the value that turns on both Flair’s route and the OAuth component; 1, yes, and on leave the component off and every call 401s. OAuth client-metadata is fetched over HTTPS and refuses a private, loopback, or link-local host, and flair mcp enable refuses a local origin (localhost, loopback, RFC1918, IPv4 link-local, .local). Remote connectors need a publicly reachable HTTPS origin; flair mcp enable refuses local origins, but route registration itself does not enforce a public HTTPS issuer.
  • @tpsdev-ai/flair-client is likewise its own package: add it to a project when you want to call Flair from your own code (JavaScript / TypeScript).

    Where the agent’s key lives

    flair init --agent mybot writes the private key to ~/.flair/keys/mybot.key (mode 0600) and the public half beside it as mybot.pub. Only the public key is registered on the instance; the private key never leaves the machine. --keys-dir writes both somewhere else.

    Back that file up โ€” it is the agent’s identity, and there is one copy. Memories are not encrypted with it, so losing it costs the identity, not the data: the agent can no longer sign, and every HTTP call it makes fails. Recovery is flair agent rotate-key mybot, which mints a new pair and re-registers the public half โ€” it needs the admin password flair init wrote to ~/.flair/admin-pass, so back that up too. Otherwise treat the key like an SSH key: one per agent per host, never copied between machines (docs/secrets-and-keys.md).

    Keys are how an agent outside the process proves who it is. Code running inside the same Harper instance needs no key at all โ€” see Embedded in a Harper app.

    Useful flags

    flair init --agent mybot --client claude-code  # attempt to wire one client
    flair init --agent mybot --no-mcp              # register the agent; skip MCP wiring
    flair init --agent mybot --skip-soul           # skip the personality wizard
    flair init --agent mybot --port 8000           # use a non-default port
    

    Lifecycle

    flair status              # instance health, memory stats, agents
    flair doctor              # diagnose common problems and suggest fixes
    flair stop                # stop the instance
    flair restart             # restart it
    flair uninstall           # remove the service, keep data and keys
    flair uninstall --purge   # remove data, keys, secrets, schedulers, and client wiring
                              # (the npm package is left; npm uninstall -g @tpsdev-ai/flair)
    

    Upgrading

    flair status and flair doctor compare your installed version against the latest published release and print a nudge when you’re behind:

    โš  flair 0.16.1 is behind โ€” latest is 0.20.1 (4 releases behind). Upgrade: npm i -g @tpsdev-ai/flair@latest
    
    flair upgrade --check   # show the plan across flair, flair-mcp and the openclaw-flair plugin
    flair upgrade           # apply it; the instance restarts automatically
    

    A plain extracted tree (npm pack + systemd, not npm install -g)? flair upgrade detects it, or pass --tree

    . See docs/upgrade.md.

    Deployed to a Harper Fabric cluster instead of running locally? Use flair upgrade --target .

    What it looks like

    !Flair: write a memory, find it by meaning, list of supported harnesses

    Write a memory, then find it by meaning. The same memory is visible to every harness in the catalog.

    !Flair cross-orchestrator: one agent, one memory store, three MCP-capable CLIs

    One Ed25519 identity, one memory store, three MCP-capable CLIs. A memory written from Claude Code is retrievable from Codex CLI and Gemini CLI a moment later. Identity and history aren’t bound to one orchestrator’s runtime.

    One agent, every harness

    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
    โ”‚  same agent, same memory, every harness                          โ”‚
    โ”‚                                                                  โ”‚
    โ”‚  Claude Code  โ”€โ”                                                 โ”‚
    โ”‚  Cursor       โ”€โ”ค                                                 โ”‚
    โ”‚  Codex CLI    โ”€โ”ผโ”€[ flair-mcp ]โ”€โ”                                 โ”‚
    โ”‚  Gemini CLI   โ”€โ”ค               โ”‚                                 โ”‚
    โ”‚  Continue.dev โ”€โ”ค               โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”      โ”‚
    โ”‚  Goose        โ”€โ”˜               โ”œโ”€โ–ถ โ”‚  Flair (self-hosted) โ”‚      โ”‚
    โ”‚  LangGraph   โ”€[ langgraph-flair ]โ”€โ”€โ”‚  Ed25519 / HNSW /    โ”‚      โ”‚
    โ”‚  OpenClaw    โ”€[ openclaw-flair  ]โ”€โ”€โ”‚  Soul + Memory       โ”‚      โ”‚
    โ”‚  n8n         โ”€[ n8n-nodes-flair ]โ”€โ”€โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜      โ”‚
    โ”‚  Hermes      โ”€[ hermes-flair    ]โ”€โ”˜           โ”‚ federation       โ”‚
    โ”‚  Pi agent    โ”€[ pi-flair        ]โ”€โ”˜           โ”‚ (hub/spoke)      โ”‚
    โ”‚                                               โ–ผ                  โ”‚
    โ”‚                                    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”      โ”‚
    โ”‚                                    โ”‚  Flair (Fabric hub)  โ”‚      โ”‚
    โ”‚                                    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜      โ”‚
    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
    

    Choose your harness from the full integrations catalog โ†’.

    How it works

    Flair is a native Harper v5 application. Harper handles HTTP, persistence (RocksDB), and application logic in one process โ€” self-hosted, with no sidecars, no vector database and no embedding API.

    Agent โ”€โ”€[Ed25519-signed request]โ”€โ”€โ–ถ Flair (Harper)
                                          โ”œโ”€โ”€ Auth middleware (verify signature)
                                          โ”œโ”€โ”€ Identity (Agent + Integration tables)
                                          โ”œโ”€โ”€ Memory (write โ†’ auto-embed โ†’ store)
                                          โ”œโ”€โ”€ Soul (permanent personality/values)
                                          โ””โ”€โ”€ Search (semantic + keyword, ranked)
    

    Embeddings are generated in-process by nomic-embed-text (768-dim) via a Harper plugin, on CPU or GPU (Metal, CUDA). No API calls, no sidecar, no network hop. Supply-chain policy covers the bake-time and dependency pinning that keep it that way.

    Requests are signed as agentId:timestamp:nonce:METHOD:/path and verified against the agent’s registered public key, with a 30-second replay window and nonce deduplication.

    See DESIGN.md for the invariants behind the three primitives โ€” why they’re shaped the way they are.

    Features

    | Feature | What it does |
    |—|—|
    | Semantic memory | Auto-embedded on write. Search by meaning, not keywords. |
    | Tiered durability | permanent (retained until explicitly deleted by its owner or an admin) / persistent / standard (default) / ephemeral (24h TTL). |
    | Temporal validity | validFrom / validTo bounds. Expired memories drop out of search and bootstrap automatically. |
    | Trust-graded recall | Opt-in per-result evidence: provenance, usage signal, freshness, supersession. Confidence bands (strong/moderate/breadcrumb) and first-class abstention when nothing clears the floor. |
    | Relationship graph | Entity-to-entity triples with temporal bounds, queryable alongside semantic memory. |
    | Auto entity detection | Entities extracted from memory content on write. No tagging required. |
    | Predictive bootstrap | Cold-start context selected from active project, recent activity and agent role โ€” not just recency. |
    | Multi-agent | One instance, any number of agents, each with its own keys, memories and soul. |
    | Federation | Hub-and-spoke sync between instances using signed requests and pairing tokens. Originator enforcement blocks cross-node replay. docs/federation.md |
    | Memory hygiene (REM) | On-demand (flair rem rapid) and scheduled nightly distillation. Candidates are staged and promoted one at a time with a required rationale โ€” never auto-applied. docs/rem.md |
    | Memory bridges | Import/export to foreign memory systems via a YAML descriptor or a code plugin. docs/bridges.md |
    | Real-time feeds | Administrators subscribe to table changes over WebSocket/SSE; verified agents subscribe to changes to the memories they can read through /FeedMemories, and to soul changes through /FeedSouls. |
    | OAuth 2.1 server | PKCE, dynamic client registration, standards-compliant token endpoint. Delegate auth to Flair without a separate IdP. docs/auth.md |
    | XAA | Bind agent identities to Google Workspace, Azure AD or Okta accounts. |
    | Web admin | Server-rendered UI for principals, connectors, IdPs and instance config. No separate dashboard service. |
    | Benchmarks | flair-bench scores candidate embedding models against the same recall corpus Flair’s CI gates on. Runs standalone โ€” no Flair install, no server. |

    Trust-graded recall reaches the authenticated HTTP API and the built-in /mcp tools today โ€” the latter being off by default, see One install, one binary. CLI, @tpsdev-ai/flair-client and flair-mcp exposure is a follow-up. REM needs a configured generative backend (Ollama, OpenAI, Anthropic, โ€ฆ) โ€” without one, flair rem rapid fails with Reflection error: No generative backend configured.

    How Flair compares

    Every product here does semantic recall over stored memories. These are the dimensions they actually differ on.

    | | Flair | Mem0 | Honcho | Letta (MemGPT) | SageOx | Built-ins (OAI/Anthropic/Google) |
    |—|—|—|—|—|—|—|
    | Where memories live | infrastructure you run | self-host or Mem0 Cloud | self-host or hosted API | self-host or Letta Cloud | SageOx cloud | vendor cloud |
    | Memory is scoped to | the agent, via an Ed25519 keypair | tenant / user | per-user tenant | the runtime | the team | the account |
    | Reaches other orchestrators | Coding assistants, workflow engines, and agent frameworks (catalog) | several | several | Letta’s runtime | 14+ coding agents and editors, via hooks, plugins and instruction files | no |
    | Sync between instances you run | hub/spoke federation | no | no | no | one hosted service | one hosted service |
    | Captures in-person conversation | no | no | no | no | yes โ€” Ox Dot | no |
    | Per-agent persistent character | first-class (Soul) | optional | persona-shaped | optional | team context, not per-agent | no |

    Where Flair loses. SageOx’s Ox Dot records in-person meetings, standups and whiteboard sessions and pipes them into shared context; Flair has no ambient capture of anything that isn’t already text in a tool. Mem0’s hosted sync is more polished. Honcho’s persona model is more developed. Letta’s integration with its own agent loop is tighter than anything Flair offers. And there is no Flair-operated cloud โ€” running it is your job.

    Integration

    Flair works with any agent runtime. Pick the path that fits yours โ€” full catalog.

    Claude Code / Cursor / Codex CLI / Gemini CLI (MCP)

    flair init --agent attempts to wire detected clients when wiring is enabled. To configure one by hand:

    // .mcp.json in your project root (Claude Code / Cursor format)
    {
      "mcpServers": {
        "flair": {
          "command": "npx",
          "args": ["-y", "@tpsdev-ai/flair-mcp"],
          "env": { "FLAIRAGENTID": "mybot" }
        }
      }
    }
    

    Then add to your CLAUDE.md:

    At the start of every session, run mcpflairbootstrap before responding.

    (mcpflairbootstrap is Claude Code’s namespaced name for the server’s bootstrap tool.) Use flair bootstrap --agent when MCP is not wired โ€” previewing context, scripts, or any agent that can run a shell command.

    The flair-mcp server exposes memorystore, memorysearch, memoryupdate, memoryget, memorydelete, relationshipstore, bootstrap, soulset, soulget, flairworkspaceset and flair_orgevent. Memory follows the agent across CLIs โ€” same instance, same identity, switch harness without losing state.

    Per-CLI config snippets (Gemini CLI’s ~/.gemini/settings.json, Codex CLI’s ~/.codex/config.toml) are in docs/mcp-clients.md; a deeper Claude Code walk-through is in docs/claude-code.md.

    OpenClaw

    openclaw plugins install @tpsdev-ai/openclaw-flair
    

    Auto-detects the agent identity, provides memorystore / memorysearch / memoryget, and provides bootstrap context from beforeprompt_build (requires host opt-in). See the plugin README.

    n8n

    Settings โ†’ Community Nodes โ†’ Install โ†’ @tpsdev-ai/n8n-nodes-flair
    

    Three nodes: Flair Chat Memory (Memory port), Flair Search (Tool port), Flair Write (Main connections). Setup and security guidance in docs/n8n.md โ€” read the auth note below first.

    Flair CLI

    Any agent that can run a shell command can use Flair directly.

    flair memory add --agent mybot "learned something important"
    flair search --agent mybot "that important thing"
    flair soul set --agent mybot --key role --value "Security reviewer" --admin-pass-file ~/.flair/admin-pass
    flair bootstrap --agent mybot --max-tokens 4000        # cold-start: soul + relevant memories
    flair backup --admin-pass-file ~/.flair/admin-pass     # logical JSON export
    flair restore ./backup.json --admin-pass-file ~/.flair/admin-pass
    

    --admin-pass-file is preferred over --admin-pass: it keeps the secret out of ps and your shell history.

    JavaScript / TypeScript

    npm install @tpsdev-ai/flair-client
    
    import { FlairClient } from '@tpsdev-ai/flair-client'

    const flair = new FlairClient({ url: 'http://localhost:19926', // or remote: https://flair.example.com agentId: 'mybot', // key auto-resolved from ~/.flair/keys/mybot.key })

    await flair.memory.write('Harper v5 sandbox blocks bare imports') const results = await flair.memory.search('native module loading') const ctx = await flair.bootstrap({ maxTokens: 4000 }) await flair.soul.get('role')

    No Harper, no embeddings โ€” just HTTP and auth. Full API in the client README.

    HTTP API (any language)

    Anything that can make an HTTP request and sign with Ed25519.

    curl -H "Authorization: TPS-Ed25519 mybot:$TS:$NONCE:$SIG" 
      -X POST http://localhost:19926/SemanticSearch 
      -d '{"agentId": "mybot", "q": "deployment procedure", "limit": 5}'

    curl -H "Authorization: TPS-Ed25519 mybot:$TS:$NONCE:$SIG" -X PUT http://localhost:19926/Memory/mybot-123 -d '{"id": "mybot-123", "agentId": "mybot", "content": "...", "durability": "standard"}'

    Sign agentId:timestamp:nonce:METHOD:/path with the agent’s private key. Protocol in SECURITY.md. Consolidated endpoint, auth-per-resource, and schema catalog: docs/api-reference.md.

    Embedded in a Harper app (in-process)

    The second front door, and the one to take if your code already runs on Harper.

    Flair is a Harper component. Deploy it into the instance your application already runs in and call its resources directly โ€” await h.post({ agentId, content }) is a method call, not a network call. No second service to operate, no HTTP round trip, and no key to distribute: a caller in the same process is already inside the trust boundary and names the agent it is acting as, per call.

    Adding it takes nothing away. The HTTP surface keeps serving MCP clients and remote agents exactly as before.

    import { server } from "harper";
    import { agentContext, collectionResource } from "@tpsdev-ai/flair/dist/resources/in-process.js";

    // The RESOURCE โ€” auth, read-scoping, visibility, embedding. // Registry keys carry no leading slash: get("Memory"), never get("/Memory"). const Memory = server.resources.get("Memory").Resource;

    const h = await collectionResource(Memory, agentContext("mybot")); await h.post({ agentId: "mybot", content: "...", durability: "standard" });

    databases.flair.Memory is the table (raw storage); the exported Memory class is the resource, where auth, read-scoping, visibility and embedding live. new Memory(...) is not a substitute for collectionResource โ€” a create needs a collection-bound instance only Harper can produce. Both helpers refuse a missing agent id rather than defaulting it, because a resource invoked with no context resolves to Flair’s trusted internal verdict and runs unfiltered across every agent.

    This path needs no key at all. Keys are how an agent outside the process proves who it is. Code running inside the same Harper instance asserts identity through the call context instead โ€” agentContext("mybot") โ€” which Flair reads and acts on with no signature, no Agent-table lookup and no registration. That is deliberate: same-process code could write the storage tables directly, so demanding a signature from it would be theatre. It is also why that id must come from your own server-side state and never from request data.

    โ†’ Embedding Flair in a Harper app โ€” the whole in-process contract, measured against a real instance: resolving the resource, the table-vs-resource distinction that decides whether your memories are scoped at all, N agents in one process, and registering agents with no shell on the node.

    Auth across surfaces

    Ordinary agents using Ed25519 keys sign network requests. They can write only their own records and read their own plus other agents’ non-private memories. Administrator agent roles and administrator Basic credentials have broader authority, including access to private memories. Stdio MCP, Pi, LangGraph, and the wake runner can use administrator Basic auth when no signing key resolves; n8n requires a Harper administrator password in its credential; its node requests use FlairClient, which prefers a resolving Ed25519 key and otherwise uses the configured Basic credentials. See SECURITY.md.

    Treat n8n’s credential as an instance-wide administrator credential: a workflow can read private memories and write under any agent ID. Use it only on an operator-controlled, single-tenant n8n instance with trusted workflow inputs. Full breakdown: docs/auth.md.

    In-process callers are a different model, not an exception to this one: they never sign, because identity is asserted through the call context rather than proven. Co-location is the grant โ€” which is why Flair beside untrusted co-tenants on a shared instance is a different proposition to Flair inside your own app.

    Deployment

    Local (default)

    flair init --agent mybot
    

    Data stays on your machine. A single Harper process โ€” no Docker, no cloud, no external services. If port 19926 is taken, flair init --port 8000 records the choice in ~/.flair/config.yaml for future commands.

    Remote Server

    Run Flair on a VPS or cloud instance; agents connect over HTTPS.

    On the server

    flair init --agent mybot --port 19926

    On each client โ€” --target seeds the agent on the remote instance

    flair agent add otherbot --target https://your-server:19926

    --target derives the operations API as REST port โˆ’ 1. If that isn’t where your ops API lives, pass --ops-target explicitly. Good for teams with multiple machines or always-on agents.

    Harper Fabric

    Managed hosting with multi-region replication and failover. Need a public URL for Cursor / Grok Bot / cloud agents? Start at docs/quickstart-fabric.md. Federation, pairing, and operator detail: docs/deploying-on-fabric.md.

    Security

    Full model, threat analysis and recommendations in SECURITY.md.

  • Ordinary agent keys use Ed25519 signatures and bind writes to their agent identity.
  • Administrator agent roles and administrator Basic credentials have broader authority.
  • Ordinary signed agents can read their own memories and other agents’ non-private memories. Private memories are owner-only for ordinary agents; administrators can also read them.
  • Memory.post() and Memory.put() are the calls behind flair memory add, MCP memorystore and the SDK writes. A new memory they write without a visibility takes a default from durability: permanent/persistent default to shared, standard/ephemeral to private. A write that names neither lands private, and an update through Memory.put() that names no visibility keeps the stored one. Their write response names the visibility the record landed on whenever the record has one; the admin-only reindex re-PUT, which rebuilds indexes for an existing row, does not return that response. POST /FeedMemories does not apply this default: a new ephemeral feed record without visibility lands private, any other new feed record without visibility has no visibility field and reads as non-private, an update that names no visibility keeps a stored private/shared value, and the response (the stored record) names visibility only when the record has one. Say what you mean with --visibility shared|private (CLI) or visibility (MCP / SDK / feed).
  • The admin password is generated by flair init and written to ~/.flair/admin-pass (mode 0600). The CLI prints the path, never the value. Prefer --admin-pass-file over --admin-pass so it stays out of ps and shell history.
  • Key rotation via flair agent rotate-key.
  • Who can connect to a hosted Flair’s native /mcp (which people, which apps, what they can reach) and how to revoke access: docs/access-control.md.
  • Architecture

    flair/
    โ”œโ”€โ”€ src/cli.ts                 # CLI: init, agent, status, backup, grant
    โ”œโ”€โ”€ config.yaml                # Harper app configuration
    โ”œโ”€โ”€ schemas/*.graphql          # Agent, Memory, Soul, Federation, OAuth tables
    โ”œโ”€โ”€ resources/
    โ”‚   โ”œโ”€โ”€ auth-middleware.ts     # Ed25519 verification + agent scoping
    โ”‚   โ”œโ”€โ”€ embeddings-provider.ts # In-process nomic embeddings
    โ”‚   โ”œโ”€โ”€ Memory.ts              # Durability enforcement + auto-embed
    โ”‚   โ”œโ”€โ”€ Soul.ts                # Permanent-by-default personality
    โ”‚   โ”œโ”€โ”€ SemanticSearch.ts      # Hybrid semantic + keyword search
    โ”‚   โ”œโ”€โ”€ MemoryBootstrap.ts     # Cold-start context assembly
    โ”‚   โ””โ”€โ”€ MemoryFeed.ts          # Real-time memory changes
    โ”œโ”€โ”€ packages/                  # flair-mcp, flair-client, openclaw-flair, n8n-nodes-flair,
    โ”‚                              # langgraph-flair, hermes-flair, pi-flair, flair-bench
    โ””โ”€โ”€ SECURITY.md                # Threat model + auth documentation
    

    Key decisions:

  • Harper-native โ€” no Express, no middleware framework. Harper is the runtime.
  • In-process embeddings โ€” nomic-embed-text via llama.cpp, CPU or GPU. No OpenAI key needed.
  • Schema-driven โ€” GraphQL @table @export auto-generates REST CRUD; custom resources add durability guards, auto-embedding and search.

Development

bun install          # install dependencies
bun run build        # compile TypeScript โ†’ dist/
bun test             # unit + integration tests

Integration tests spin up a real Harper instance on a random port and tear it down afterwards โ€” no mocks for the database layer. Every commit runs unit tests, integration tests, type check, dependency audit, Semgrep and CodeQL SAST, and a from-scratch Docker validation. See CONTRIBUTING.md.

Status

Flair is in active development and daily use. We dogfood it: the agents that build Flair use Flair for their own memory and identity.

Shipped: Ed25519 identity and auth ยท memory CRUD with durability enforcement and near-duplicate detection ยท in-process semantic embeddings ยท hybrid search with temporal intent detection ยท soul ยท relationship graph ยท auto entity detection ยท temporal validity ยท real-time feeds ยท predictive bootstrap ยท federation ยท OAuth 2.1 and XAA ยท web admin ยท REM memory hygiene ยท MCP server ยท OpenClaw plugin ยท client library ยท portable agent export/import ยท flair upgrade.

Next: git-backed memory sync ยท opt-in encryption at rest (AES-256-GCM per memory).

> Note: Flair runs on Harper v5. We run it in production daily and track upstream closely. Pin your Harper version.

License

Apache 2.0