Skip to content

Add support for source URIs on memories - #168

Merged
kentcdodds merged 3 commits into
mainfrom
cursor/source-uris-memories-09a5
Apr 14, 2026
Merged

kentcdodds merged 3 commits into
mainfrom
cursor/source-uris-memories-09a5

Conversation

@kentcdodds

@kentcdodds kentcdodds commented Apr 14, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • add optional source_uris support to memory types, zod schemas, service normalization, D1 persistence, and all MCP memory read responses
  • preserve backward compatibility by defaulting missing stored values to [] and adding a D1 migration with a source_uris_json column default
  • add focused service and MCP E2E coverage for valid URLs, invalid URL rejection, and legacy rows without the new field

Testing

  • npx vitest run --project node-unit packages/worker/src/mcp/memory/service.node.test.ts
  • node tools/prepare-e2e-env.ts && npm run build:mcp-apps && npx vitest run --project mcp-e2e packages/worker/src/mcp/mcp-server.mcp-e2e.test.ts
  • npm run typecheck

Follow-up

  • address review nits by reusing the shared memorySourceUriSchema in meta-memory-verify.ts
  • add an explicit memoryId guard in mcp-server.mcp-e2e.test.ts before templating the meta_memory_get execute payload
Open in Web Open in Cursor 

Summary by CodeRabbit

  • New Features

    • Memory records now support an optional source_uris field to track document sources (e.g., GitHub files, object URLs, Notion pages); surfaced in create, read, search, verify, and tool summaries.
  • Documentation

    • Clarified the meaning and format of source_uris in memory documentation.
  • Tests

    • Added coverage for upsert/get/search/verify flows with source_uris and legacy-record behavior.
  • Bug Fix / Migration

    • DB migration and parsing ensure existing records default to an empty source_uris list and validate incoming URIs.

Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
@coderabbitai

coderabbitai Bot commented Apr 14, 2026 •

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 86fee2ae-89cb-41f3-97e3-725aa5b9b8d1

📥 Commits

Reviewing files that changed from the base of the PR and between c6d8de0 and bbac007.

📒 Files selected for processing (4)
  • packages/worker/src/mcp/capabilities/meta/meta-memory-shared.ts
  • packages/worker/src/mcp/capabilities/meta/meta-memory-verify.ts
  • packages/worker/src/mcp/mcp-server.mcp-e2e.test.ts
  • packages/worker/src/mcp/memory/service.ts
🚧 Files skipped from review as they are similar to previous changes (4)
  • packages/worker/src/mcp/mcp-server.mcp-e2e.test.ts
  • packages/worker/src/mcp/capabilities/meta/meta-memory-verify.ts
  • packages/worker/src/mcp/capabilities/meta/meta-memory-shared.ts
  • packages/worker/src/mcp/memory/service.ts

📝 Walkthrough

Walkthrough

This PR adds optional source_uris to the memory subsystem: DB schema, types, repo, service validation/normalization, MCP capability inputs/outputs, search results, tool summaries, and tests — persisting, validating, and propagating source-URI arrays across memory operations.

Changes

Cohort / File(s) Summary
Documentation & Migration
docs/use/memory.md, packages/worker/migrations/0018-mcp-memory-source-uris.sql
Documented source_uris; DB migration adds non-null source_uris_json TEXT column with default '[]'.
Types
packages/worker/src/mcp/memory/types.ts
Added source_uris_json: string to MemoryRow and sourceUris: string[] to MemoryMetadata.
Repo & DB Mapping
packages/worker/src/mcp/memory/repo.ts
SELECT/INSERT/UPDATE now include source_uris_json; mapMemoryRow reads it into rows; updateMemory fields accept source_uris_json.
Service Layer
packages/worker/src/mcp/memory/service.ts, packages/worker/src/mcp/memory/memory-search.ts, packages/worker/src/mcp/memory/types.ts
Added sourceUris to upsert/verify inputs and MemoryRecord; introduced normalizeSourceUris() (trim/dedupe/validate), parseJsonStringArray()/parseSourceUris(); search returns sourceUris from DB JSON.
MCP Capabilities & Schemas
packages/worker/src/mcp/capabilities/meta/meta-memory-shared.ts, .../meta-memory-upsert.ts, .../meta-memory-get.ts, .../meta-memory-search.ts, .../meta-memory-delete.ts, .../meta-memory-verify.ts
Added Zod schemas for source_uris (URL + length/count caps); handlers accept source_uris input and include source_uris in responses (upsert/get/search/delete/verify).
Tooling / UI Formatting
packages/worker/src/mcp/tools/memory-tool-context.ts
Memory summaries now include sourceUris; markdown formatting conditionally renders a "Sources:" bullet when present.
Tests
packages/worker/src/mcp/memory/service.node.test.ts, packages/worker/src/mcp/mcp-server.mcp-e2e.test.ts
Added tests for upsert/get/search propagation of source_uris, validation errors for invalid URLs, and legacy-row handling defaulting to [].

Sequence Diagram(s)

mermaid
sequenceDiagram
participant Client as rgba(52,152,219,0.5) Client
participant MCP as rgba(46,204,113,0.5) MCP Server
participant Service as rgba(241,196,15,0.5) Memory Service
participant DB as rgba(155,89,182,0.5) Database

Client->>MCP: codemode.meta_memory_upsert { source_uris: [...] }
MCP->>Service: upsertMemory(args with sourceUris)
Service->>Service: normalizeSourceUris()
Service->>DB: INSERT/UPDATE source_uris_json = JSON.stringify(sourceUris)
DB-->>Service: row with source_uris_json
Service->>MCP: return memory { source_uris: [...] }
MCP-->>Client: response with memory.source_uris

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~23 minutes

Possibly related PRs

Poem

🐰
I found some URLs and tucked them in my store,
Each memory now whispers where it came before,
GitHub, R2, Notion — breadcrumbs in a line,
Hopping through JSON, tidy, trimmed, and fine.
The rabbit hums: "Sources saved!" — a tiny sign.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'Add support for source URIs on memories' directly and accurately summarizes the main change: introducing optional source_uris fields to memory records across types, schemas, service logic, database persistence, and MCP capabilities.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch cursor/source-uris-memories-09a5

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@kentcdodds
kentcdodds marked this pull request as ready for review April 14, 2026 05:43
@github-actions

github-actions Bot commented Apr 14, 2026 •

Copy link
Copy Markdown
Contributor

🔎 Preview deployed: https://kody-pr-168.kentcdodds.workers.dev

Worker: kody-pr-168
D1: kody-pr-168-db
KV: kody-pr-168-oauth-kv

Mocks:

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
packages/worker/src/mcp/mcp-server.mcp-e2e.test.ts (1)

81-90: Consider an explicit guard for memoryId before templating it into execute code.

This makes failures clearer and avoids accidentally generating memory_id: undefined if earlier expectations are refactored later.

Optional test hardening diff
 	const memoryId = upsertStructured?.result?.memory?.id
+	expect(memoryId).toBeDefined()
+	if (!memoryId) {
+		throw new Error('Expected memory id from meta_memory_upsert')
+	}
 
 	const getResult = await mcpClient.client.callTool({
 		name: 'execute',
 		arguments: {
 			code: `async () => {
 				return await codemode.meta_memory_get({
 					memory_id: ${JSON.stringify(memoryId)},
 				})
 			}`,
 		},
 	})
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/worker/src/mcp/mcp-server.mcp-e2e.test.ts` around lines 81 - 90, The
test currently templates memoryId (from upsertStructured?.result?.memory?.id)
directly into the execute code which can produce `memory_id: undefined`; add an
explicit guard/assert for memoryId before calling mcpClient.client.callTool (for
example check `if (!memoryId) throw new Error("missing memoryId")` or use the
test framework's expect/assert) so the test fails with a clear message and never
interpolates an undefined value into the code string passed to
mcpClient.client.callTool.
packages/worker/src/mcp/capabilities/meta/meta-memory-verify.ts (1)

38-38: Consider aligning the schema with memoryRecordSchema for consistency.

The candidate.source_uris is defined as a required array z.array(z.string().url()), while memoryRecordSchema in meta-memory-shared.ts defines it as z.array(memorySourceUriSchema).optional().

While this works correctly (since verifyMemoryCandidate always returns source_uris as an array), using the shared memorySourceUriSchema would improve consistency:

♻️ Suggested improvement
+import {
+	memoryRecordSchema,
+	memorySourceUriSchema,
+	memoryVerifyInputSchema,
+	requireMcpUser,
+} from './meta-memory-shared.ts'

 const outputSchema = z.object({
 	candidate: z.object({
 		subject: z.string(),
 		summary: z.string(),
 		details: z.string(),
 		category: z.string().nullable(),
 		tags: z.array(z.string()),
-		source_uris: z.array(z.string().url()),
+		source_uris: z.array(memorySourceUriSchema),
 		dedupe_key: z.string().nullable(),
 	}),
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/worker/src/mcp/capabilities/meta/meta-memory-verify.ts` at line 38,
The candidate schema in meta-memory-verify.ts uses source_uris:
z.array(z.string().url()) but should align with the shared memoryRecordSchema;
replace this with the shared memorySourceUriSchema (and make it optional like
memoryRecordSchema) so the candidate validation uses
z.array(memorySourceUriSchema).optional() (or the equivalent pattern used in
meta-memory-shared.ts) — update the schema where candidate.source_uris is
defined and import memorySourceUriSchema from meta-memory-shared.ts and keep
verifyMemoryCandidate behavior intact.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@packages/worker/src/mcp/capabilities/meta/meta-memory-verify.ts`:
- Line 38: The candidate schema in meta-memory-verify.ts uses source_uris:
z.array(z.string().url()) but should align with the shared memoryRecordSchema;
replace this with the shared memorySourceUriSchema (and make it optional like
memoryRecordSchema) so the candidate validation uses
z.array(memorySourceUriSchema).optional() (or the equivalent pattern used in
meta-memory-shared.ts) — update the schema where candidate.source_uris is
defined and import memorySourceUriSchema from meta-memory-shared.ts and keep
verifyMemoryCandidate behavior intact.

In `@packages/worker/src/mcp/mcp-server.mcp-e2e.test.ts`:
- Around line 81-90: The test currently templates memoryId (from
upsertStructured?.result?.memory?.id) directly into the execute code which can
produce `memory_id: undefined`; add an explicit guard/assert for memoryId before
calling mcpClient.client.callTool (for example check `if (!memoryId) throw new
Error("missing memoryId")` or use the test framework's expect/assert) so the
test fails with a clear message and never interpolates an undefined value into
the code string passed to mcpClient.client.callTool.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: fd192d2e-925f-4658-851f-d70925e8cee8

📥 Commits

Reviewing files that changed from the base of the PR and between cab119c and c6d8de0.

📒 Files selected for processing (15)
  • docs/use/memory.md
  • packages/worker/migrations/0018-mcp-memory-source-uris.sql
  • packages/worker/src/mcp/capabilities/meta/meta-memory-delete.ts
  • packages/worker/src/mcp/capabilities/meta/meta-memory-get.ts
  • packages/worker/src/mcp/capabilities/meta/meta-memory-search.ts
  • packages/worker/src/mcp/capabilities/meta/meta-memory-shared.ts
  • packages/worker/src/mcp/capabilities/meta/meta-memory-upsert.ts
  • packages/worker/src/mcp/capabilities/meta/meta-memory-verify.ts
  • packages/worker/src/mcp/mcp-server.mcp-e2e.test.ts
  • packages/worker/src/mcp/memory/memory-search.ts
  • packages/worker/src/mcp/memory/repo.ts
  • packages/worker/src/mcp/memory/service.node.test.ts
  • packages/worker/src/mcp/memory/service.ts
  • packages/worker/src/mcp/memory/types.ts
  • packages/worker/src/mcp/tools/memory-tool-context.ts

@cursor cursor Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

Bugbot Autofix prepared fixes for both issues found in the latest run.

  • ✅ Fixed: Source URIs array lacks max size constraint
    • Added explicit source URI count/length limits in the schema and normalization logic to prevent unbounded storage.
  • ✅ Fixed: Redundant identical function duplicates existing helper
    • Deduplicated the JSON array parsing by using a shared helper for tags and source URIs.

You can send follow-ups to the cloud agent here.

Reviewed by Cursor Bugbot for commit c6d8de0. Configure here.

Comment thread packages/worker/src/mcp/memory/service.ts
Comment thread packages/worker/src/mcp/memory/service.ts
cursoragent and others added 2 commits April 14, 2026 05:57
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
@kentcdodds
kentcdodds merged commit 5ac3c10 into main Apr 14, 2026
9 checks passed
@kentcdodds
kentcdodds deleted the cursor/source-uris-memories-09a5 branch April 14, 2026 14:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants