feat: item 8 (search-mcp cartridge) + ADR-0013 streamable HTTP transport (epic #87)#99
Merged
Merged
Conversation
docs(item-14): ADR-0013 Streamable HTTP transport Two epic #87 Tier A items in one PR — search-mcp ships as code, HTTP-transport ships as an RFC (~1-2 weeks of impl work per epic estimate; design-first per Tier B pattern). == Item 8 — search-mcp cartridge == Multi-provider web search behind one cartridge, four providers: - Tavily — LLM-optimised summaries; answer-mode; extract API - Brave — privacy-first index; no tracking - Exa — neural search over high-quality content; extract API - Perplexity — Q&A-style answers with citations Surface: - cartridges/search-mcp/cartridge.json — manifest with 4 cartridge- level tools (search_authenticate / web / answer / extract) - cartridges/search-mcp/README.adoc — provider strengths + auth env vars + bridge wiring note - mcp-bridge/lib/tools.js — single boj_search bridge tool dispatching to cartridge via operation + provider args (open=tavily/brave/exa/ perplexity for web; perplexity/tavily for answer; tavily/exa for extract). AAA-tier description carries the provider matrix so the LLM picks correctly. - mcp-bridge/main.js — dispatch case routes to search-mcp via invokeCartridge; hardeningGate requires operation field; domain classification: search - mcp-bridge/lib/offline-menu.js — search-mcp added to Teranga tier Backend implementation in the Elixir/Zig dispatch layer is deferred; surface area is captured so MCP clients can already discover and invoke (returns hint until backend lands). Existing 15/15 tests pass; boj_search appears in tools/list. == Item 14 — ADR-0013 Streamable HTTP transport == RFC for adding MCP's HTTP+SSE transport alongside stdio. Same bridge binary; BOJ_TRANSPORT=stdio|http|both selects mode. No existing stdio clients break. Key design points: - Single endpoint POST /mcp + GET /mcp (SSE) per latest MCP spec - Mcp-Session-Id UUIDs maintained server-side for per-session state - Auth: none (loopback-only) | bearer | mTLS | OIDC - Mounts on the same Cowboy listener as webhooks (ADR-0004 honoured) - Workers deployment: ~60% of cartridges work (HTTP-API-based); local-only cartridges (browser-mcp, container-mcp, local-coord-mcp, local sandbox) don't and are reported via boj_capabilities - Federation (ADR-0010) reuses this transport layer - Webhook notifications (ADR-0011) fan out over the SSE stream Three new deployment targets unlocked: Workers, containers, browser-based agents. Implementation plan: 2 PRs over ~1-2 weeks. Tracked in epic #87 item 14. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced May 20, 2026
🔍 Hypatia Security ScanFindings: 33 issues detected
View findings[
{
"reason": "Stale AI session file -- delete",
"type": "stale",
"file": "GEMINI.md",
"action": "delete",
"rule_module": "root_hygiene",
"severity": "medium"
},
{
"reason": "Issue in quality.yml",
"type": "missing_workflow",
"file": "quality.yml",
"action": "create",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Issue in security-policy.yml",
"type": "missing_workflow",
"file": "security-policy.yml",
"action": "create",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Action actions/cache@v4 needs attention",
"type": "unpinned_action",
"file": "abi-drift.yml",
"action": "pin_sha",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Action hyperpolymath/standards/.github/workflows/governance-reusable.yml@main needs attention",
"type": "unpinned_action",
"file": "governance.yml",
"action": "pin_sha",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Python file detected -- banned language",
"type": "banned_language_file",
"file": "/home/runner/work/boj-server/boj-server/.github/scripts/validate-eclexiaiser.py",
"action": "flag",
"rule_module": "cicd_rules",
"severity": "critical"
},
{
"reason": "TypeScript file detected -- banned language",
"type": "banned_language_file",
"file": "/home/runner/work/boj-server/boj-server/cartridges/sanctify-mcp/adapter/mod.ts",
"action": "flag",
"rule_module": "cicd_rules",
"severity": "critical"
},
{
"reason": "TypeScript file detected -- banned language",
"type": "banned_language_file",
"file": "/home/runner/work/boj-server/boj-server/cartridges/academic-workflow-mcp/adapter/mod.ts",
"action": "flag",
"rule_module": "cicd_rules",
"severity": "critical"
},
{
"reason": "TypeScript file detected -- banned language",
"type": "banned_language_file",
"file": "/home/runner/work/boj-server/boj-server/cartridges/fireflag-mcp/adapter/mod.ts",
"action": "flag",
"rule_module": "cicd_rules",
"severity": "critical"
},
{
"reason": "TypeScript file detected -- banned language",
"type": "banned_language_file",
"file": "/home/runner/work/boj-server/boj-server/cartridges/ephapax-mcp/adapter/mod.ts",
"action": "flag",
"rule_module": "cicd_rules",
"severity": "critical"
}
]Powered by Hypatia Neurosymbolic CI/CD Intelligence |
hyperpolymath
added a commit
that referenced
this pull request
May 20, 2026
…ultimodal (#103) ## Summary Closes the bridge-surface portion of epic #87 items 7 and 9. Backend dispatch (Elixir/Zig) tracked separately in tracker issues #100 (vector) and #101 (multi-modal). Eight new cartridges in two domains; two new umbrella bridge tools. ## Item 7 — Vector databases (4 cartridges) | Cartridge | Provider strength | |---|---| | \`pinecone-mcp\` | Hosted serverless indexes; dimension + metric required at create-time | | \`weaviate-mcp\` | Hybrid (vector + BM25) search; schema-driven classes; modular vectorisers | | \`qdrant-mcp\` | Rust-native; payload filtering; sparse + dense vectors; self-host or cloud | | \`chromadb-mcp\` | Embedded or client/server; LLM-app-focused; document storage alongside vectors | All four share a **7-operation manifest**: \`authenticate\` / \`list_collections\` / \`create_collection\` / \`delete_collection\` / \`upsert\` / \`query\` / \`delete\`. Provider-specific extras live under \`params\` (Pinecone namespace, Weaviate alpha-hybrid weight, Qdrant score_threshold, Chroma embedding_function). ## Item 9 — Multi-modal (4 cartridges) | Cartridge | Role | Worker-compat? | |---|---|---| | \`whisper-mcp\` | Speech-to-text (OpenAI API + local whisper.cpp backends) | ✅ HTTP API | | \`elevenlabs-mcp\` | Text-to-speech, voice cloning (premium), multilingual | ✅ HTTP API | | \`replicate-mcp\` | Image/video/audio generation; async prediction model | ✅ HTTP API | | \`ffmpeg-mcp\` | Local transcoding (probe/extract/concat/trim) | ❌ **Local-only** per ADR-0013 | ffmpeg-mcp is the glue: extract audio from video → whisper transcribe; extract frames → replicate vision model; etc. ## Bridge tools (2 new) Both follow the \`boj_search\` umbrella pattern from PR #99: \`\`\` boj_vector {operation, provider ∈ {pinecone|weaviate|qdrant|chromadb}, ...} boj_multimodal {operation, provider ∈ {whisper|elevenlabs|replicate|ffmpeg}, ...} \`\`\` Each dispatches via \`invokeCartridge\` to the right cartridge. \`hardeningGate\` requires \`operation\`. Domain classifications added: \`vector\`, \`multimodal\`. ## Offline-menu All 8 cartridges added to \`mcp-bridge/lib/offline-menu.js\` (Teranga tier) so they surface in \`boj_menu\` even when the REST backend is offline. ## Tool count 42 (after \`boj_search\`) → **44** (after \`boj_vector\` + \`boj_multimodal\`). Per the umbrella-tool design choice in #100/#101, adding 8 cartridges added only 2 bridge tools — not 8. ## Tests - ✅ 15/15 existing tests pass (no regressions) - ✅ \`tools/list\` advertises both new tools end-to-end (verified via \`deno run\`) ## What's NOT in this PR - Idris2 ABI, Zig FFI, Deno adapter for any of the 8 cartridges — just the manifest + bridge wiring - Tests against live provider APIs — surface captured; contract testing comes with backend impl - Backend dispatch in the Elixir/Zig layer — per-cartridge follow-up work (~1-2 days each per the trackers) ## Sequencing This closes the **mechanical** portion of items 7 and 9. The trackers (#100, #101) update on merge — backends remain open for follow-up sessions. Epic #87 status after this lands: - Tier A: items 1, 8, 13 done in code; items 7, 9 **surfaces done** (backends pending); item 14 RFC only - Tier B: 6/6 RFCs done - Tier C: items 11, 12 untouched 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two epic #87 Tier A items in one PR — item 8 ships as code, item 14 ships as an RFC (the impl is ~1-2 weeks of focused work per epic estimate; design-first per the Tier B pattern).
Item 8 — `search-mcp` cartridge + `boj_search` bridge tool
Multi-provider web search behind one cartridge:
What's in the diff
Status
Bridge surface captured — MCP clients discover and invoke today. Backend dispatch implementation in Elixir/Zig deferred (separate work).
Tests
Item 14 — ADR-0013 Streamable HTTP transport
RFC for adding MCP's HTTP+SSE transport alongside stdio. Same bridge binary; `BOJ_TRANSPORT=stdio|http|both` selects mode. No existing stdio clients break.
Why this RFC matters
JSR's runtime-compatibility question surfaced the gap: the user can't tick "Browsers" or "Cloudflare Workers" because the bridge legitimately doesn't run there. Item 14 is the right framing — not "make stdio work in a browser" (architecturally wrong) but "add an HTTP transport for the contexts where stdio doesn't work."
Key design points
Three new deployment targets unlocked
Implementation sketch
2 PRs over ~1-2 weeks:
Federation alignment
ADR-0010 (cross-machine federation) needs HTTPS transport anyway. ADR-0013's transport layer is reusable for federation. Webhook notifications (ADR-0011) fan out over this RFC's SSE stream.
Sequencing
Independent of all currently-open PRs. Item 8 lands as code; item 14 lands as RFC awaiting implementation in follow-up. After this lands, epic #87 Tier A remaining is items 7 (vector DBs × 4) + 9 (multi-modal × 4) — both multi-cartridge waves that warrant separate sessions, not a single rushed PR.
🤖 Generated with Claude Code