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

elasticdash-mcp

v0.0.9

Published

ElasticDash MCP server — search, inspect, and rerun AI agent traces from ElasticDash

Downloads

173

Readme

ElasticDash Trace Search MCP

An MCP server that lets your coding agent (Claude Code) search and investigate recorded traces from your AI agent's runtime behavior. When a user reports an issue ("the agent returned full stats instead of just attack"), the MCP searches your traces, identifies relevant ones by keyword matching, and lets the agent drill into the root cause.

Prerequisites

  • Node.js 20+
  • An ElasticDash project with traces being recorded (via elasticdash-test SDK)
  • An Anthropic API key (used internally for symptom parsing and trace ranking)

Installation

1. Clone this repo

git clone <this-repo-url> ElasticDash-MCP
cd ElasticDash-MCP
npm install

2. Configure environment

cp .env.example .env

Edit .env with your values:

# Required: ElasticDash backend URL and API key.
# ELASTICDASH_SERVER_URL is accepted as an alias for ELASTICDASH_API_URL
# (the Python SDK uses SERVER_URL; the TypeScript SDK uses API_URL).
ELASTICDASH_API_URL=https://devserver.elasticdash.com
ELASTICDASH_API_KEY=ed_your_api_key_here

# Optional: explicit project ID (if not set, resolved from API key scope)
# ED_PROJECT_ID=2

# Optional: Anthropic API key — only needed for rerun_step on Claude-based trace steps
# ANTHROPIC_API_KEY=sk-ant-your-key-here

3. Set up the ed_tools / ed_workflows files in your agent project

The MCP instructs the coding agent to read tool/workflow definitions from your project root before searching. Your project must have:

ed_tools.ts / ed_tools.js / ed_tools.py (pick the extension matching your project's language) — Lists all tools your agent uses. The coding agent reads this to know valid tool names.

TypeScript / JavaScript example:

export const fetchPokemonDetails = wrapTool('fetchPokemonDetails', async (input: any) => {
    // ...
});

/**
 * Generate the final answer from accumulated results.
 */
export const generateFinalAnswer = wrapTool('generateFinalAnswer', async (input: any) => {
    // ...
});

Python example (re-exports @ed_tool-decorated functions so the SDK can discover them):

from my_agent.tools import (  # noqa: F401
    fetch_pokemon_details,
    generate_final_answer,
)

ed_workflows.ts / ed_workflows.js / ed_workflows.py — The coding agent reads this to find workflow names (looks for edStartTrace('name') / start_trace('name') calls).

4. Register the MCP server in Claude Code

Add to your project's .mcp.json (in your agent project root):

{
  "mcpServers": {
    "elasticdash-mcp": {
      "command": "/absolute/path/to/node",
      "args": ["--import", "tsx", "/absolute/path/to/ElasticDash-MCP/mcp-server/server.ts"],
      "cwd": "/absolute/path/to/ElasticDash-MCP"
    }
  }
}

Important: Use absolute paths for both the node binary and the server script. To find your node path, run which node in your terminal.

Example with real paths:

{
  "mcpServers": {
    "elasticdash-mcp": {
      "command": "/Users/you/.nvm/versions/node/v20.20.0/bin/node",
      "args": ["--import", "tsx", "/Users/you/projects/ElasticDash-MCP/mcp-server/server.ts"],
      "cwd": "/Users/you/projects/ElasticDash-MCP"
    }
  }
}

Why absolute paths? Using npx tsx or relative paths often causes "Failed to connect" errors because Claude Code may not resolve PATH or cwd the same way your shell does. Absolute paths ensure reliable startup.

Environment variables: two paths

The MCP needs ELASTICDASH_API_URL (or ELASTICDASH_SERVER_URL) and ELASTICDASH_API_KEY at runtime. You have two ways to provide them:

Recommended — explicit env block in .mcp.json (most reliable):

{
  "mcpServers": {
    "elasticdash-mcp": {
      "command": "/absolute/path/to/node",
      "args": ["--import", "tsx", "/absolute/path/to/ElasticDash-MCP/mcp-server/server.ts"],
      "env": {
        "ELASTICDASH_API_URL": "https://devserver.elasticdash.com",
        "ELASTICDASH_API_KEY": "ed_your_api_key_here"
      }
    }
  }
}

Alternative — .env file picked up by dotenv. The MCP server calls import 'dotenv/config', which reads .env from whatever directory the process is launched in. Claude Code typically launches MCP subprocesses in the agent project's directory (the cwd field in .mcp.json is not always honored), so dotenv will load your agent project's .env, not the one in this repo. That is fine as long as your agent project's .env defines the variables — and it accepts either ELASTICDASH_API_URL or ELASTICDASH_SERVER_URL for the URL.

5. Restart Claude Code

After adding the MCP config, restart Claude Code (or reload the MCP connection) to pick up the new server.

Usage

Once installed, describe any runtime issue with your agent in natural language:

The user only asks for the attack stats of Pikachu, but the agent returns
the full stats instead of just attack. This happened within 3 days.

The coding agent will automatically:

  1. Read ed_tools.{ts,js,py} to learn your tool names
  2. Call search_traces with keyword: "pikachu", time_range: "3 days ago", tool_names: ["fetchPokemonDetails"]
  3. Review input_preview/output_preview in results to find the right trace
  4. Call get_trace_details and rerun_step to investigate root cause

What triggers the MCP

The MCP activates when you describe runtime agent behavior:

  • "The user asked X but got Y"
  • "The agent returned wrong/too much/incomplete info"
  • "This happened yesterday / within 3 days / last week"
  • "A user reported...", "A customer complained..."

It does NOT activate for pure code questions like "refactor this function".

How It Works

User describes symptom
        |
        v
[Coding Agent] — reads ed_tools.{ts,js,py}, extracts keyword/time/tools from symptom
        |
        v
[search_traces] — deterministic backend search (keyword, time, tools)
        |            returns traces with input/output previews
        v
[get_trace_details] — agent picks relevant trace, fetches full events
        |
        v
[rerun_step] — agent re-executes suspicious LLM steps for comparison

No internal LLM calls — the coding agent (Claude Code) handles all reasoning.

Key features

  • Keyword search: Searches decrypted trace content (workflow input/output) for specific terms
  • Tool-aware: Reads your ed_tools.{ts,js,py} to know valid tool names — never guesses
  • Input/output previews: Returns trace previews so the agent can identify relevant traces without extra API calls
  • Auto-investigation: After finding traces, the agent automatically drills in with get_trace_details and rerun_step
  • Multi-provider rerun: Supports re-executing LLM steps across Claude, OpenAI, Kimi/Moonshot models

Project Structure

mcp-server/
  server.ts       # MCP entry point (stdio transport, 3 tools)
  pipeline.ts     # Direct search (keyword, time, tools → backend)
  state.ts        # TraceSummary type definition
logs/
  mcp_server.jsonl  # Server request/response logs

Environment Variables Reference

| Variable | Required | Description | | -------- | -------- | ----------- | | ELASTICDASH_API_URL | Yes (or ELASTICDASH_SERVER_URL) | ElasticDash backend URL. The TypeScript SDK uses ELASTICDASH_API_URL; the Python SDK uses ELASTICDASH_SERVER_URL. The MCP accepts either. | | ELASTICDASH_SERVER_URL | Alias for ELASTICDASH_API_URL | Same as above. Used only if ELASTICDASH_API_URL is unset. | | ELASTICDASH_API_KEY | Yes | API key for your ElasticDash project | | ED_PROJECT_ID | No | Explicit project ID (default: resolved from API key) | | ANTHROPIC_API_KEY | No | Only needed for rerun_step on Claude-based trace steps |

Troubleshooting

MCP not triggering: Make sure your prompt describes runtime agent behavior, not a code question. Include what the user asked and what the agent returned wrong.

No traces found: Check that:

  • ELASTICDASH_API_URL (or ELASTICDASH_SERVER_URL) and ELASTICDASH_API_KEY are correct
  • Your agent is recording traces via the elasticdash-test (TypeScript) or elasticdash-sdk (Python) SDK
  • The time range covers when the issue occurred

fetch failed errors with sub-100ms latency: The MCP fell back to http://localhost:3000/api because no backend URL was resolved. Either the env block in .mcp.json is missing, or dotenv loaded a .env that doesn't set ELASTICDASH_API_URL / ELASTICDASH_SERVER_URL. See the "Environment variables: two paths" section above.

Wrong tool names in search: Ensure ed_tools.{ts,js,py} exists in your project root. TypeScript projects use wrapTool('toolName', ...); Python projects re-export @ed_tool-decorated functions.

Logs: Check logs/mcp_server.jsonl for full request/response details including which filters were applied.