Skip to content

feat(mcp): generate a search index and serve it from ports and adapters - #128

Open
oto-macenauer-absa wants to merge 1 commit into
masterfrom
feat/mcp-search-index
Open

oto-macenauer-absa wants to merge 1 commit into
masterfrom
feat/mcp-search-index

Conversation

@oto-macenauer-absa

@oto-macenauer-absa oto-macenauer-absa commented Oct 21, 2026 •

Copy link
Copy Markdown
Collaborator

What

First layer of the MCP server stack (#117): the search index the build generates and the search engine that serves it. No server yet, and nothing is exposed.

Stack: this PR ← #129 (MCP runtime) ← #119 (deployment and docs).

Changes

  • mcp/search-index/schema.ts: the search index file format and validateSearchIndex(). It is the only code that build and runtime share.

  • mcp/build/, build time only:

    • extract.ts turns untrusted page HTML into bounded, markdown-like text with parse5;
    • index-builder.ts builds the deterministic index.
  • scripts/build-mcp.js: new build step 3b, which writes dist/_mcp/search-index.json. It is listed in .dockerignore, so it never reaches the nginx web root.

  • mcp/src/, the domain behind ports and adapters:

    • ports.ts: the DocumentRepository and SearchBackend ports (async; cursors are opaque and owned by the adapter);
    • knowledge-base.ts: the KnowledgeBase facade;
    • adapters/memory/: the in-memory adapters (stemmed term frequency, title boost, compound split, fuzzy match);
    • compose.ts: wires the adapters to the facade.

    A future backend such as AWS OpenSearch is a new adapter pair.

  • TypeScript that Node runs as-is: mcp/tsconfig.json allows only syntax Node can erase.

  • Lint tooling: ESLint strictTypeChecked, Prettier, an import boundary that keeps build-time code out of the runtime, npm run lint, and a CI lint job.

  • scripts/build-vite.js: public assets are copied rather than hardlinked, which keeps the CI artifact archiver reliable.

  • Tests (npm run test:mcp):

    • a backend contract suite, which any future backend must pass;
    • extraction;
    • search index edge cases;
    • ranking examples over the fixture build.

Verification

  • npm run lint: green
  • npm audit --omit=dev --audit-level=high: green
  • npm test: all passed
  • npm run test:mcp: all passed
  • npx playwright test --config=playwright.config.ci.js: all passed
  • npm run test:container: all passed

Part of #117

🤖 Generated with Claude Code

Build step 3b extracts every page's untrusted HTML into bounded text
(mcp/build/) and writes dist/_mcp/search-index.json, kept out of the
image's web root by .dockerignore. mcp/search-index/schema.ts is the
file format, the only code build and runtime share.

The runtime domain sits behind DocumentRepository and SearchBackend
ports with a KnowledgeBase facade; adapters/memory/ implements both
over the search index (stemmed lexical ranking, title boost, compound
split, fuzzy match). A future backend such as OpenSearch is a new
adapter pair that must pass tests/support/backend-contract.js.

TypeScript limited to erasable syntax so Node runs it as-is; linted by
tsc, ESLint strictTypeChecked and Prettier (npm run lint, new CI job),
with an import boundary keeping build-time code out of the runtime.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
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.

1 participant