Skip to content

feat(mcp): add Keenable to the MCP marketplace - #2313

Merged
taltas merged 1 commit into
Zoo-Code-Org:mainfrom
keenableai:feat/keenable-mcp
Nov 4, 2026
Merged

taltas merged 1 commit into
Zoo-Code-Org:mainfrom
keenableai:feat/keenable-mcp

Conversation

@ilya-bogin-keenable

Copy link
Copy Markdown
Contributor

Related GitHub Issue

Closes: #2312

Description

This PR adds a keenable item to src/assets/marketplace/mcps.yml. The item goes between kagi and laravel-boost, so the list stays in alphabetical order. It uses the same remote-server pattern as the AnySearch entry from #1955. There are no TypeScript changes.

  • Remote Server: streamable-http at https://api.keenable.ai/mcp-public. No account or key is needed.
  • Remote Server (API Key): the same endpoint with an X-API-Key: {{KEENABLE_API_KEY}} header. The installer asks for the key. The key only raises the rate limits.

Both methods send an X-Keenable-Title: Zoo Code header. Keenable uses it to count traffic per app. The server has two read-only tools: search_web_pages and fetch_page_content.

Data sent to Keenable: the search query or the page URL, and the X-Keenable-Title header. The API key is sent only when the user selects the API key method.

Roadmap area: Enhanced User Experience. Users get web search in one click, with no sign-up.

Test Procedure

  • I loaded the real mcps.yml through ConfigLoader, which uses the extension schema. Result: 67 MCP items, unique ids, alphabetical order kept, keenable right after kagi.
  • I installed both methods with SimpleInstaller into a temporary .roo/mcp.json. I parsed each result with ServerConfigSchema from McpHub. The keyless config has no X-API-Key header. The API key method puts the given key into the header.
  • Live, no key: I connected to the installed config with StreamableHTTPClientTransport and McpOAuthClientProvider. This is the same setup that McpHub uses for streamable-http. The connection took 320 ms. There was no UnauthorizedError and no sign-in step. tools/list returned search_web_pages and fetch_page_content. One search_web_pages call returned 10 results in 329 ms.
  • npx vitest run services/marketplace __tests__/dist_assets.spec.ts (after pnpm bundle): the 88 existing tests pass.
  • npx prettier --check src/assets/marketplace/mcps.yml passes.
  • I did not run a live call with an API key.

Pre-Submission Checklist

  • Issue Linked: This PR is linked to an approved GitHub Issue (see "Related GitHub Issue" above).
  • Scope: My changes are focused on the linked issue (one major feature/fix per PR).
  • Self-Review: I reviewed my own code with care.
  • Writing Style: The PR title and description use Simplified Technical English (ASD-STE100): short sentences, plain words, active voice, one idea per sentence, no contractions.
  • Testing: Not applicable. This is a config-only change. The checks above cover it.
  • Test Helpers (test changes only): Not applicable.
  • Visual Snapshot (UI changes only): Not applicable.
  • Documentation Impact: I checked if my changes need documentation updates (see "Documentation Updates" section below).
  • Contribution Guidelines: I read and agree to the Contributor Guidelines.

Documentation Updates

  • No documentation updates are required.

Additional Notes

Disclosure: I work at Keenable, which runs this MCP server.

@coderabbitai

coderabbitai Bot commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review.

Summary

Summary by CodeRabbit

  • New Features
    • Added the Keenable server to the marketplace, with web search and page-fetching capabilities.
    • The server can be configured with an API key or used without one.

The marketplace now includes Keenable with a public remote-server configuration and an optional API-key configuration. Both use the Keenable MCP endpoint and send the X-Keenable-Title header.

Changes: Keenable marketplace entry

Layer / File(s) Summary
Add remote server configurations
src/assets/marketplace/mcps.yml
Adds public and API-key configurations for the Keenable endpoint. Both send X-Keenable-Title; the API-key configuration also sends X-API-Key from KEENABLE_API_KEY and declares a placeholder. The entry describes web search and page fetching.

Estimated code review effort: 2 (Simple) | ~5 minutes

Change: Feature

Merge Risk: Minimal · up to 802fa

The Keenable entry adds public and optional API-key installation options. No actionable merge-blocking issue remains established.

Pre-merge checks: Passed 8
Check name Status Explanation
Title check Passed The title "feat(mcp): add Keenable to the MCP marketplace" matches the main change. The PR adds a keenable entry to src/assets/marketplace/mcps.yml, and the raw summary confirms it. The title is short…
Description check Passed The description follows the template and fills in the required sections. It links issue #2312 with "Closes: #2312". It explains the change, including the remote-server configs, the X-API-Key header, t…
Linked Issues check Passed The change implements the coding requirements in #2312. It adds keenable in src/assets/marketplace/mcps.yml between kagi and laravel-boost. It defines both Streamable HTTP methods at `https://…
Out of Scope Changes check Passed The whole-PR diff contains only the Keenable marketplace entry requested by #2312. The entry metadata, tags, descriptions, and installer parameter support that marketplace addition. No unrelated sourc…
Regression Evidence Passed PASS. The PR changes only the declarative src/assets/marketplace/mcps.yml file. It adds one MCP item with two existing marketplace installation-method shapes: streamable HTTP content and a parameter…
Security Boundaries Passed PASS. The pull request changes only src/assets/marketplace/mcps.yml. The new Keenable entries use fixed HTTPS URL https://api.keenable.ai/mcp-public and a fixed X-Keenable-Title value. The API k…
Persistence Integrity Passed Pass. The pull request changes only the static marketplace definition in src/assets/marketplace/mcps.yml (36 inserted lines). The Keenable entries define HTTP configuration and parameter substitutio…
Lifecycle Resource Cleanup Passed PASS — The pull request changes only src/assets/marketplace/mcps.yml and adds static Streamable HTTP server configurations. The changed entries define URLs and headers; they add no listener, watcher…
Full details: Title check

Explanation

The title "feat(mcp): add Keenable to the MCP marketplace" matches the main change. The PR adds a keenable entry to src/assets/marketplace/mcps.yml, and the raw summary confirms it. The title is short, uses one sentence, and names the feature and the affected area. It omits the two install methods, but it does not need to cover every detail.

Full details: Description check

Explanation

The description follows the template and fills in the required sections. It links issue #2312 with "Closes: #2312". It explains the change, including the remote-server configs, the X-API-Key header, the X-Keenable-Title header, and the two read-only tools. It gives a detailed test procedure with the commands and results. The pre-submission checklist is complete, and the documentation section is filled in. The Visual Snapshots and Videos sections are omitted, which is acceptable because the change is config-only and has no UI impact. The description meets the template's required content.

Full details: Linked Issues check

Explanation

The change implements the coding requirements in #2312. It adds keenable in src/assets/marketplace/mcps.yml between kagi and laravel-boost. It defines both Streamable HTTP methods at https://api.keenable.ai/mcp-public. The key method sends X-API-Key from {{KEENABLE_API_KEY}}; both methods send X-Keenable-Title: Zoo Code. The entry states that the service supports web search and page fetching, and that the API key is optional and raises rate limits.

Full details: Out of Scope Changes check

Explanation

The whole-PR diff contains only the Keenable marketplace entry requested by #2312. The entry metadata, tags, descriptions, and installer parameter support that marketplace addition. No unrelated source, TypeScript, or configuration changes are present.

Full details: Regression Evidence

Explanation

PASS. The PR changes only the declarative src/assets/marketplace/mcps.yml file. It adds one MCP item with two existing marketplace installation-method shapes: streamable HTTP content and a parameterized X-API-Key header. ConfigLoader already validates these shapes through mcpMarketplaceItemSchema, and SimpleInstaller already handles method selection and parameter replacement. No executable code or durable UI changed, so focused new regression tests are not required for this mechanical configuration change.

Full details: Security Boundaries

Explanation

PASS. The pull request changes only src/assets/marketplace/mcps.yml. The new Keenable entries use fixed HTTPS URL https://api.keenable.ai/mcp-public and a fixed X-Keenable-Title value. The API key placeholder is used only as the user-selected X-API-Key header for that endpoint. The configuration defines no command, executable, redirectable input, or allowlist bypass. Search and page data are sent to the declared MCP service as the advertised function. No changed path leaks secrets or PII to an unintended destination.

Full details: Persistence Integrity

Explanation

Pass. The pull request changes only the static marketplace definition in src/assets/marketplace/mcps.yml (36 inserted lines). The Keenable entries define HTTP configuration and parameter substitution; they do not add persistence operations. The downstream installer path is unchanged and only provides existing JSON read/write behavior in SimpleInstaller.ts:226-265. No changed persistence path can lose or corrupt state under this check.

Full details: Lifecycle Resource Cleanup

Explanation

PASS — The pull request changes only src/assets/marketplace/mcps.yml and adds static Streamable HTTP server configurations. The changed entries define URLs and headers; they add no listener, watcher, provider, timer, task, cancellation, disposal, or restart logic. No changed lifecycle path can leak resources or duplicate work.

Finishing Touches
Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

CodeRabbit Verify

  • Run CodeRabbit Verify to test the changes in this pull request.
Recent review info
Run configuration
Commits

Reviewing files that changed from the base of the PR and between 3ee042d and 802fa19.

Files selected for processing: 1
  • src/assets/marketplace/mcps.yml

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 7 remain after this review.

Recent review details
Additional context used
Path-based instructions: 2
Verify extension/webview contracts, cancellation and error propagation, VS Code lifecycle correctness, and behavior under retries and partial failure.

CodeRabbit configuration file

Files:

  • src/assets/marketplace/mcps.yml
Act as an adversarial second-opinion reviewer.

CodeRabbit configuration file

Files:

  • src/assets/marketplace/mcps.yml

@codecov

codecov Bot commented Nov 3, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@github-actions

github-actions Bot commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

Review status

Thanks for contributing. This comment tracks the review sequence and the next action.

Current step: The required review sequence passed. Remaining merge requirements apply.

Review-state labels are managed by this workflow; do not edit them manually. community-approved is managed the same way — do not add or remove it manually. It signals a fresh community code approval for the current head as an advisory priority only; maintainer review is still required.

@github-actions github-actions Bot added coderabbit-review-active Required CI passed; CodeRabbit review is active awaiting-coderabbit Waiting for CodeRabbit to approve the latest commit labels Nov 3, 2026
@github-actions github-actions Bot added awaiting-maintainer CodeRabbit approved; waiting for a human maintainer and removed coderabbit-review-active Required CI passed; CodeRabbit review is active awaiting-coderabbit Waiting for CodeRabbit to approve the latest commit labels Nov 3, 2026

@taltas taltas 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.

Hi @ilya-bogin-keenable, thanks for the MCP, looks great! Wishing you and Keenable the best.

@taltas
taltas added this pull request to the merge queue Nov 3, 2026
@github-actions github-actions Bot removed the awaiting-maintainer CodeRabbit approved; waiting for a human maintainer label Nov 3, 2026
Merged via the queue into Zoo-Code-Org:main with commit d4722af Nov 4, 2026
25 checks passed
easonLiangWorldedtech added a commit to easonLiangWorldedtech/Zoo-Code that referenced this pull request Nov 5, 2026
Live merge base 3ee042d; main brought 6 commits (Zoo-Code-Org#2223 display settings, Zoo-Code-Org#2313
Keenable, Zoo-Code-Org#1309 abort-signal round 2, Zoo-Code-Org#2293 mutant comments, Zoo-Code-Org#2294 CI hygiene,
Zoo-Code-Org#1207 BM25 ranker) across 113 paths. Conflict prediction by blob identity against
the live merge base flagged 10 shared paths; 8 auto-merged and 2 needed a hand
resolution. Both hand resolutions keep the settled side and our side:

- src/core/webview/ClineProvider.ts: kept main's displaySettings import and our
  extra ProviderSettingsNotFoundError binding; took main's three new display keys
  (timeFormat/dateFormat/showRelativeTimes) into our getState() return, re-pointed
  at mergedStateValues because that is where our per-view merge feeds this block;
  and wrapped our setValues() sanitization with main's withoutInvalidDisplaySettings
  so an invalid display value is dropped before the shared write and before the
  view-local write, instead of only before the shared write.
- src/core/webview/webviewMessageHandler.ts: kept main's isInvalidDisplayValue
  guard and our viewStates guard in the updateSettings loop, both with their own
  continue, and kept main's whole failed-save/settingsSaveResult restructuring.

Fidelity: every line either side added since the merge base is present in the
result except 6, all of them intentional rewrites named above (1 ours, 5 main).
No file present on either side is absent from the result: 0 of main's 39 new files
missing, 0 of ours' 1 new file missing, 0 files main deleted since the base.
No conflict markers remain, and the recursive stage-1 blobs matched the real
merge-base blobs byte for byte with no committed markers in them.
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.

Add Keenable to the MCP Marketplace

2 participants