cd /news/ai-agents/a-map-not-a-megadump-sentinel-ir-mcp… · home › topics › ai-agents › article
[ARTICLE · art-154949] src=dev.to ↗ pub= topic=ai-agents verified=true sentiment=↑ positive

A Map, Not a Megadump: Sentinel-IR-MCP 0.2.0 Adds TypeScript, 0.2.1 Makes Missing Analysis Visible

The Sentinel-IR project released version 0.2.0 of Sentinel-IR-MCP, adding TypeScript and TSX support to its Model Context Protocol server that gives AI coding agents a compact structural summary of a codebase instead of raw source. Version 0.2.1 added "incomplete", "statusCounts" and "skipped.unreadable" fields to the directory summary so parse-incomplete or unreadable files are surfaced rather than hidden, following the principle that "a missing result must look missing, not safe." The tool is a read-only analysis aid, not a full security scanner.

by read17 min views2 publishedOct 22, 2026

When an AI agent opens a codebase, should it read every file first, or should it get a compact map of what those files contain and inspect the important ones on demand?

That is the idea behind Sentinel-IR and Sentinel-IR-MCP. Version 0.2.0 brought TypeScript and TSX into the MCP workflow. Version 0.2.1 made a different, less flashy but equally important improvement: it made incomplete and skipped files visible in the directory summary, rather than letting a low-risk-looking entry hide uncertainty or one unreadable file ruin the whole result.

This article is deliberately split into three reading depths. Start with the 30-second version, take the friendly tour, or jump to the engineering details.

An AI coding agent can spend a lot of context reading source files just to work out where the important things are. Sentinel-IR creates a compact structural summary instead: imports, exports, routes, environment reads, filesystem/network/process activity, selected risk signals, and an explicit analysis status.

Sentinel-IR-MCP exposes that summary to compatible AI clients through the Model Context Protocol (MCP), using three tools:

Version 0.2.0: added TypeScript and TSX support alongside JavaScript. The language is selected from the file extension, with an explicit language option available for "analyze_code".

Version 0.2.1: added "incomplete", "statusCounts", and "skipped.unreadable" to the directory summary. A parse-incomplete file is listed separately, and one file that cannot be read or handled must not hide the results for the rest of the directory.

The principle: a missing result must look missing, not safe.

This is a read-only structural analysis aid, not a complete security scanner and not a guarantee that the code is safe.

The problem: giving an agent a whole library instead of a map

Imagine asking a new teammate to review a project with hundreds of files. You hand them the whole repository and say, “Find the important parts.” They have to discover the layout, hunt for routes and imports, locate the places that touch the filesystem, and work out where commands or network requests might happen.

An AI agent faces a similar problem. Reading more source can consume more context and time, and the most relevant file may be buried among many ordinary files.

Sentinel-IR takes a different first step. It parses supported source files and extracts compact structural facts. The result is closer to a map or an index than a copy of the original file. The agent can use that map to decide which raw files deserve closer inspection.

The map is not the territory. It helps navigation; it does not replace the source code when a detailed review is needed.

What is Sentinel-IR?

Sentinel-IR is the analysis library. It looks at JavaScript or TypeScript structure and produces a compact Intermediate Representation, usually shortened to IR.

In plain English, the IR can tell an agent things such as:

The point is not to retell every line of code in natural language. It is to provide a smaller, structured set of facts that a tool or agent can inspect consistently.

What does MCP add?

MCP, the Model Context Protocol, is a standard way for an AI application to communicate with tools and other context providers.

Think of Sentinel-IR as the workshop tool and MCP as the standard socket that lets a compatible AI client use it. Instead of creating a special integration for every client, the server exposes named tools with defined inputs and outputs. Clients such as Claude Desktop, Cursor, Windsurf, and other compatible MCP clients can call those tools when configured to do so.

MCP does not make the analysis smarter by itself. It makes the capability accessible through a consistent interface.

What changed in 0.2.0?

Before 0.2.0, this MCP workflow was focused on JavaScript. Version 0.2.0 added TypeScript and TSX support while preserving the existing JavaScript path.

The supported extensions are:

Language| Extensions

JavaScript| ".js", ".mjs", ".cjs"

TypeScript| ".ts", ".mts", ".cts", ".tsx"

For file-based tools, the extension selects the language. For "analyze_code", a "target" filename can provide the extension; an explicit "language" can override the default when necessary. This matters because TypeScript is not just JavaScript with decorative annotations. Types, type assertions, TS-specific declarations, and TSX syntax affect how a parser should interpret a source file. Language-aware parsing lets the analysis work with the source structure instead of treating TypeScript as if it were always plain JavaScript.

The implementation keeps JavaScript on its existing analysis path rather than forcing all languages through one parser configuration. That is a compatibility decision: supporting another language should not silently rewrite established JavaScript results.

What changed in 0.2.1?

Version 0.2.1 focuses on making the directory summary more honest and resilient.

There are three useful categories to understand:

Complete analysis means the analyzer finished parsing the file according to its current rules. It does not mean the program is proven safe.

Incomplete analysis means the file produced a result, but parsing did not finish cleanly. The file remains in "files", and its status is "incomplete". Because the parser could not fully understand the file, its risk result must not be treated as a safety verdict.

Skipped/unreadable means the file did not produce a normal analyzed entry because the per-file read or analysis operation raised an error. In 0.2.1, it is surfaced in "skipped.unreadable" instead of allowing that file to abort the entire directory operation. The current implementation uses that category for exceptions across the file-read/analysis boundary, so it is an outcome category rather than a detailed taxonomy of every underlying cause.

The new fields are:

The original "files" shape and risk-based ordering remain unchanged. The IR library itself is not changed by this MCP release.

Why is this important?

Suppose a directory contains:

A useful report should still tell you about "run.ts" and "ok.ts". It should also clearly say that "broken.ts" is incomplete and "locked.js" did not produce an analyzed result. It should not turn either missing understanding into a quiet “looks safe.”

That is the practical difference between a list of findings and a report that exposes its blind spots.

This section is for people integrating the server or evaluating its behavior in a real workflow.

3.1 The integration surface

The server currently exposes three tools, keeping the surface small and explicit:

Tool| Input| Purpose

"analyze_code"| Source text; optional "target" and "language"| Analyze source without first reading a project file through the tool.

"analyze_file"| A path inside an allowed root| Read and analyze one supported file.

"analyze_directory"| Optional directory path, "max_files", and "recursive"| Analyze supported source files and return risk-sorted summaries plus counts and skipped/incomplete lists.

Results are returned as JSON text and as MCP "structuredContent". Tool annotations declare the tools read-only, non-destructive, idempotent, and not open-world. Those annotations describe intended tool behavior; they are not a substitute for inspecting the implementation or configuring the correct allowed roots.

3.2 A copy-ready MCP configuration

The server requires Node.js 20 or newer and can be started with "npx". Give it the absolute path of the project that the agent is permitted to inspect. Replace the example path with your own project path.

"claude_desktop_config.json" entry

The following is a valid JSON configuration object for the relevant part of the Claude Desktop config. Merge the "mcpServers" entry into the existing configuration rather than deleting other servers.

{

  "mcpServers": {

    "sentinel-ir": {

      "command": "npx",

      "args": [

        "-y",

        "[sentinel-ir-mcp@0.2.1](mailto:sentinel-ir-mcp@0.2.1)",

        "/absolute/path/to/your/project"

      ]

    }

  }

}

Cursor project config: ".cursor/mcp.json"

{

  "mcpServers": {

    "sentinel-ir": {

      "command": "npx",

      "args": [

        "-y",

        "[sentinel-ir-mcp@0.2.1](mailto:sentinel-ir-mcp@0.2.1)",

        "${workspaceFolder}"

      ]

    }

  }

}

These examples pin the version to "0.2.1" so the configuration does not silently switch to a future release. If you prefer to follow the latest npm version, remove "@0.2.1" from the package name. After changing the client configuration, restart or reload the client as required by that application.

3.3 A copy-ready "analyze_code" tool input

When an MCP client calls "analyze_code", the tool arguments are JSON. This example uses a TypeScript filename so the tool can select the TypeScript language from the extension. The "language" override is included to make the intent explicit.

{

  "target": "src/danger.ts",

  "language": "typescript",

  "code": "import { exec } from \"node:child_process\";\n\nexec(\"echo hello\");\n"

}

This is the tool input, not a standalone JavaScript file. JSON requires quotes and newlines inside a string to be escaped. That is why this form can be pasted into a tool inspector or used as a fixture without guessing where a quote or line break belongs.

3.4 Understanding the 0.2.1 directory summary

"analyze_directory" continues returning its original "files" array in risk order, and adds explicit status information beside the existing risk counts. Here is a reduced, illustrative shape for the relevant fields. The file objects below are intentionally abbreviated to make the summary easier to read; actual entries include more fields, including "forbidden" and structural "facts".

{

  "analyzed": 3,

  "truncated": false,

  "riskCounts": {

    "critical": 1,

    "high": 0,

    "medium": 0,

    "low": 2

  },

  "statusCounts": {

    "complete": 2,

    "incomplete": 1

  },

  "incomplete": [

    "src/broken.ts"

  ],

  "skipped": {

    "tooLarge": [],

    "symlinks": 0,

    "unreadable": [

      "src/locked.js"

    ]

  },

  "files": [

    {

      "path": "src/run.ts",

      "analysisStatus": "complete",

      "language": "typescript",

      "risk": "critical"

    },

    {

      "path": "src/broken.ts",

      "analysisStatus": "incomplete",

      "language": "typescript",

      "risk": "low"

    },

    {

      "path": "src/ok.ts",

      "analysisStatus": "complete",

      "language": "typescript",

      "risk": "low"

    }

  ]

}

The key invariants are more important than any particular example:

In the illustrated example, three files were analyzed and one additional file could not produce an analyzed result. Therefore "analyzed" is 3, not 4. The unreadable file appears in the skipped section and is not counted in the status or risk totals.

One detail about the file limit: a source-file candidate that cannot be read still occupies a slot in "max_files". The limit is applied during collection, before each file's analysis outcome is known. With a small limit, that means a skipped file can consume a slot even though it will not appear in "analyzed".

3.5 Why keep "files" unchanged?

Adding a useful field can still break consumers if it changes the shape, meaning, or order of existing fields. In 0.2.1, "files" keeps its current shape and its risk-first ordering. The new "incomplete" list is a second view designed for a different question: “Which paths need special attention because the analysis did not finish?”

The two lists are intentionally not sorted the same way:

This avoids changing the established array ordering while making incomplete files easy to find. It is a small example of additive API evolution: add explicit metadata without silently redefining the existing field.

3.6 Failure isolation and the meaning of "skipped.unreadable"

Before the 0.2.1 fix, an individual file read error could fail the entire directory analysis. The new per-file error boundary lets the loop continue. The server records the affected path under "skipped.unreadable" and continues processing other collected files.

The current implementation catches errors around both reading the file and invoking its analysis. Consequently, a thrown per-file analyzer error is also recorded under "skipped.unreadable". That preserves the “one file must not hide all the others” behavior, but the field name should be understood as the current skipped outcome category, not a promise that every entry failed only because of filesystem permissions. A future schema could separate "readErrors" and "analysisErrors" if consumers need precise root-cause diagnostics; that would be a separate, intentional schema change.

A few other states remain distinct:

A consumer should inspect all applicable status and skipped fields before drawing conclusions from the result.

3.7 Boundaries and safety properties

The MCP server is intended to be read-only. It reads supported source files inside explicitly allowed folders. It does not write project files, execute the analyzed source, run shell commands, or open network connections as part of analysis.

The traversal also has practical limits:

There is an important prompt-injection nuance. The IR avoids copying full comments, function bodies, or string bodies into the model context, which can reduce exposure to instructions embedded in source text. But the IR is still derived from untrusted repository content. It contains identifiers and selected literals such as route paths, module names, export names, and environment-variable names. Treat it as data, not as trusted instructions. Compactness reduces the amount of source copied; it does not eliminate prompt injection.

And this is not a full security scanner. The risk classification comes from a fixed set of structural patterns. Dynamic behavior that constructs module names at runtime or hides a call in a way the current rules do not recognize can be missed. “No risky pattern found” is not equivalent to “the program is safe.”

3.8 Evidence, tests, and the token question

The 0.2.1 changes include tests for summary consistency and failure cases. The release work reported 29/29 local tests on Node 20, 22, and 24. CI reported 28 passing tests and one skipped test. The skipped case uses a real "chmod 000" file; CI runs as root, which can still read that file, so the real permission test is not meaningful there. Read failures are also covered with a simulated error that works in CI.

The test cases exercise:

The released package was also tested through the official MCP client, according to the release report. The reported mixed directory contained a dangerous file, incomplete files, a normal file, and an unreadable file. The expected behavior was that the dangerous file remained first in risk order, incomplete paths appeared separately, unreadable files were excluded from analyzed counts, and the original "files" shape stayed intact.

What about token savings? It is a motivation, but we should not turn motivation into a universal benchmark. The project README records one concrete measurement using the source of "sentinel-ir@0.1.3", an MCP stdio run, and the "o200k_base" tokenizer:

Four files from the library| Tokens

Raw source combined| 11,564

IR combined| 317

Reduction in this sample| about 97.3%

That sample demonstrates how compact the output can be for those files. It is not a promise that every project, every file size, or every tokenizer will see the same reduction. There is also a per-file overhead: the README notes an IR floor of roughly 120 tokens per file, so very small files may not benefit from being summarized individually.

The next useful experiment is therefore not another headline. It is a reproducible comparison on representative projects: task success, relevant-file recall, total tokens, latency, and how often incomplete analysis changes the agent's next action.

3.9 What 0.2.1 does not change

A release is easier to evaluate when the boundaries are explicit.

Version 0.2.0 expanded the language coverage. Version 0.2.1 improved how uncertainty and per-file failure are surfaced through the MCP directory summary. Those are complementary changes: broader input coverage helps the tool understand more source; explicit status reporting helps the agent know when the tool has not understood enough.

3.10 A practical review sequence for an AI agent

The tool is most useful when the agent treats the result as a workflow, not as a magic verdict. A defensible sequence looks like this:

This sequence can be embedded into the instructions of an orchestration agent. It is not hard-coded autonomous remediation: the server reports facts, and the client decides what to do with them. For example, it does not repair files, run tests, or modify the project.

A machine-readable review policy is included in the companion JSON examples. It is a suggested policy document, not a configuration automatically consumed by Sentinel-IR-MCP.

3.11 What should a consumer consider a complete inventory?

A response can be internally consistent and still be an incomplete view of the repository. These are separate properties:

For example, "statusCounts.complete + statusCounts.incomplete === analyzed" can be true even while "truncated" is also true. The counts may be perfectly correct for the subset processed, but the entire directory was not scanned. Likewise, every analyzed file can have "analysisStatus: "complete"" while the rule set still misses an obfuscated or dynamically constructed operation. This is why the consumer should not compress all uncertainty into one boolean called "safe". A robust report keeps these dimensions separate. Version 0.2.1 directly improves one of them: it exposes incomplete and skipped outcomes instead of hiding them inside a risk-sorted list or aborting the entire operation.

3.12 Compatibility questions for integrations

For an MCP client or framework author, there are a few practical integration rules: The IR schema and MCP response are related, but they are not the same thing. The IR comes from "sentinel-ir"; "sentinel-ir-mcp" packages it into tool calls, applies path and size rules, and adds directory-level results. This release changes the MCP directory summary, not the core IR schema.

3.13 Reproducing the evidence rather than repeating the headline

A release note can say that tests pass. A useful engineering report tells the next person which conditions were actually tested and which conditions were simulated.

For the 0.2.1 summary change, the most meaningful checks are not just “the command returned without throwing.” They are assertions about the semantics of the result: Scenario| Expected interpretation

Valid, parseable source| One "files" entry with "analysisStatus: "complete"".

Broken JS/TS/TSX syntax| A file entry with "analysisStatus: "incomplete"", and one path in "incomplete".

Two broken files with the same basename in different directories| Two distinct paths in "incomplete", each present once.

Read error for one file| That file is recorded under "skipped.unreadable"; other files still produce results.

Per-file analysis throws| The per-file failure is isolated; under the current implementation it is also recorded in "skipped.unreadable".

More eligible files than "max_files"| "truncated" communicates that the directory inventory is partial.

Unreadable candidate within the limit| It consumes a slot but is not included in "analyzed".

Same directory analyzed repeatedly| The status list remains deterministically path-sorted; risk-first "files" order remains stable for the same inputs.

For a clean verification run, use fixtures whose expected behavior is known before running the analyzer. Keep malformed syntax cases separate from genuinely dangerous patterns, so a test does not accidentally treat a parser failure as a successful risk detection. Then exercise the packed npm tarball through an actual MCP client, because importing local source is not a substitute for testing the artifact users install. There is also a useful environment distinction in the release report: a local permission test using "chmod 000" may behave differently from the same test in CI if CI runs as root. The test was therefore skipped in that CI environment, while a simulated read error exercised the error-handling path. Reporting that distinction is better than claiming the permission test proved something in an environment where the permission did not prevent access.

A companion checklist JSON records the primary invariants so they can be copied into an issue, release checklist, or future test plan. It is a checklist, not an executable test suite by itself.

3.14 Benchmark the workflow, not just the compressed output

A small IR is promising, but token reduction alone cannot tell us whether the agent found the right file or completed the task correctly. A serious evaluation should compare at least two workflows on the same task set:

Keep model, task, repository snapshot, context limit, and success criteria as consistent as possible. Measure:

Run tasks over several repository sizes and include small files. The IR has per-file overhead, so a workflow that works well on a large repository may not save tokens on a tiny one. Repeat the experiment and report the range or distribution, not just the best run.

The question to answer is not “Is the IR smaller?” The README already gives a concrete small example of that. The more important question is: Does the IR-first workflow help an agent complete real tasks with less wasted context, without causing it to overlook the files or uncertainty that matter? That remains a measurement question, not a claim made by the release.

3.15 Current scope and the next engineering questions

As of 0.2.1, the supported languages are JavaScript, TypeScript, and TSX. Python is not supported by this release. Adding Python will require a deliberate choice about parser architecture, language-specific risk rules, handling incomplete syntax, packaging, and distribution. It should not be described as supported merely because the MCP interface can accept text.

The same rule applies to any future language: adding an extension is not the whole feature. A language should have tests for ordinary code, dangerous patterns, aliases, malformed input, and type- or language-specific syntax. The output contract should remain stable where possible, and uncertainty should remain explicit.

For maintainers, the useful next gates are therefore: These are not promises about what the next release will contain. They are the checks that make a future expansion credible.

Final thought An AI coding agent does not always need a bigger context window. Sometimes it needs a better index, an honest status field, and a clear signal when part of the map is missing.

Sentinel-IR-MCP 0.2.0 gives the workflow TypeScript and TSX support. Sentinel-IR-MCP 0.2.1 makes incomplete and skipped analysis harder to overlook.

The guiding rule is simple: give the agent a compact map first, let it inspect the relevant source when needed, and never let missing information masquerade as a clean bill of health.

── more in #ai-agents 4 stories · sorted by recency
── more on @sentinel-ir 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/a-map-not-a-megadump…] indexed:0 read:17min 2026-10-22 · —