npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@keenable/mcp-server

v0.1.7

Published

MCP server for Keenable AI search, fetch, and feedback APIs

Readme

Keenable MCP Server

Server URL: https://api.keenable.ai/mcp

Authentication: API key via the X-API-Key header.

Create an API key in the console.

Remote MCP (recommended)

Claude Code:

claude mcp add keenable \
  --transport http https://api.keenable.ai/mcp \
  --scope user \
  --header "X-API-Key: <YOUR_API_KEY>"

Other MCP clients (Claude Desktop, Cursor, Windsurf, etc.):

{
  "mcpServers": {
    "keenable": {
      "url": "https://api.keenable.ai/mcp",
      "headers": {
        "X-API-Key": "<YOUR_API_KEY>"
      }
    }
  }
}

Note: After adding, disable any built-in or third-party search/fetch tools (WebSearch, WebFetch, brave_search, tavily_search, etc.). Keenable tools replace them — leaving both active causes agents to pick inconsistently.


Available Tools

search_web_pages

Search the web and return ranked results with URLs, titles, and descriptions.

Input

| Field | Type | Required | Description | |---|---|---|---| | query | string | yes | The search query | | site | string | no | Restrict results to a specific site (e.g. "techcrunch.com") | | acquired_after | string | no | Filter to pages acquired/indexed after this date (YYYY-MM-DD) | | acquired_before | string | no | Filter to pages acquired/indexed before this date (YYYY-MM-DD) | | published_after | string | no | Filter to pages published after this date (YYYY-MM-DD) | | published_before | string | no | Filter to pages published before this date (YYYY-MM-DD) |

Output

| Field | Type | Description | |---|---|---| | results | array | List of search results | | results[].title | string | Page title | | results[].url | string | Page URL | | results[].description | string | Snippet / summary of the page | | results[].published_at | string | When the page was published (ISO 8601, if available) | | results[].acquired_at | string | When the page was acquired/indexed (ISO 8601, if available) |

Output example

{
  "results": [
    {
      "title": "TypeScript Best Practices 2026",
      "url": "https://example.com/ts-best-practices",
      "description": "A comprehensive guide to modern TypeScript patterns and best practices.",
      "published_at": "2026-01-15T10:30:00Z",
      "acquired_at": "2026-01-16T08:12:34Z"
    }
  ]
}

fetch_page_content

Fetch one or more URLs and extract content as clean markdown. Only URLs from the index are supported; this is not a general web scraper.

Input

| Field | Type | Required | Description | |---|---|---|---| | urls | string[] | yes | URLs to fetch (min 1) |

Output

One text block per URL, each containing:

| Field | Type | Description | |---|---|---| | url | string | The fetched URL | | title | string | Page title (if available) | | content | string | Extracted page content in markdown |

Output example

{
  "url": "https://example.com/ts-best-practices",
  "title": "TypeScript Best Practices 2026",
  "content": "# TypeScript Best Practices 2026\n\nUse strict mode, prefer interfaces over type aliases for object shapes..."
}

submit_search_feedback

Submit per-URL relevance scores and comments after a search to improve result quality over time.

Input

| Field | Type | Required | Description | |---|---|---|---| | query | string | yes | The original search query | | relevance | array | yes | Per-URL relevance entries | | relevance[].url | string | yes | The result URL being scored | | relevance[].score | number | yes | Relevance score (0–5) | | relevance[].comment | string | yes | Explanation of why this score was given |

Score scale: 0 = content not loaded, 1 = not relevant at all, 2 = slightly relevant, 3 = moderately relevant, 4 = very relevant, 5 = perfectly relevant.

Input example

{
  "query": "TypeScript best practices",
  "relevance": [
    {
      "url": "https://example.com/ts-best-practices",
      "score": 5,
      "comment": "Comprehensive guide covering exactly what was asked"
    },
    {
      "url": "https://example.com/js-patterns",
      "score": 2,
      "comment": "Covers JavaScript patterns but not TypeScript-specific"
    }
  ]
}

Output

| Field | Type | Description | |---|---|---| | message | string | Confirmation message |


Additional setups

Stdio MCP

For agents that don't support remote MCP connections, the server is available as an npm package that runs locally over stdio.

{
  "mcpServers": {
    "keenable": {
      "command": "npx",
      "args": ["-y", "@keenable/mcp-server"],
      "env": {
        "KEENABLE_API_KEY": "<YOUR_API_KEY>"
      }
    }
  }
}

OAuth

The remote MCP server at https://api.keenable.ai/mcp supports the MCP OAuth authorization flow, so clients can authenticate without manually passing an API key. In practice, most MCP clients have unstable OAuth implementations, so we don't currently recommend this path. Use an API key instead.

Using as an NPM package

Install the package and import the tools in your own application:

npm install @keenable/mcp-server
import { tools, toolHandlers } from '@keenable/mcp-server';

// Option 1: Use environment variable (stdio MCP servers)
process.env.KEENABLE_API_KEY = 'your-api-key';
const result1 = await toolHandlers['search_web_pages']({ query: 'TypeScript' });

// Option 2: Pass API key explicitly (HTTP servers, per-request auth)
const result2 = await toolHandlers['search_web_pages'](
  { query: 'TypeScript' },
  'your-api-key'
);

Exported items:

  • tools - Array of MCP tool definitions
  • toolHandlers - Object mapping tool names to handler functions
  • ToolDefinition - TypeScript type for tool definitions
  • ToolHandler - TypeScript type: (args: any, apiKey?: string) => Promise<CallToolResult>

Development

git clone https://github.com/keenableai/keenable-mcp-ts.git
cd keenable-mcp-ts
npm install
npm run build

License

MIT