Dev.to · 20 min read

Sentinel-IR-MCP: Give Your AI Agent a Map, Not the Whole Codebase

Sentinel-IR-MCP: Give Your AI Agent a Map, Not the Whole Codebase

30 seconds for the scroll crowd. 10 minutes for curious humans. A hands-on guide for developers who want to connect the idea to a real AI client. The project: "GitLab source" (https://gitlab.com/jakubrojicek11/sentinel-ir-mcp) · "npm package" (https://www.npmjs.com/package/sentinel-ir-mcp) · "Sentinel-IR library" (https://gitlab.com/jakubrojicek11/sentinel-ir) Jump to your speed "⚡ The 30-second version" (#the-30-second-version) "🧠 The 10-minute guide for non-experts" (#the-10-minute-guide-for-non-experts) "🛠️ The 30-minute hands-on guide for developers" (#the-30-minute-hands-on-guide-for-developers) "🔬 Measurements, limitations and honest questions" (#measurements-limitations-and-honest-questions) You don't have to read the entire thing. That would rather defeat the point. 😉 The 30-second version AI coding agents can inspect repositories, explain functions, investigate bugs and modify code. But there is a small problem. Reading more code is not the same as understanding more code. Give an agent a large repository and it may spend its context window reading implementation details that have nothing to do with the current task. Now imagine giving it a map first. Instead of immediately sending the entire JavaScript source to the model, "Sentinel-IR" (https://www.npmjs.com/package/sentinel-ir) extracts compact structural facts: imports, exports, routes, filesystem and network operations, environment-variable access, process execution and risk signals. "Sentinel-IR-MCP" (https://www.npmjs.com/package/sentinel-ir-mcp) connects those facts to AI clients through the "Model Context Protocol (MCP)" (https://modelcontextprotocol.io/). The agent can inspect a folder, identify files worth investigating, and request a more detailed analysis of selected files. The basic idea: "JavaScript files → structural facts → AI agent → targeted investigation" The server is read-only. It does not modify files or execute the analyzed JavaScript. It restricts file access to configured directories and supports JavaScript files ending in ".js", ".mjs" and ".cjs". It is not a magic security scanner. It is a way to give an agent better evidence before asking it to reason. Three tools. One narrow job. Less unnecessary source code in the conversation. That is Sentinel-IR-MCP. The 10-minute guide for non-experts First, forget about AI for a moment Imagine you ask somebody to inspect a building before renovation. You need to know: Which walls are load-bearing? Where are the electrical cables? Where do the pipes go? Which parts should be inspected before anyone starts drilling? You don't necessarily need the inspector to memorize every brick, every paint mark and every screw. You need the important facts. Software has the same problem. A JavaScript repository may contain hundreds of files. Some handle user requests. Some read environment variables. Some write files. Others contact external services or execute operating-system commands. If an AI agent reads everything immediately, it receives both useful evidence and a lot of irrelevant detail. Sentinel-IR introduces a smaller first step: describe the structure of the code before asking the model to investigate everything. What is Sentinel-IR? "Sentinel-IR" (https://gitlab.com/jakubrojicek11/sentinel-ir) is the underlying library. Think of it as a technical inspector that looks for recognizable structures in JavaScript code. It can identify things such as: Imports and exports. Dynamic code execution patterns, including "eval". Certain process-execution and "child_process" patterns. Filesystem and network operations. Environment-variable access. Routes and other structural facts. It turns those observations into a compact representation called an intermediate representation, or IR. That name sounds more complicated than the idea. An IR is simply a structured description of what the analyzer detected. It is not the source code itself, and it is not an explanation of every line. A useful distinction: Source code: the actual instructions written by a developer. Structural facts: a compact description of recognizable properties of those instructions. AI reasoning: what the model concludes from the evidence it receives. Those are three different things. Keeping them separate makes the system easier to inspect. So what is Sentinel-IR-MCP? The library can analyze JavaScript, but an AI client needs a way to call it. That is where "Sentinel-IR-MCP" (https://gitlab.com/jakubrojicek11/sentinel-ir-mcp) comes in. MCP stands for Model Context Protocol. You can think of it as a common connection interface between an AI application and external tools. Without that connection, the agent might need a custom integration for every utility it wants to use. With an MCP server, a compatible client can discover available tools and call them using the protocol. Sentinel-IR-MCP exposes three: Tool| What it does "analyze_code"| Analyzes JavaScript source supplied as text. "analyze_file"| Analyzes one permitted JavaScript file. "analyze_directory"| Summarizes permitted JavaScript files in a directory, prioritizing higher-risk results. The agent can ask for a directory overview first and then investigate selected files. It does not need to start by sending every source file to the language model. What does the result actually look like? Imagine a JavaScript file imports "child_process", calls "eval" and uses "cp.exec()". Here is a shortened view of the type of structured result demonstrated in the project's README: { "analysisStatus": "complete", "world": { "confidence": 0.75, "risk": "critical" }, "forbidden": [ "eval", "child_process", "process_spawn" ], "facts": { "ast": true, "imports": ["child_process"], "operations": [ "dynamicEval", "processSpawn", "childProcess" ], "dangerous": [ "eval", "child_process", "process_spawn" ] } } This is a shortened illustration based on the documented example, not a claim that every file produces this exact output. Notice the important part. The result does not need to repeat the complete function body to tell the agent that certain patterns were detected. It gives the agent evidence it can use to decide what deserves further investigation. There is also a useful warning in the actual example: the broad "mission.objective" hint can remain "general_optimization" even when the risk is "critical". That is why the project README advises consumers to rely on "world.risk", "forbidden" and "facts", rather than treating every field as equally authoritative. A structured result is useful only when the consumer understands what each field means. Why should ordinary people care? Because AI systems are becoming connected to tools, files and business processes. The question is no longer only whether a model can generate convincing text. It is also what information the model sees before it acts, which evidence supports its conclusions, and where the tool's boundaries are. A smaller structural representation can help with three things: Less irrelevant context. The agent can prioritize relevant files instead of reading everything by default. A clearer inspection trail. Developers can see which structural facts caused a file to be investigated. A smaller prompt-injection surface. The IR does not copy comments, string bodies or function bodies into the result. That can reduce the chance that hidden instructions in those parts of a file reach the model through this particular path. That last point is not a guarantee of safety. Identifiers and some literal values can still appear in the IR, so the result itself must be treated as untrusted data. And reducing context does not automatically make an AI system cheaper, faster or more accurate in every situation. The size of the files, the task and the tokenizer all matter. This is an architectural approach worth testing, not a miracle claim. What does it NOT do? Let's make that clear before the marketing department arrives. 😄 Sentinel-IR-MCP: Does not prove that JavaScript is safe. Does not replace a full security review. Does not support TypeScript or other languages. Does not detect every possible way code can hide its behavior. Does not modify the repository or automatically fix findings. Does not eliminate prompt injection. Its job is narrower: make selected structural facts available to an AI client through MCP. The distinction matters because an agent that receives a concise report can still misunderstand it. Better evidence is not the same thing as infallible reasoning. The 30-minute hands-on guide for developers Now let's move from the idea to an actual integration. The following examples follow the configuration and tool interface documented in the "Sentinel-IR-MCP repository" (https://gitlab.com/jakubrojicek11/sentinel-ir-mcp). Phase 1: Understand the architecture The data flow is intentionally small: Your project JavaScript files | v +-------------------+ | Sentinel-IR-MCP | | | | analyze_directory | | analyze_file | | analyze_code | +-------------------+ | v Compact structural IR | v MCP-compatible AI client | v Select what to inspect next The MCP server bridges two existing pieces: "sentinel-ir", which performs the structural analysis. An MCP-compatible client, which discovers and calls the analysis tools. The implementation uses the official ""@modelcontextprotocol/sdk"" (https://www.npmjs.com/package/@modelcontextprotocol/sdk), "zod" schemas and "sentinel-ir". The current package metadata specifies Node.js 20 or newer. There is no need to compile the parser yourself: the documented analysis path uses WebAssembly. Phase 2: Install through "npx" Check that Node.js is installed: node --version npm --version The required Node.js version is 20 or newer. You normally do not need to install the MCP server globally. The client configuration can start it through "npx", which downloads the package when necessary. The basic command shape is: npx -y sentinel-ir-mcp /absolute/path/to/your/project Replace the example path with the actual directory you want the agent to inspect. Important: "npx" may contact npm to download the package and its dependencies. The read-only guarantee described by the project concerns the server's analysis behavior, not the initial package installation. The server does not need to write to your repository or execute the JavaScript being analyzed. Phase 3: Connect Claude Desktop Open the Claude Desktop developer configuration. The project's README identifies the configuration file as "claude_desktop_config.json". Typical locations are: macOS: "~/Library/Application Support/Claude/" Windows: "%APPDATA%\Claude\" Add the following entry to the existing "mcpServers" object: { "mcpServers": { "sentinel-ir": { "command": "npx", "args": [ "-y", "sentinel-ir-mcp", "/absolute/path/to/your/project" ] } } } Replace "/absolute/path/to/your/project" with an absolute path to the folder you authorize for inspection. For example, a Windows configuration can use a path such as: "C:/Users/you/Projects/my-app" Do not replace your entire existing configuration if it already contains other MCP servers. Add the new entry alongside them and preserve valid JSON syntax. Save the configuration and restart Claude Desktop. The tool should then be available to the client if the server starts successfully and the client's MCP integration is compatible. Phase 4: Connect Cursor Cursor can use a project-level MCP configuration at: .cursor/mcp.json Create the file if it does not exist, or merge the following entry into the existing "mcpServers" object: { "mcpServers": { "sentinel-ir": { "command": "npx", "args": [ "-y", "sentinel-ir-mcp", "${workspaceFolder}" ] } } } "${workspaceFolder}" is intended to resolve to the workspace that contains the ".cursor" directory. The project's README also documents a user-level configuration at "~/.cursor/mcp.json" when you want to configure the server across projects. After updating the configuration, follow the client version's MCP reload or restart process. Configuration details can vary between client versions, so check the relevant client documentation if the server does not appear. Phase 5: Connect Windsurf or another client For Windsurf, the documented path is: Cascade panel → "..." → Open MCP config file Add the same server entry, using an absolute path to the project directory. Other MCP clients that can start servers through standard input/output (stdio) can use the same basic configuration: { "mcpServers": { "sentinel-ir": { "command": "npx", "args": [ "-y", "sentinel-ir-mcp", "/absolute/path/to/your/project" ] } } } A detail worth knowing: if you omit folder arguments, the server attempts to use the client's MCP roots, if the client supports them. When no usable roots are provided, only "analyze_code" is available. For a first setup, explicitly configuring the allowed directory is usually easier to understand and verify. Phase 6: Use the three tools correctly The three tools serve different purposes. Tool A: "analyze_directory" Use it to get a high-level view of a project before deciding which files deserve attention. Its inputs include: Parameter| Purpose "path"| The directory to inspect; optional. "max_files"| Maximum number of files to analyze. "recursive"| Whether to include subdirectories. The defaults are: 50 files per directory analysis. A maximum configurable value of 500 files. Recursive traversal enabled by default. The result contains a compact summary for each file, ordered from higher to lower risk, plus risk counts and information about skipped files or truncation. This is the first tool to use when you do not yet know which files matter. For example, ask your agent: «Use "analyze_directory" to inspect the configured project. Summarize the highest-risk JavaScript files, show the structural evidence for each finding, and tell me whether the result was truncated. Do not modify anything.» That request tells the model what to look for without telling it to act on a risk label blindly. Tool B: "analyze_file" Once the directory overview identifies something interesting, use "analyze_file" to inspect one file. Example tool input: { "path": "src/server.js" } The path is resolved against the configured folders. Only permitted JavaScript files within the allowed locations can be read, and the default maximum file size is 1 MiB. The key practical benefit is that the MCP tool can read the file locally and return its structural representation. The full file does not have to be inserted into the conversation merely to learn its structural properties. The model can then request raw source through other authorized tools or workflows if it needs more detail. That is the central workflow: inspect structure first, request full source only when justified. Tool C: "analyze_code" This tool accepts JavaScript source directly as text: { "target": "example.js", "code": "const cp = require('child_process');\nmodule.exports = input => eval(input);\ncp.exec('whoami');" } The "target" field is optional and identifies the file in the analysis metadata. Use this tool when source text is already available and you want to analyze it without selecting a file on disk. There is an important distinction between the two approaches. When you use "analyze_code", you are explicitly supplying source text to the MCP tool. When you use "analyze_file", the MCP server reads a permitted local file and returns the compact result. If your objective is to avoid sending entire source files through the conversation, "analyze_file" is the more relevant option. Phase 7: Read the result as evidence, not a verdict Here are the major result fields to pay attention to: Field| How to use it "analysisStatus"| Check whether the analysis completed. "world.risk"| Review the reported risk level. "forbidden"| Inspect the patterns the result identifies as forbidden. "facts"| Examine the detected structural facts. "facts.dangerous"| Review the dangerous patterns that were detected. "facts.riskSignals"| Inspect the evidence behind the risk signals. "summary"| Review the file's size and selected capabilities. A robust integration should not simply convert every "critical" result into an automatic rejection or every "low" result into permission to execute the code. Instead: Check whether analysis completed. Inspect the relevant facts. Check the evidence behind the classification. Retrieve additional information if necessary. Make the final decision according to your own system's policies. The analyzer recognizes a defined set of AST patterns. That is useful, but it is not a proof that all possible behavior has been discovered. Phase 8: Keep file access inside the intended boundaries The server is designed to restrict reads to directories configured on the command line or usable MCP roots. The path handling described by the repository resolves real paths before checking whether a target is permitted. Paths that resolve outside the allowed roots are refused. The directory analyzer skips: "node_modules" ".git" Hidden directories Symbolic links It also stops after the configured file limit and reports truncation when applicable. These rules matter because an AI tool should not receive filesystem access simply because a developer connected an MCP server. However, read-only does not mean that the tool can access no data. It can read eligible source files inside the configured boundary. You should therefore configure the narrowest directory that supports the task. For example, do not authorize an entire home directory when the agent only needs one repository. Also remember that a result can contain identifiers and literal values such as route paths, module names, export names and environment-variable names. The structural representation reduces the amount of source code passed into the model, but it is still data derived from untrusted code. Never treat content extracted from a repository as trusted instructions merely because it has been converted into JSON. Phase 9: Set sensible limits The documented command-line options are: sentinel-ir-mcp [--max-file-bytes ] [--max-files ] [folder ...] --max-file-bytes Largest file to analyze. Default: 1048576 (1 MiB) --max-files Default directory file limit. Default: 50 Maximum: 500 For example: npx -y sentinel-ir-mcp \ --max-file-bytes 524288 \ --max-files 25 \ /absolute/path/to/your/project This example reduces the maximum file size to 512 KiB and the default directory-analysis limit to 25 files. Choose limits based on your repository and workload. Smaller limits can keep analysis bounded, but they may also exclude files that contain important evidence. Always pay attention to skipped-file information and truncation. A truncated directory overview should never be presented to a downstream system as if the entire project had been inspected. Phase 10: Test the actual integration A configuration file is not proof that the integration works. The first practical verification should establish that the client can start the server, discover the tools and call them. Try the following sequence: Check 1: Tool discovery Ask the client to list or discover the available Sentinel-IR-MCP tools. Expected tool names: analyze_code analyze_file analyze_directory Check 2: A harmless example Use "analyze_code" with a small JavaScript snippet containing an export or import. Confirm that the tool returns a structured analysis result. Check 3: A directory overview Call "analyze_directory" on the permitted test repository. Check that the paths, number of files and ordering make sense. Check 4: A file outside the boundary Attempt to access a path outside the permitted folder, including a relative traversal path. The expected behavior is refusal, not a successful read. Check 5: A non-JavaScript file Try a file with a different extension. The server should reject unsupported file types. Check 6: A file-size limit Use a JavaScript file larger than your configured maximum. The expected behavior is a refusal instead of an unbounded read. Check 7: A symlink boundary Test both an in-boundary file and a symlink that points outside the permitted directory, where supported by your environment. Verify the actual behavior rather than relying only on the configuration. These are integration checks to perform in your own environment, not results I am claiming to have executed here. Phase 11: Run the repository's tests For developers who want to inspect or modify the implementation, the documented development workflow is: git clone https://gitlab.com/jakubrojicek11/sentinel-ir-mcp.git cd sentinel-ir-mcp npm ci npm test The repository's test documentation describes checks for the tool list and annotations, the three analysis tools, prohibited paths, symbolic-link boundaries, unsupported file types, size limits, MCP roots and command-line options. The project also documents a GitLab CI release flow that tests and publishes tagged releases to npm with provenance. To inspect the actual implementation, start here: "MCP server implementation" (https://gitlab.com/jakubrojicek11/sentinel-ir-mcp/-/raw/main/src/server.js) "Package configuration" (https://gitlab.com/jakubrojicek11/sentinel-ir-mcp/-/raw/main/package.json) "Project README" (https://gitlab.com/jakubrojicek11/sentinel-ir-mcp/-/blob/main/README.md) Do not confuse a passing unit test with proof that every client integration or filesystem boundary is correct in every possible environment. Test the setup you intend to deploy. Phase 12: Build a better agent workflow The MCP connection is only the beginning. The architectural benefit becomes more interesting when an agent uses structural evidence as part of a deliberate decision process. A basic workflow could look like this: Receive a task | v Analyze the permitted directory | v Check status and truncation | v Inspect relevant facts and risk signals | v Select files needing more evidence | v Analyze those files individually | v Read raw source only when justified | v Apply existing review and safety policies This is not autonomous remediation. It is a way to organize the evidence available to an agent. You can extend the workflow with your own policy layer. For example, you might require human approval before an agent modifies files involved in process execution, credentials or network operations. That policy is separate from the MCP server itself. The server provides the structural facts; the surrounding system decides what to do with them. There is value in keeping those responsibilities separate. A library analyzes. An MCP server exposes tools. An agent interprets their outputs. A policy layer decides what actions are permitted. When all four are mixed together, it becomes harder to identify which component produced an incorrect result. Measurements, limitations and honest questions Numbers are useful. Numbers without their conditions are advertising. The Sentinel-IR-MCP README documents a measurement using files from the published "sentinel-ir@0.1.3" sources. The author counted tokens with "gpt-tokenizer@4.0.4", using the "o200k_base" encoding. Here are the reported results: File or operation| Raw tokens| IR tokens "src/ast-facts.js"| 8,439| 120 "src/sentinel-ir.js"| 2,084| 133 "src/tree-parser.js"| 891| 121 "examples/basic.js"| 150| 120 All four via "analyze_directory"| 11,564| 317 For the combined directory result: [ 1-\frac{317}{11564}\approx97.3% ] That is approximately 97.3% fewer tokens for this specific measured input and output, using the stated tokenizer. It is not proof that every repository will see a 97.3% reduction. Small source files may not benefit much because the compact representation itself has a minimum size. The README notes that an IR result can be around 120 tokens per file, which may outweigh the benefit for very small files. The same README reports about 160 milliseconds per "analyze_file" call for "src/ast-facts.js", averaged over 10 calls on Node 24 running on a Linux cloud VM. Initial WebAssembly parser loading adds another consideration. Those figures are useful starting points for an evaluation. They are not a cross-platform performance guarantee. There are also three important limitations. First, this is JavaScript-only. TypeScript and other languages are currently outside the documented scope. Second, it is not a comprehensive security scanner. Static patterns can miss behavior assembled dynamically or hidden in ways that the analyzer does not recognize. Third, the IR does not eliminate prompt injection. It omits comments and function bodies, but some code-derived text remains. The agent must treat the output as data, not instructions. The project is therefore best understood as a compact structural-analysis interface for AI agents, not a replacement for a security review or a complete understanding of a repository. What I would like to test next There are practical questions worth answering with real integration data: How much context does structural triage save on repositories of different sizes? How often does an agent request the correct source file after seeing the structural overview? Which useful details disappear when the model sees the IR instead of raw source? How do false positives and false negatives behave on deliberately tricky JavaScript? How much time does the complete workflow save after including parser startup, tool calls and follow-up inspection? The answers should come from measured tasks, fixed test sets and independently reproducible results, not from the assumption that a smaller prompt is always a better prompt. The point is not to make AI read less at any cost The point is to help it read the right things first. Sometimes the agent needs the whole function. Sometimes it needs a single route definition. Sometimes it needs to know that a file imports "child_process" before spending time on anything else. Those situations should not all begin with the same enormous context dump. Sentinel-IR provides the structural representation. Sentinel-IR-MCP makes it available to compatible AI clients. What the agent does with that evidence remains a separate question, and that separation is intentional. Try it, inspect it, challenge it The code is public. The package is available. The limitations are documented. "Install Sentinel-IR-MCP from npm" (https://www.npmjs.com/package/sentinel-ir-mcp) "Inspect the source on GitLab" (https://gitlab.com/jakubrojicek11/sentinel-ir-mcp) "Explore the underlying Sentinel-IR library" (https://gitlab.com/jakubrojicek11/sentinel-ir) "Read the earlier introduction to Sentinel-IR" (https://dev.to/jackymencz/dont-feed-the-whole-file-to-the-ai-meet-sentinel-ir-8cp) "Read the developer release notes for Sentinel-IR 0.1.3" (https://dev.to/jackymencz/sentinel-ir-013-is-live-better-ast-alias-detection-termux-mobile-android-1270) If you work on AI coding agents, static analysis or MCP integrations, I would be especially interested in feedback backed by an actual repository and repeatable tests. Where would a structural evidence layer fit into your agent? Before the model reads the source? Before it proposes a patch? Before a policy engine decides whether an action is allowed? Unlimited ability to run does not mean unlimited reason to run. And unlimited context does not mean unlimited understanding.

This is a summary aggregated from Dev.to. Read the complete article on the original site:

Read full article at Dev.to

More AI & Machine Learning News