Skip to main content
Glama

narrow-mcp

An MCP server that narrows large, low-density non-source files (logs, test output, CSV, JSON, HTML) down to the verbatim spans relevant to a stated intent -- verified against the original file, never a summary.

Why

Coding agents burn context reading large low-density files. A 40k-token log might hold a few hundred tokens of signal. This tool:

  1. Runs deterministic narrowing first (grep-style search, structural parsing per file type, sampling) -- free, fast, zero LLM cost.

  2. If that alone resolves the query with confidence (e.g. an exact CSV "null column" query), returns it directly. No LLM call at all.

  3. Otherwise passes only the narrowed candidates (never the raw file) to a cheap, fast selector model that returns line ranges and a one-line reason -- never prose.

  4. Re-reads the chosen line ranges from the original file on disk and returns that verbatim text. The selector's own words are never trusted or returned -- only its line-number coordinates, which get verified.

  5. If the selector fails, times out, or returns something invalid, falls back to the deterministic candidate set rather than failing outright.

Non-goals: source code retrieval (use LSP/tree-sitter/ast-grep), prose summarization, local/self-hosted models.

Related MCP server: Code Scalpel

Quick start

  1. Install:

    pip install narrow-mcp

    or run it without installing anything, always on the latest version:

    uvx narrow-mcp
  2. Set one API key. The provider is auto-detected from whichever you set — see Configuration for the full picker, including a completely free option via OpenRouter:

    export ANTHROPIC_API_KEY=sk-ant-...
  3. Register it with Claude Code:

    claude mcp add narrow-mcp -- uvx narrow-mcp

    (Verify current claude mcp add flag syntax with claude mcp add --help first — CLI flags change across releases.)

  4. That's it. You don't call the tool directly — once registered, your coding agent sees one tool, narrow_file(path, intent), and decides on its own when a large file is worth narrowing instead of reading in full. For example, given a CSV and the intent "which rows have null customer_id", the agent gets back exactly the matching rows, verified against the file on disk, along with how much that saved:

    {
      "status": "deterministic",
      "file_type": "csv",
      "spans": [
        {"start_line": 4, "end_line": 4, "text": "3,Carol White,,carol@example.com", "reason": "structured_null", "source": "deterministic"},
        {"start_line": 6, "end_line": 6, "text": "5,Eve Black,,eve@example.com", "reason": "structured_null", "source": "deterministic"},
        {"start_line": 9, "end_line": 9, "text": "8,Heidi Young,,heidi@example.com", "reason": "structured_null", "source": "deterministic"}
      ],
      "metrics": {"original_size_tokens_est": 94, "returned_size_tokens_est": 23, "savings_pct": 75.5, "latency_ms": 1}
    }

    status: "deterministic" means this resolved from the exact CSV query alone — no LLM call at all, the most common outcome for well-posed queries. status: "selected" means the cheap selector model chose the spans; status: "deterministic_fallback" means the selector was tried and failed, so the tool fell back to its deterministic candidates rather than returning nothing; status: "refused" means the path was a source file (use LSP/tree-sitter/ast-grep for those instead).

Status

v1, single file per call. Four file types: log/build-output, CSV, JSON (single document or JSONL), HTML.

Development

pip install -e ".[dev]"
pytest
python eval/run_eval.py          # mocked selector, free
python eval/run_eval.py --live   # real selector call, needs an API key (see Configuration)

Configuration

You only need to set one API key. The provider is auto-detected from whichever key is present -- no separate provider/model config required:

If you set...

Provider used

Default model

ANTHROPIC_API_KEY

anthropic

claude-haiku-4-5

OPENAI_API_KEY

openai

gpt-5-nano

OPENROUTER_API_KEY

openrouter

openrouter/free (see below)

(none)

anthropic

claude-haiku-4-5 (calls just always fall back to the deterministic path)

If more than one key is set, priority is Anthropic > OpenAI > OpenRouter. Override anything explicitly with the env vars below.

Using OpenRouter's free models

OpenRouter still requires its own API key even for $0-cost models -- set OPENROUTER_API_KEY and you're done, no other config needed. It defaults to openrouter/free, a meta-router that auto-picks among whichever tool-calling-capable models are currently free, so it never goes stale the way hardcoding one specific :free model name would.

To see the current free-model roster live (it rotates) and pick a specific one instead of the meta-router:

narrow-mcp-list-free-models

Then set NARROW_MCP_SELECTOR_MODEL=<id> to whichever one you want.

OpenRouter's free tier is rate-limited (20 req/min; 50 req/day, or 1000/day once the account has $10+ lifetime spend) -- fine for interactive use, worth knowing about for batch runs.

All environment variables

  • NARROW_MCP_SELECTOR_PROVIDER -- anthropic | openai | openrouter. Overrides auto-detection.

  • NARROW_MCP_SELECTOR_MODEL -- overrides the provider's default model.

  • NARROW_MCP_SELECTOR_API_KEY_ENV -- overrides which env var holds the key.

  • NARROW_MCP_SELECTOR_TIMEOUT_S (default 3.0)

  • NARROW_MCP_MAX_CANDIDATE_CHARS, NARROW_MCP_MAX_CANDIDATES, NARROW_MCP_CONTEXT_LINES, NARROW_MCP_RIPGREP_PATH, NARROW_MCP_MAX_JSON_BYTES

Available Tools

1 tool
narrow_fileA

Given a path to a large, low-density non-source file (logs, build output, CSV, JSON, HTML) and a specific intent, returns only the verbatim line-numbered spans relevant to that intent, verified against the original file -- never a summary. Refuses source code files; use code-navigation tools for those.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathYes
intentYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
noteNo
spansYes
statusYes
metricsNo
file_typeYes
truncated_countNo

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full behavioral burden and does so well. It reveals that output is verbatim, line-numbered spans, that summaries are never produced, that results are verified against the original file, and that source code files are refused.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tightly written sentences with no wasted words. The core input-output behavior is front-loaded, followed by the refusal rule and alternative, making the description easy to parse quickly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description is complete for a simple 2-parameter tool: it states inputs, output behavior, source-file exclusion, and the alternative tool category. The presence of an output schema covers return structure, so no further return-value explanation is required.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It enriches both parameters: 'path' means a path to a large, low-density non-source file of specific types, and 'intent' means a specific goal that selects relevant spans. It could add more detail about path formats or intent phrasing, but the semantics are sufficiently conveyed for a simple 2-parameter tool.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Descriptions state a specific verb-driven operation: given a file path and intent, return only relevant verbatim line-numbered spans, never a summary. It clearly defines the resource type (large, low-density non-source files) and the output form, making it easy to distinguish from other tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says when to use the tool: for large, low-density non-source files such as logs, build output, CSV, JSON, and HTML. It also says when not to use it—source code files—and directs the agent to code-navigation tools instead, providing a clear alternative.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. 1 tool updatev0.1.0
    • First observednarrow_file

TDQS

A4.7/5.0
Disambiguation5/5

With only one tool, there is no possibility of an agent selecting the wrong operation from this server. The tool's description also clearly delineates supported file types and explicitly excludes source files.

Naming Consistency4/5

The single name 'narrow_file' follows a clear verb_noun structure and is easy to predict. However, with only one tool there is no larger naming pattern to assess for consistency.

Tool Count3/5

A single tool is at the low end of what feels like a complete server, even though the server is intentionally narrow. The count is not a severe mismatch, but agents have no fallback or related operations available.

Completeness5/5

For the server's stated narrow purpose, the tool covers the entire workflow: it accepts a qualifying file and intent, returns verified verbatim relevant spans, and handles boundary cases by refusing source files. No obvious missing operation remains within this deliberately small scope.

Maintenance

ActivityNo data
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • F
    license
    D
    quality
    D
    maintenance
    Enables AI agents to perform semantic search over codebases by converting natural language queries into efficient search patterns like grep and ripgrep. It utilizes LLMs to verify relevance and find code snippets that traditional keyword-based searches might miss.
    1
    -
  • A
    license
    A
    quality
    B
    maintenance
    Token-efficient skim-then-expand I/O for agentic models, enabling lossless reading of large files via skeletons and exact expansion with anchor IDs.
    6
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Provides persistent memory for coding agents and grounds their claims by verifying against the actual codebase, preventing hallucinated responses.
    506
    Apache 2.0

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/manik-prakash/narrow-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server