LidLift is a launch-ready tool-dissonance product for MCP stacks. It scores prompt-to-tool fit before execution, turns that score into an explicit guardrail decision, ranks safer alternatives, and exposes the same analysis engine through a remote MCP server.
- Web console:
https://lidlift.optimizationinversion.com - API health:
https://api.optimizationinversion.com/health - MCP endpoint:
https://api.optimizationinversion.com/mcp - GitHub:
https://github.com/igor-holt/lidlift-mcp
apps/web: Next.js App Router operator console for Vercelworkers/mcp: Cloudflare Worker exposing remote MCP tools on/mcppackages/core: shared heuristics, schemas, and sample catalogVercel AI SDK + AI Gateway: optional narrative briefing layer for the web API
- Interactive console with live preview, ranked results, and explicit
allow/review/clarify/blockgates GET|POST /api/discover-toolsfor vendor-native tool discovery with cache control, force refresh, and vendor auto-detectionPOST /api/analyzefor deterministic ranking plus optional AI Gateway narrative outputGET /api/healthfor web readiness checksGET|POST /discover-toolsplusPOST /mcpfor remote MCP transport on Cloudflare Workers- Shared Zod-backed schemas so the browser, API layer, and MCP worker stay aligned
pnpm install
pnpm dev:web
pnpm dev:mcpOpen the web app from the URL printed by Next.js. The Worker runs locally through Wrangler.
Web app:
- Copy [apps/web/.env.example](/Users/igorholt/LidLift MCP/apps/web/.env.example:1)
- Set
AI_GATEWAY_API_KEYfor local operator brief generation - Override
AI_GATEWAY_MODELif you do not want the defaultanthropic/claude-sonnet-4.6 - Set
NEXT_PUBLIC_MCP_SERVER_URLafter deploying the Cloudflare Worker - Set
LIDLIFT_DISCOVERY_CACHE_TTL_SECONDSto tune vendor discovery cache lifetime. Default:600 - Optional vendor discovery keys:
OPENAI_API_KEY,ANTHROPIC_API_KEY,XAI_API_KEY,GEMINI_API_KEY
Worker:
- No secrets are required for the public analyzer
- Set
LIDLIFT_DISCOVERY_CACHE_TTL_SECONDSto tune discovery cache lifetime. Default:600 - Optional vendor discovery keys can be configured as Worker secrets with the same names:
OPENAI_API_KEY,ANTHROPIC_API_KEY,XAI_API_KEY,GEMINI_API_KEY - Optional production KV cache: bind
DISCOVERY_CACHEinwrangler.jsoncand the Worker will persist discovery cache entries in KV instead of process memory - Optional local vars can go in [workers/mcp/.dev.vars.example](/Users/igorholt/LidLift MCP/workers/mcp/.dev.vars.example:1) once you extend the Worker with auth or upstream APIs
LidLift can now discover a vendor's built-in tool surface without a hand-authored tool catalog.
curl "https://api.optimizationinversion.com/discover-tools?vendor=openai&model=gpt-5" \
-H "Authorization: Bearer $OPENAI_API_KEY"curl "https://lidlift.optimizationinversion.com/api/discover-tools?model=gpt-5" \
-H "X-Vendor: openai" \
-H "Authorization: Bearer $OPENAI_API_KEY"curl "https://lidlift.optimizationinversion.com/api/discover-tools" \
-X POST \
-H "Content-Type: application/json" \
-d '{
"vendor": "anthropic",
"model": "claude-sonnet-4-5",
"auth_token": "'"$ANTHROPIC_API_KEY"'"
}'curl "https://api.optimizationinversion.com/discover-tools?vendor=openai&model=gpt-5&force_refresh=true" \
-H "Authorization: Bearer $OPENAI_API_KEY"curl "https://lidlift.optimizationinversion.com/api/analyze" \
-X POST \
-H "Content-Type: application/json" \
-d '{
"prompt": "Find the safest way to inspect today's production logs.",
"vendor": "openai",
"model": "gpt-5"
}'If you pass both vendor and tools, LidLift merges the vendor-discovered tools with your supplied catalog and prefers the later definition when names collide.
/api/analyze also accepts force_refresh: true and will pass it through to vendor discovery before ranking.
The Cloudflare Worker now exposes a discover_vendor_tools MCP tool and rank_tools accepts vendor, model, and optional auth_token.
{
"name": "rank_tools",
"arguments": {
"prompt": "Review the repo and patch the failing test without publishing anything.",
"vendor": "xai",
"model": "grok-4.20-reasoning"
}
}- Default cache TTL is
600seconds throughLIDLIFT_DISCOVERY_CACHE_TTL_SECONDS - Web routes fall back to in-process memory cache
- The Cloudflare Worker can use an optional
DISCOVERY_CACHEKV binding for shared cache across isolates - Use
force_refresh=trueonly for CI, debugging, or vendor validation drift checks. It bypasses cache and increases upstream pressure
- LidLift returns structured discovery errors with codes such as
ERR_RATE_LIMIT,ERR_AUTH, andERR_VENDOR - When a vendor returns
429, LidLift preservesretryAfterSecondswhen available - Recommended production policy: keep the default 10 minute TTL, avoid force refresh in hot paths, and route customer-triggered refreshes through explicit admin actions
These discovery hardening tests now live under packages/core/src/vendors/__tests__/:
autoDetectVendorcoverage forX-Vendor, provider-specific headers, bearer token patterns, andUser-AgentdiscoverVendorToolscache hit, miss, force refresh, TTL expiry, and sanitized error behavior- Adapter coverage for OpenAI live validation plus Anthropic, xAI, and Gemini static built-in fallbacks
- Add the vendor literal to packages/core/src/types.ts.
- Extend
normalizeVendor, default model mapping, and environment variable lookup in packages/core/src/discovery.ts. - Add a built-in manifest entry set and expose it through
vendorAdapterRegistry. - Add auto-detection hints in packages/core/src/vendors/auto-detect.ts if the vendor has recognizable headers or token patterns.
- Add adapter and discovery tests in
packages/core/src/vendors/__tests__/.
- The production Vercel project is linked to this repository with
apps/webas the root directory. - Add
AI_GATEWAY_API_KEY,AI_GATEWAY_MODEL, andNEXT_PUBLIC_MCP_SERVER_URL. - Push to
mainto trigger a Git-backed deployment, or use Vercel previews for branch validation.
- Deploy from
workers/mcp. - Publish with
pnpm --filter mcp deploy. - The production MCP endpoint is
https://api.optimizationinversion.com/mcp.
These commands are already passing in this workspace:
pnpm --filter @tool-dissonance/core test
pnpm --filter mcp check
pnpm --filter mcp test
pnpm --filter web lint
pnpm build