Skip to content

RAG Search MCP App - #25

Open
Noah Dorce (noahDee) wants to merge 10 commits into
mainfrom
rag-mcp-app
Open

RAG Search MCP App#25
Noah Dorce (noahDee) wants to merge 10 commits into
mainfrom
rag-mcp-app

Conversation

@noahDee

@noahDee Noah Dorce (noahDee) commented Jun 22, 2026

Copy link
Copy Markdown

Summary
Adds a self-contained example under agents/rag-search-mcp/ demonstrating retrieval-augmented generation with per-patient access control on the Corti Agentic Framework. It pairs a local MCP server that does scoped document search with a UI app that auto-provisions a Corti orchestrator wired to that MCP. A clinician signs in, sees their patient panel, and chats with the agent. Retrieval is scoped server-side to exactly the patients that clinician is allowed to see, so the agent can never surface records outside that panel, including while asking clarifying questions.

What's included

search-documents-mcp (TypeScript): A stateful Streamable-HTTP MCP server exposing one search_documents tool. Embeddings run on-device; chunks are tagged shared or patient: and filtered by a verified scope token bound to the A2A contextId. Also serves /bind-context and /ingest.
rag-ui-corti (React + Express): Connects to Corti, provisions an orchestrator wired to the MCP, and gives a clinician sign-in, patient panel, scoped chat, and document upload. Each message carries a short-lived scope token from the clinician's panel.

Packages / tools
MCP server: @modelcontextprotocol/sdk, @huggingface/transformers (all-MiniLM-L6-v2, ONNX runtime), express, zod, TypeScript.
UI app: react 18 + vite, express, @corti/sdk, lucide-react, tailwindcss, dotenv, concurrently.
Auth between the two: HMAC-signed, audience-scoped, 5-minute scope tokens (the UI signs, the MCP verifies a shared secret).

Planed updates

  • The ability to enter new patient info when uploading a document.
  • Add sample questions to README for testing
  • Pairing with other Corti agents to tie to ecosystem
Medical.Document.RAG.Lookup.App.Overview.mp4

Copilot AI 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.

Pull request overview

Adds a new self-contained example under agents/rag-search-mcp/ demonstrating retrieval‑augmented generation (RAG) with per‑patient access control: a stateful Streamable‑HTTP MCP server provides scoped semantic search, and a React+Express UI provisions/uses a Corti orchestrator and mints short‑lived scope tokens.

Changes:

  • Added search-documents-mcp (TypeScript) MCP server: embedding-based local retrieval, disk-backed chunk store, scope-token verification, and HTTP endpoints (/mcp, /bind-context, /ingest).
  • Added rag-ui-corti (React + Express) app: Corti connection + orchestrator provisioning/detection, mock clinician sign-in and patient panel, scoped chat, and document upload.
  • Added mock documents and READMEs to make the demo runnable end-to-end.

Reviewed changes

Copilot reviewed 52 out of 55 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
agents/rag-search-mcp/README.md Top-level README describing the two demo components and how to run them.
agents/rag-search-mcp/search-documents-mcp/tsconfig.json TypeScript compiler configuration for the MCP server.
agents/rag-search-mcp/search-documents-mcp/package.json MCP server package metadata and runtime dependencies.
agents/rag-search-mcp/search-documents-mcp/package-lock.json MCP server dependency lockfile.
agents/rag-search-mcp/search-documents-mcp/.env.example Example env vars for MCP server (secret + port).
agents/rag-search-mcp/search-documents-mcp/README.md MCP server documentation: flow, scoping model, endpoints, and setup.
agents/rag-search-mcp/search-documents-mcp/src/embed.ts On-device embedding generation via @huggingface/transformers.
agents/rag-search-mcp/search-documents-mcp/src/store.ts File-backed chunk store + scoped semantic search implementation.
agents/rag-search-mcp/search-documents-mcp/src/token.ts Scope-token verification (HMAC + exp).
agents/rag-search-mcp/search-documents-mcp/src/scope.ts Auth header parsing + contextId→scope binding store.
agents/rag-search-mcp/search-documents-mcp/src/server.ts MCP tool definition (search_documents) and response formatting.
agents/rag-search-mcp/search-documents-mcp/src/http.ts Express HTTP wrapper for MCP transport + /bind-context + /ingest.
agents/rag-search-mcp/search-documents-mcp/src/ingest.ts CLI ingestion utility for indexing docs/.
agents/rag-search-mcp/search-documents-mcp/docs/clinic-policy.md Mock shared reference document.
agents/rag-search-mcp/search-documents-mcp/docs/records-retention-memo.md Mock shared reference document (retention update).
agents/rag-search-mcp/search-documents-mcp/docs/hypertension-guideline.md Mock shared reference guideline document.
agents/rag-search-mcp/search-documents-mcp/docs/diabetes-guideline.md Mock shared reference guideline document.
agents/rag-search-mcp/search-documents-mcp/docs/metformin-medication-sheet.md Mock shared reference medication sheet.
agents/rag-search-mcp/search-documents-mcp/docs/discharge-summary.md Mock patient-scoped document (patient:000-MOCK-1234).
agents/rag-search-mcp/search-documents-mcp/docs/discharge-summary-2.md Mock patient-scoped document (patient:000-MOCK-5678).
agents/rag-search-mcp/search-documents-mcp/docs/lab-results.md Mock patient-scoped document (patient:000-MOCK-5678).
agents/rag-search-mcp/search-documents-mcp/docs/clinic-note-sam.md Mock patient-scoped document (patient:000-MOCK-3456).
agents/rag-search-mcp/search-documents-mcp/docs/cardiology-note-maria.md Mock patient-scoped document (patient:000-MOCK-9012).
agents/rag-search-mcp/rag-ui-corti/package.json UI app package metadata and dependencies.
agents/rag-search-mcp/rag-ui-corti/package-lock.json UI app dependency lockfile.
agents/rag-search-mcp/rag-ui-corti/.env.example Example env vars for Corti + MCP wiring + token secret + prompt.
agents/rag-search-mcp/rag-ui-corti/config.js Env loading/validation and derived MCP endpoint URLs.
agents/rag-search-mcp/rag-ui-corti/corti.js Corti SDK client lifecycle + Express guards + error shaping.
agents/rag-search-mcp/rag-ui-corti/session.js In-process “active clinician” and active MCP name tracking.
agents/rag-search-mcp/rag-ui-corti/directory.js Mock clinician/patient directory + profile shaping for UI.
agents/rag-search-mcp/rag-ui-corti/token.mjs HMAC signing for scope tokens minted by the UI app.
agents/rag-search-mcp/rag-ui-corti/mcp.js Token minting (scopes + names + audience) + agent MCP matching by URL.
agents/rag-search-mcp/rag-ui-corti/server.js Express API server wiring + JSON size limit configuration.
agents/rag-search-mcp/rag-ui-corti/routes/auth.js /api/auth route to establish Corti connection.
agents/rag-search-mcp/rag-ui-corti/routes/clinicians.js Clinician listing + mock “sign-in” route.
agents/rag-search-mcp/rag-ui-corti/routes/agent.js Agent detection-by-MCP-URL + provisioning route.
agents/rag-search-mcp/rag-ui-corti/routes/chat.js Chat start (warmup + pre-bind) + message relay with token DataPart.
agents/rag-search-mcp/rag-ui-corti/routes/documents.js Document upload route enforcing scope against clinician panel.
agents/rag-search-mcp/rag-ui-corti/index.html Vite app entry HTML + font loading.
agents/rag-search-mcp/rag-ui-corti/vite.config.js Vite dev server configuration + /api proxy.
agents/rag-search-mcp/rag-ui-corti/tailwind.config.js Tailwind theme configuration (tokens + fonts).
agents/rag-search-mcp/rag-ui-corti/postcss.config.js PostCSS plugins for Tailwind build.
agents/rag-search-mcp/rag-ui-corti/src/main.jsx React entrypoint.
agents/rag-search-mcp/rag-ui-corti/src/index.css Tailwind base styles + theme variables.
agents/rag-search-mcp/rag-ui-corti/src/api.js Frontend API client + agent-task polling helpers.
agents/rag-search-mcp/rag-ui-corti/src/ui.jsx Shared UI primitives (Banner, ScreenHeader, MONO).
agents/rag-search-mcp/rag-ui-corti/src/App.jsx Top-level flow orchestration between views.
agents/rag-search-mcp/rag-ui-corti/src/AuthView.jsx “Connect to Corti” screen.
agents/rag-search-mcp/rag-ui-corti/src/AgentSetupView.jsx Detect-or-create orchestrator screen.
agents/rag-search-mcp/rag-ui-corti/src/ClinicianSignInView.jsx Mock clinician picker screen.
agents/rag-search-mcp/rag-ui-corti/src/PatientPanelView.jsx Patient panel + start chat/upload navigation.
agents/rag-search-mcp/rag-ui-corti/src/UploadView.jsx Upload document UI (scope selection + file/text ingest).
agents/rag-search-mcp/rag-ui-corti/src/AgentChatView.jsx Minimal chat UI with file attachment support and context continuity.
agents/rag-search-mcp/rag-ui-corti/README.md UI app documentation: setup, token flow, and layout.
Files not reviewed (1)
  • agents/rag-search-mcp/search-documents-mcp/package-lock.json: Generated file

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread agents/typescript/search-documents-mcp/src/http.ts
Comment thread agents/rag-search-mcp/search-documents-mcp/src/http.ts
Comment thread agents/rag-search-mcp/search-documents-mcp/src/token.ts
Comment thread agents/typescript/search-documents-mcp/src/token.ts
Comment thread agents/rag-search-mcp/rag-ui-corti/config.js Outdated
Comment thread agents/typescript/search-documents-mcp/src/server.ts
Comment thread agents/rag-search-mcp/search-documents-mcp/src/http.ts
Comment thread agents/rag-search-mcp/search-documents-mcp/src/scope.ts Outdated
Comment thread agents/typescript/search-documents-mcp/package-lock.json
@noahDee
Noah Dorce (noahDee) marked this pull request as ready for review June 23, 2026 20:46

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

These comments were written with AI assistance and validated by a person. They may still be more robust than you expect — please ask if anything seems off or unclear.

Thanks for this — it is a genuinely well-built example. The scoped RAG design is thoughtful, both component READMEs are thorough, and the security-sensitive paths (scope tokens, ingest gating) are implemented carefully. A few repo-convention items to sort before merge. Inline comments have the per-file detail.

Blockers

  • Folder layout does not match repo convention (inline). Use {category}/{language-or-stack}/{example-name}/ — e.g. agents/react/..., agents/typescript/... — not agents/rag-search-mcp/{app}.
  • Root README.md not updated (inline). Add row(s) under ### Agents so the example is discoverable.
  • Not wired into CI (.github/workflows/sdk-examples-ci.yml). Neither app is registered — checks were skipped on this PR, not passed. Add ts-filter + matching include per project.
  • Missing linter setup in both projects (inline). Repo convention; add Biome even though CI did not run here.

Should fix

  • @corti/sdk pinned to ^1.2.0 — bump to ^3/^4 or latest (inline).
  • VITE_-prefixed Corti credentials + non-standard env names (inline).
  • Parent README "Note" contradicts the code and links to missing notes.md (inline).

Nits (optional)

  • Add "private": true to both package.json files (inline).
  • Clarify committed data/index.json vs npm run reindex in MCP README (inline).
  • notes.md link also in MCP README Layout section (inline).
  • UI server is plain .js while MCP is TypeScript — consider aligning (inline).

Code quality

  • Checked naming: module/route files use camelCase (corti.js, auth.js), React components use PascalCase (AgentChatView.jsx) — matches repo standard.
  • Main naming gap is env vars (VITE_CORTI_* vs CORTI_*) — covered inline.
  • rag-ui-corti keeps Express at the project root and React under src/; acceptable for a Vite + Express split.

Security: no committed secrets; Corti client secret is read server-side only today. The VITE_ prefix on secrets is still a footgun — fix inline.

(Left as a draft for a maintainer to review and submit.)

Comment thread agents/rag-search-mcp/README.md Outdated
Comment thread agents/rag-search-mcp/README.md Outdated
Comment thread agents/rag-search-mcp/README.md Outdated
Comment thread agents/react/search-documents-ui/package.json
Comment thread agents/react/search-documents-ui/package.json
Comment thread agents/typescript/search-documents-mcp/package.json
Comment thread agents/typescript/search-documents-mcp/package.json
Comment thread agents/rag-search-mcp/search-documents-mcp/README.md Outdated
Comment thread agents/rag-search-mcp/search-documents-mcp/README.md Outdated
Comment thread agents/rag-search-mcp/rag-ui-corti/.env.example Outdated

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

These comments were written with AI assistance and validated by a person. They may still be more robust than you expect — please ask if anything seems off or unclear.

Thanks for the follow-up — a lot of the earlier feedback landed cleanly (folder layout, root README rows, Biome config, @corti/sdklatest, CORTI_* env naming, private: true, TypeScript server migration). Remaining items below each match an inline comment.

Re-review

  • ✅ Addressed: agents/react/search-documents-ui/ + agents/typescript/search-documents-mcp/ layout; root README Agents rows; Biome + lint scripts; @corti/sdk latest; no VITE_ Corti secrets; private: true; Express server in TypeScript; parent notes.md / contradictory Note removed.
  • ⚠️ Still open: neither project is wired into CI (carried forward).
  • 💬 Discussed (no change needed): ALLOW_INGEST default-off + README warnings; skipping localhost bind and verbose demo logging (not required for merge).

Blockers

  • CI still not registered for either new project.
  • npm run lint fails in search-documents-ui (56 errors) — will break CI once wired.

Should fix

  • MCP README claims a committed data/index.json that is not in the PR.

Code quality

  • Naming/structure look good (camelCase modules, PascalCase React components, Corti calls go through @corti/sdk on the server). Scope-token design is solid.

"build": "vite build",
"preview": "vite preview",
"typecheck": "tsc -p tsconfig.server.json",
"lint": "biome check ."

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Blocker: wire both new projects into CI. Neither search-documents-ui nor search-documents-mcp appears in .github/workflows/sdk-examples-ci.yml — path filters + matrix include — so lint/build never run on this contribution.

Why it matters: without this, regressions land silently and Biome issues (see sibling comment) never surface on the PR.

How to fix: add two filters under the ts-filter step and matching include entries, mirroring react-next-agent-chat:

search-documents-ui:
  - 'agents/react/search-documents-ui/**'
  - '.github/workflows/sdk-examples-ci.yml'
search-documents-mcp:
  - 'agents/typescript/search-documents-mcp/**'
  - '.github/workflows/sdk-examples-ci.yml'

and:

- project: search-documents-ui
  path: agents/react/search-documents-ui
- project: search-documents-mcp
  path: agents/typescript/search-documents-mcp

Filter name must match the project value. Same pattern as agents/react/next-agent-chat.

"build": "vite build",
"preview": "vite preview",
"typecheck": "tsc -p tsconfig.server.json",
"lint": "biome check ."

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Blocker: npm run lint fails (56 errors). Biome is present (good — prior feedback addressed), but biome check . currently exits non-zero. Most hits are lint/style/useBlockStatements (e.g. server/corti.ts, server/mcp.ts), noNonNullAssertion in server/config.ts, and useButtonType in the React views.

Why it matters: once CI is wired (previous comment), this job will fail and block merge. Even locally, a red lint script means the example does not match repo convention.

How to fix: from this directory run npx biome check --write . (or fix manually), then re-run npm run lint until it is clean. Compare with sdk/typescript/express-web-api/ for the same Biome ruleset.

npm run reindex # optional on first run — a prebuilt index is committed
```

> **First run:** `data/index.json` is committed, so you can skip `npm run reindex`

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Should fix: README says data/index.json is committed, but it is not in the PR. Setup calls reindex "optional on first run" and the callout says you can skip straight to Running — yet there is no data/ directory in the tree. Skipping reindex leaves an empty index (store.ts treats a missing file as []), so search_documents returns nothing.

Why it matters: readers following this README alone will think the demo works out of the box; the UI README correctly requires npm run reindex, so the two halves disagree.

How to fix: either commit a generated data/index.json, or (simpler) make reindex required in Setup — drop the "optional / prebuilt index" wording and align with agents/react/search-documents-ui/README.md (npm run build && npm run reindex && npm run start:http).

Noah Dorce and others added 10 commits August 6, 2026 20:27
Logging scopes count vs. logging full patient MRN

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

Potential fix for pull request finding

Scope count vs. full patient MRN

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

Potential fix for pull request finding

Dont log sensitive data

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

Potential fix for pull request finding

Kebab case project name

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
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.

3 participants