Skip to content

backlog: share MCP/viewer access and schema primitives #8

Description

@ZeR020

Status

Private backlog on this fork only. Do not implement until the pi 8-layer stack is on upstream main (or abandoned). Do not add commits to stack/1stack/8.

Do not mention this issue on upstream PRs.

What this is

kunickiaj’s review of the original pi PR listed an important follow-up (not one of the seven blockers):

MCP/viewer memory access and schema behavior should share core primitives to avoid authorization and contract drift.

His stack sketch put this in layer 1: “Shared spool/memory-access refactors.”

We already shipped spool + the kind catalog in layer 1. We did not ship shared access helpers. This issue is the rest of that follow-up.

Plain language: MCP and viewer HTTP are two doors into the same notebook. The rules for “what kinds exist” and “may this caller see/write this note” must live in @codemem/core. Each door calls those rules. They must not keep their own copies.

Already done (do not redo)

  • packages/core/src/memory-kinds.ts — kinds + validateMemoryKind
  • MCP memory-kinds.ts re-exports core
  • Viewer remember routes import REMEMBER_MEMORY_KINDS
  • Bounded JSON parser exported from viewer helpers; L3 POSTs use it
  • Auth check both doors already use is store.timeline(..., filters)

Still to do

Schema (contract)

  1. MCP memoryKindSchema in packages/mcp-server/src/schemas.ts must be derived from REMEMBER_MEMORY_KINDS. Delete the handwritten z.enum(["discovery", …]).
  2. One filter-key list in @codemem/core. Viewer SCHEMA_FILTER_NAMES and MCP filterNames both come from it. No second hand-sorted array.

Access (authorization)

Move the twins into core. Callers pass only what differs:

  • getVisibleMemory(store, id, filters)store.timeline(null, id, 0, 0, filters).find(...)
  • getVisibleMemories / forgetVisibleMemory the same way
  • rememberVisibleMemory(store, input, { toolVersion, metadata, envProject, cwd, user, now })

MCP keeps toolVersion: "mcp-ts", metadata: { mcp: true }.
Viewer keeps toolVersion: "viewer-api", metadata: { viewer: true }.

Existing MCP tests in memory-access.test.ts should keep passing against the core functions (or thin aliases).

Must not change (regression guards)

Sharing primitives does not mean sharing defaults.

  • Viewer read project default stays null. Do not inject process cwd / CODEMEM_PROJECT on HTTP.
  • MCP read may still default project from cwd/env. Pass defaultProject in; do not pick one policy for both.
  • Writes on both doors already honor explicit project or env only. Keep that.
  • Do not extract expandMemories, distill file loading, HTTP parseGetFilters, or the retrieval ledger.

When to implement

  1. Layer 1 is on upstream main.
  2. Prefer waiting until layer 3 (viewer routes) is also there, so one PR can switch both doors.
  3. Branch from upstream main, not from stack/8.
  4. Do not shrink this back to “lists only.”

Verification

  • pnpm exec vitest run packages/mcp-server/src/memory-access.test.ts packages/mcp-server/src/server.test.ts
  • CODEMEM_EMBEDDING_DISABLED=1 pnpm exec vitest run packages/viewer-server/src/routes/memory-tools.test.ts
  • MCP kind enum === REMEMBER_MEMORY_KINDS
  • Viewer schema filter names === MCP filterNames === core list
  • Nested-cwd / no-implicit-project tests on the viewer still pass
  • tool_version / session metadata still mcp-ts vs viewer-api

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions