---
title: Per-client memory your AI runs
type: playbook
for: [MSPs & agencies]
---

Per-client memory your AI runs

Deploy a private knowledge base your AI runs. Once per client.

Basic Memory doesn't replace your ticket system. Tickets live in HaloPSA, Autotask, ConnectWise, wherever you already track them. We're the long-term context layer next to it: durable notes, runbooks, and decisions, owned by you and queryable by your AI. Every BM record links back to its source-of-truth ticket.

## The problem

The 'why' behind every ticket disappears.

Your ticketing system records what happened. It rarely captures why, what you tried, or what to do next time. That context lives in chat scrollback, individual heads, and PSA scratchpads. And it vanishes the moment the ticket closes. New tickets re-learn the same lessons.

## How it works in Basic Memory

The workflow.

  1. 1Stand up a Claude Team plan per client, with Basic Memory connected as a central MCP and our shared Agent Skills available out of the box.
  2. 2Define schemas for the durable context you want to keep. Person, Organization, Ticket Record, Runbook. And drop them into the workspace. The Ticket schema expects a `ticket_url` linking back to the source ticket in your PSA.
  3. 3Add a CLAUDE.md to the workspace telling Claude how to operate inside it: which notes to load first, what's append-only, and how to use the schemas.
  4. 4As work happens, Claude writes durable records alongside the operational ticket. Call notes, diagnoses, resolutions. Each one links the source ticket; the runbooks compound across clients.
Claude is the back-office secretary that runs everything… before Basic Memory I'd have been working 120 hours a week.MSP owner-operator

## What you get

The outcome.

Your ticketing system stays the operational source of truth. Basic Memory becomes the durable context layer that pays forward. Runbooks, patterns, and resolutions your whole team and its AI agents can query, owned by you instead of locked in a vendor database.

## In practice

Help desk on a real schema. End to end.

Here's the loop running for real. The ticket itself lives in the MSP's ticketing system (HaloPSA in this example). What follows is what Basic Memory holds alongside it. Durable schemas, the call notes, the resolution, and a runbook that pays forward to the next caller. Every code block is captured live from a real Basic Memory project; nothing is fabricated.

schemas/Person.md. The canonical Person schema

Verbatim from the docs. This is the picoschema format. Required and optional fields, typed relations (capitalized like Organization), arrays, enums. Define the shape once for every entity that recurs across clients.

---
title: Person
type: schema
entity: person
version: 1
schema:
  name: string, full name
  role?: string, job title
  email?: string, contact email
  works_at?: Organization, employer
  expertise?(array, areas of knowledge): string
settings:
  validation: warn
  frontmatter:
    tags?(array): string
    status?(enum):
    - active
    - inactive
    - archived
---
schemas/Ticket.md. Durable record, not the ticket itself

The schema models what we keep about a ticket. Not the ticket's operational state. `ticket_url` is required: every BM record links back to its source-of-truth ticket in the PSA. `status` and `priority` are captured as snapshot context, not authoritative. Required Person relation; required dated frontmatter.

---
title: Ticket
type: schema
entity: ticket
version: 2
schema:
  title: string, short summary of the issue
  ticket_url: string, URL of the source-of-truth ticket in the
              ticketing system
  status(enum, snapshot at capture time):
  - open
  - in-progress
  - blocked
  - resolved
  priority(enum, how urgent):
  - low
  - normal
  - high
  - urgent
  reported_by: Person, who reported the issue
  client?: Organization, client the ticket belongs to
  category?(enum, area of the system):
  - network
  - hardware
  - software
  - access
  - other
  resolution?: string, how it was resolved
  blocks?(array, downstream work): Ticket
settings:
  validation: warn
  frontmatter:
    opened_at: string, ISO date
    closed_at?: string, ISO date when resolved
    tags?(array): string
---
tickets/2026-06-18. Printer offline at downtown location.md

What an AI writes after Jamie calls in. The ticket itself was opened in HaloPSA. The [ticket_url] observation links back to it. Everything else is the durable context BM keeps: typed observations, the call notes, the relations to Person and Organization.

---
title: 2026-06-18 — Printer offline at downtown location
type: ticket
opened_at: '2026-06-18T09:14:00Z'
---

# Printer offline at downtown location

## Observations

- [title] Receipt printer offline at the downtown register
- [ticket_url] https://halo.acmemsp.example/tickets/8472
- [status] open
- [priority] high
- [reported_by] [[Jamie Rivera]]
- [client] [[Acme Bakery]]
- [category] hardware

## Description

Jamie called in: receipt printer at the downtown register stopped
responding around 9am. POS terminal still online; staff are
handwriting receipts. Other two locations unaffected.

## Relations

- reported_by [[Jamie Rivera]]
- client [[Acme Bakery]]
tickets/2026-06-18. POS slow at midtown.md

An hour later, the same agent picks up an offhand mention and writes a stub so it doesn't get lost. Title and ticket_url are present (HaloPSA #8473), but the rest is missing. The schema is about to catch it.

---
title: 2026-06-18 — POS slow at midtown
type: ticket
opened_at: '2026-06-18T14:02:00Z'
---

# POS slow at midtown

Jamie mentioned offhand that the midtown POS has been slow today.
No formal report yet. Capturing this as a stub so we don't lose it.

## Observations

- [title] POS terminal slow at midtown location
- [ticket_url] https://halo.acmemsp.example/tickets/8473
- [priority] normal
→ schema_validate(note_type="ticket")

The agent batch-validates every ticket in the project. The complete one passes; the stub gets two warnings naming the exact fields that are missing. This is the real, unedited output from the MCP tool.

# Schema Validation: ticket

Notes: 2 | Valid: 2 | Warnings: 2 | Errors: 0

- **2026-06-18. Printer offline at downtown location**. Valid
- **2026-06-18. POS slow at midtown**. Valid
  - warning: Missing required field: status
    (expected [status] observation)
  - warning: Missing required field: reported_by
    (no 'reported_by [[...]]' relation found)
→ schema_validate(note_type="ticket") // after fix

The agent reads the warnings, adds the missing [status] observation and the reported_by relation, and re-runs validation. Both tickets clean. The schema kept the graph consistent. Without anyone having to remember to check.

# Schema Validation: ticket

Notes: 2 | Valid: 2 | Warnings: 0 | Errors: 0

- **2026-06-18. Printer offline at downtown location**. Valid
- **2026-06-18. POS slow at midtown**. Valid
runbooks/Runbook. Receipt printer offline.md

Here's the moment that makes the case, and it's outside the ticketing system entirely. HaloPSA records that the printer was fixed. It does not extract the pattern. The agent does that here, turning today's resolution into tomorrow's SOP. Plain Markdown the MSP owns, queryable by every future agent. The ticket links the runbook (documented_in); the runbook back-links automatically (referenced_by). One wiki-link, two-way visibility. Next time someone reports a stuck queue, the runbook is already there. Nobody had to file it.

---
title: Runbook — Receipt printer offline
type: runbook
tags: [runbook, hardware, pos]
category: hardware
---

# Runbook. Receipt printer offline

For client POS receipt printers that stop responding while the
terminal stays online.

## Symptoms

- Receipt printer unresponsive
- POS terminal still functional
- Often one register affected while others continue normally

## Diagnostic steps

1. Confirm power, USB, and paper.
2. Check the print spooler service on the register's host machine.
3. Inspect the print queue for stuck jobs. Large multi-page prints
   are the usual suspect.
4. If the queue has a stuck job, clear it and restart the spooler.
5. Send a test receipt to verify.

## Observations

- [pattern] Stuck queue is the most common cause
- [pattern] Watch for accidental large jobs sent the night before
- [convention] Always confirm the fix with the on-site contact
  before closing the ticket

## Relations

- referenced_by [[2026-06-18. Printer offline at downtown location]]
→ search_notes(query="printer stuck queue")

Two weeks from now, someone reports a printer issue. The agent searches before it acts. And the runbook ranks first. The graph is doing the librarian's job without anyone curating an index. This is the loop that makes a knowledge base smarter the more you use it.

# Search Results: printer stuck queue

### Runbook. Receipt printer offline
  score: 1.2356
  For client POS receipt printers that stop responding...

### 2026-06-18. Printer offline at downtown location
  score: 0.9459
  ## Observations
  - [title] Receipt printer offline at the downtown register
  - [status] resolved
  - [resolution] Stuck print queue cleared...

### Ticket  (schema)
  score: 0.5906
  Schema for help desk tickets. What was reported, by whom...
From the field

Schemas are the most important piece

Schemas are the most important piece, probably more than the notes themselves. The notes the client writes against those schemas are theirs, editable and growing. The template is the skeleton. Their knowledge fills in on top.

MSP partner, on what makes the per-client flow hold up. The opinion is right. Schemas are the load-bearing wall. Use Basic Memory's schema system above and you get this for free, across every client tenant.

## FAQ

Common questions.

How can an MSP deploy AI knowledge bases for clients?
Build a reusable memory pack. Schemas, templates, SOPs, and agent instructions. Then provision an isolated Basic Memory workspace per client from it. Claude runs the back office against each workspace: onboarding, filing documents to schema, and handling tickets, all in plain Markdown the client owns.
Is each client's data isolated?
Yes. Every client gets its own isolated database and file storage. There is no shared tenancy at the data layer. With optional Entra SSO and consolidated billing for the partner.

Try this playbook.

Free and open source to run locally. Two minutes to connect your first AI tool.