Repository navigation
Rebuild knowledge-base around Context GROQ and Knowledge Bases - #53
Conversation
Replace the App SDK dashboard with a help center plus support and ops chat, seed Beacon content including the 30 vs 45 day refund conflict, and document the product-side MCP setup. Co-authored-by: Cursor <cursoragent@cursor.com>
| import {handleChat} from '@/lib/chat-handler' | ||
|
|
||
| export async function POST(req: Request) { | ||
| return handleChat(req, 'ops') |
There was a problem hiding this comment.
🔒 Agentic Security Review
Severity: HIGH
POST /api/chat/internal calls handleChat(req, 'ops') with no session, secret, or middleware check. That handler then attaches SANITY_ORGANIZATION_TOKEN to the ops GROQ and Knowledge Base MCP URLs and auto-runs those tools. /internal and the public nav expose the same staff surface.
Impact: Anyone who can reach a deployed help center can retrieve internal runbooks and policy data that this starter treats as staff-only, and can spend the deployer’s Anthropic quota as an unauthenticated MCP proxy.
Reviewed by Cursor Security Reviewer for commit 7f37c25. Configure here.
There was a problem hiding this comment.
No this works as intentional. For the starter I want people to be able to easily demo and experience the internal chat as well. WE shouldn't publish this starter live as a demo since these are ungated chat routes.
The ops surface is fictional Beacon content, not a staff trust boundary; call out auth only if real internal sources are wired later. Co-authored-by: Cursor <cursoragent@cursor.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…onventions
Correctness
- Fail loudly when /initial-context is refused or empty: throw
InitialContextError, return 502 {error} from the chat routes, render it
in the chat UI. An empty KB outline was previously a silent "no results".
- Restore the 22 markdown seed sources beside their PDFs so
`seed:files` and the "edit the source" story work again.
- Commit packages/@starter/sanity-types/sanity.types.ts (un-ignore) so
fresh clones and Vercel builds resolve the types.
- KB dataset source query dereferences products/topics to titles.
- beacon-catalog groqFilter only passes published FAQs.
- Seed review dates are relative to generation time; bootstrap regenerates
before import so the Needs Review demo does not rot.
- Model -> claude-sonnet-5. Prompts: FAQ answerText projection,
internalCategory->title instead of a nonexistent `category` field.
- Close MCP clients on every streamText exit path (onError/onAbort,
consumeStream, allSettled connects).
Setup path
- Each chat route runs with whichever of its GROQ / KB MCP URLs is set.
- New context/ directory with copy-paste purpose, source query, groqFilter
and full Instructions text for both Knowledge Bases and all four MCPs.
- Cache initial context 5 min per endpoint; Accept: text/plain per docs.
- Drop the unused SANITY_ORGANIZATION_ID prompt and env var.
- README: Labs page (not Manage -> Apps) for enabling Knowledge Bases,
URL override params, seed editing, Deploying section, two stale files,
manual-Instruction fallback, accurate bootstrap and token descriptions.
Conventions
- Remove duplicate AGENTS.md (CLAUDE.md -> AGENT.md symlink remains).
- Add deploy.yml mirroring commerce-pdp-management, with the read token
the private-dataset app build needs.
- Build functions in CI before the bundle-size check (starter + root).
- Remove dead `next lint` script (Next 16). Ignore .pnpm-store/ at root.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
Fixed some issues that were identified in the other starters around CI/CD processes and missing sanity types. |
| return (value ?? {}) as ToolSet | ||
| } | ||
|
|
||
| export function renameTools( |
There was a problem hiding this comment.
We'd recommend not renaming tools, as they are referenced by their OOTB name in initial context.
Could the instructions field in the MCP endpoint cover the reasons as to why it should call these GROQ tools instead?
There was a problem hiding this comment.
Sounds good. We should probably add a sentence clarifying this since my agent got this idea from the patterns doc around Context: https://www.sanity.io/docs/ai/sanity-context-patterns specifically renaming groq_query when there are multiple endpoints.
| if (cached && cached.expires > Date.now()) return cached.value | ||
|
|
||
| // The endpoint returns text/plain (Markdown), per the docs. | ||
| const response = await fetch(`${url.replace(/\/$/, '')}/initial-context`, { |
There was a problem hiding this comment.
Prefer using new URL() and append to pathname instead, so query params don't get mangled. (Query params can be used for important stuff like workspace)
| - "Is a paused campaign's audience still billed?" -> Knowledge Base. | ||
| - "What is the refund window?" -> GROQ for the FAQ fact. If the user wants the policy explained, also read the Knowledge Base. | ||
|
|
||
| GROQ hybrid search (semanticSimilarity only inside score()): |
There was a problem hiding this comment.
I'd try removing instructions regarding how to use semanticSimilarity and which tools exists. Context MCP should provide all the instructions it needs in initial context and tool descriptions. Users shouldn't need to be concerned about the inner workings of the MCP ideally. Let us know if you experience any regressions!
| Routing: | ||
| - "Which policies are overdue for review?" -> GROQ on policy. | ||
| - "How do I handle a SEV-1?" -> Knowledge Base runbooks. | ||
| - Credit thresholds ($500) live on the refund policy (GROQ). The customer-facing refund window is 30 days. |
There was a problem hiding this comment.
This pattern could cause drift from actual content. If the goal is to tell the agent to check refund policy in the dataset for credit threshold values, I'd try adding it in the instructions field on the MCP endpoint instead. That's where we recommend putting retrieval tips. (Good practice even though it's probably not gonna drift in this example)
…nner prompts Per @torbratsberg on #53: - Stop renaming MCP tools. Initial context refers to them by their served names, so the renamed toolset and the inlined instructions disagreed. Only initial_context is dropped (its payload is inlined). GROQ and KB modes expose disjoint tool sets, so nothing collides. - Build the /initial-context URL with new URL() and append to pathname, so query params on the MCP URL (e.g. ?workspace=) are preserved. - Remove GROQ/semanticSimilarity how-to and tool inventories from the system prompts. Prompts now carry voice, boundaries, and which surface owns which kinds of facts; retrieval guidance lives in each MCP's initial context and instructions field (context/mcp/*.md). - Remove hardcoded content values ($500 threshold, 30-day window) from the ops prompt and from the checked-in MCP instructions; point at the policy documents and the Knowledge Base's Instruction instead. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>




Summary
/chat) and ops (/internal) agents.Test plan
cd knowledge-base && pnpm install && pnpm run format:check && pnpm run lint && pnpm run typecheck && pnpm run validatepnpm bootstrapon a fresh project (schema deploy, private dataset, embeddings, Viewer token, seed import)app/.env.localMade with Cursor