Skip to main content
Glama

MCP-сервер JProfiler

JProfiler — это Java-профилировщик с интеграцией AI-агента через Model Context Protocol. Профилируйте «горячие точки» CPU, выделение памяти, JDBC-запросы, HTTP-вызовы и многое другое прямо из вашего AI-помощника по программированию.

Установка

Claude Code

claude mcp add jprofiler -- npx -y @ej-technologies/jprofiler-mcp

Cursor

Доступен в cursor.directory.

Установить MCP-сервер

Codex

codex mcp add jprofiler -- npx -y @ej-technologies/jprofiler-mcp

Gemini CLI

gemini mcp add jprofiler npx -y @ej-technologies/jprofiler-mcp@latest

Другие MCP-клиенты

Используйте следующую команду npx в качестве команды MCP-сервера в конфигурации вашего клиента:

npx -y @ej-technologies/jprofiler-mcp@latest

Для клиентов, использующих JSON-файл конфигурации (Claude Desktop, Windsurf, VS Code и т. д.):

{
  "mcpServers": {
    "jprofiler": {
      "command": "npx",
      "args": ["-y", "@ej-technologies/jprofiler-mcp"]
    }
  }
}

Дополнительные аргументы

  • --filter <patterns> — список шаблонов имен инструментов через запятую для включения

  • --subsystems <list> — список подсистем через запятую для включения

  • --max-depth <n> — максимальная глубина развертывания дерева вызовов

Related MCP server: Github MCP Server Java

Лицензия

Для JProfiler требуется лицензия. При первом использовании вы можете начать бесплатную 10-дневную пробную версию или ввести существующий лицензионный ключ. Приобрести можно на сайте https://www.ej-technologies.com/store/jprofiler.

Условия лицензии: https://www.ej-technologies.com/jprofiler/license

Available Tools

8 tools
attachA

Attach to a running JVM by PID or to a JVM inside a Docker container. Records performance data for the following subsystems: cpu, jdbc, jpa, mongo_db, cassandra, http_server, http_client, ws, jndi, jms, kafka_consumer, rmi, grpc, ai, process until check_status is called with 'stopRecording: true', or allocation data when "recordingConfig": {"recordAllocations": true} is passed. Pass "recordingConfig": {"recordMonitors": true} to additionally record monitor and lock events. You can use list_jvms to discover JVMs.

NameRequiredDescriptionDefault
pidNoThe PID of a local JVM process, or the container PID (NSpid) of a JVM inside the specified container. If a container is specified and this is omitted, the topmost JVM in the container is used.
recordingConfigNoWhat to record in this session. Every key is optional and omitted keys keep their defaults - set only the keys this analysis needs, such as recordMonitors for lock contention analysis, recordAllocations for allocation sites, triggers for automatic captures during the recording, or advanced.methodCallRecordingType instrumentation when invocation counts are needed.
containerNameOrIdNoThe name or ID of a Docker container. When specified, profiling attaches to a JVM inside this container.

TDQS

A3.9/5.0
Behavior3/5

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

With no annotations, the description carries the full burden. It does disclose a valuable behavioral trait: this starts a persistent recording session that runs until explicitly stopped via check_status. But it says nothing about overhead, failure modes (target not attachable, JVM already attached, missing permissions), or what the call hands back, which the agent needs to proceed to check_status/attached_action.

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

Conciseness4/5

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

Front-loaded with the action and target, then the recording-scope sentence, then the discovery hint. The single long enumeration of subsystems is dense but earns its place by telling the agent what data will exist afterwards.

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

Completeness4/5

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

For a zero-required-param, deeply nested tool with no output schema, the description covers the essentials: target selection, what gets recorded, how recording terminates, and where to find PIDs. The main omission is that the agent is not told what a successful attach returns or whether follow-up calls need a session identifier.

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

Parameters3/5

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

Schema description coverage is 100% and the nested recordingConfig is exhaustively documented inline, so the baseline is 3. The description's mentions of recordAllocations, recordMonitors and the default subsystem list restate what the schema already explains, adding little new meaning.

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?

States a specific verb and target: attach profiling to a *running* JVM, by PID or one inside a Docker container. The word 'running' implicitly separates it from prepare_profiling, and the recording scope (subsystem list, allocation vs performance) is spelled out, so the agent knows exactly what the call accomplishes.

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

Usage Guidelines4/5

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

Gives an explicit discovery path ('use list_jvms to discover JVMs') and states how the recording ends (check_status with stopRecording, or an allocation-mode session). However, it never contrasts attach with prepare_profiling or states when not to attach (e.g. JVM already attached, JVM not yet started), which is the key sibling ambiguity here.

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

attached_actionA

Perform a point-in-time action on the connected JVM: thread and monitor dumps, heap marking and heap dumps, MBean snapshots, and starting or stopping subsystem recording. Requires a recording session started with attach or prepare_profiling. The action names and parameters are the same as for the actions of recordingConfig.triggers.

NameRequiredDescriptionDefault
cpuNoOptional for 'startRecording'/'stopRecording': include CPU recording.
labelNoOptional for 'mbeanSnapshot' and 'threadDump': label shown in the mbean.snapshots resp. threads.dumps dataset. In triggers the default is a name derived from the event.
actionYesThe action to perform on the attached JVM. 'threadDump': the current state and stack trace of every thread, grouped like in the JProfiler thread dumps view - use it when the app is slow but CPU usage is low, and take two dumps to find threads stuck at the same stack trace. 'monitorDump': the currently held and waited-on monitors with the involved threads and stack traces, plus deadlock detection over the current wait/own graph - deadlocks never appear in recorded monitor history because deadlocked events never finish, this dump is the way to find them, and no monitor recording is needed for it; attach-mode dumps show java.util.concurrent locks only, not intrinsic (synchronized) monitors. 'markHeap': mark all current heap objects as old, objects allocated afterwards count as new in heap dumps taken later in this session (generation argument of the heap datasets) - use it to bracket an operation of interest. 'mbeanSnapshot': capture the current JMX MBean attribute values into the session snapshot, for exploration usually unfiltered. 'heapDump': take a heap dump that becomes part of the session snapshot while the recording keeps running - expensive on large heaps, use create_heap_dump instead to stop the recording and analyze the heap immediately. 'startRecording'/'stopRecording': start or stop the recording of subsystems in this session, at least one of 'cpu', 'allocations', 'monitors', 'probes', 'complexity' is required - this does not end the session, use check_status with stopRecording for that. Dumps and snapshots taken by these actions become part of the session snapshot and are served by the threads.dumps, monitor.current, mbean.snapshots and heap.* datasets after the recording is stopped. For captures at events or from JVM start, configure actions with the same names in recordingConfig.triggers of attach or prepare_profiling.
filterNoOptional for 'mbeanSnapshot': regular expression matched against the domain and each property value of the MBean object names: "java.lang|com.mycompany.*" captures all MBeans in those domains, "Memory" the java.lang:type=Memory MBean. Without a filter all MBeans are captured, the right choice for exploration.
fullGcNoOptional for 'heapDump': run a full GC before the dump so only live objects are captured. Default true.
probesNoOptional for 'startRecording'/'stopRecording': probe names to start or stop, e.g. ["jdbc"], "custom:<fully qualified probe class name>" for custom probes of the profiled application, or "script:<name>" for a script probe defined in recordingConfig.advanced.scriptProbes.
monitorsNoOptional for 'startRecording'/'stopRecording': include monitor recording.
complexityNoOptional for 'startRecording'/'stopRecording': include complexity recording - requires recordingConfig.advanced.complexityMethods in the same session. Use it to bound the measurement window, for example scoped to a method with a methodInvocation trigger, or to exclude a warmup phase.
allocationsNoOptional for 'startRecording'/'stopRecording': include allocation recording.
includeVirtualThreadsNoOptional for 'threadDump': take a virtual thread dump that includes all virtual threads and the thread container hierarchy in addition to the platform threads. Default false (platform threads only). Virtual threads require JDK 21+.

TDQS

A4.4/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 discloses the recording-session prerequisite, that dumps and snapshots become part of the session snapshot and are served by datasets after recording stops, and that startRecording/stopRecording does not end the session. The action-level details further explain expensive operations, attach-mode limitations, default full GC behavior, and virtual-thread requirements.

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?

The main description is three front-loaded sentences with no wasted text: it names the capability, states the prerequisite, and gives the trigger-related cross-reference. The extensive action detail lives in the schema where it belongs.

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

Completeness4/5

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

For a ten-parameter tool with no annotations and no output schema, the definition is largely complete: it explains the session prerequisite, where captured data goes, and how recording start/stop differs from ending a session. Minor gaps remain around error behavior and explicit return mechanics, but the core operational context is present.

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

Parameters3/5

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

Schema description coverage is 100%, so the schema already documents all ten parameters in detail, including action-specific meanings and defaults. The main description adds a useful cross-reference that action names and parameters match recordingConfig.triggers, but does not independently add syntax or semantics beyond the schema.

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?

The description states a specific verb and resource: perform a point-in-time action on the connected JVM, and enumerates the action families (thread/monitor dumps, heap marking/dumps, MBean snapshots, subsystem recording). It also distinguishes this from the recording workflow by requiring a session started with attach or prepare_profiling.

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

Usage Guidelines4/5

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

The description clearly states the prerequisite: a recording session started with attach or prepare_profiling. The action parameter schema supplies explicit context for each action, including alternatives such as create_heap_dump for immediate heap analysis and check_status with stopRecording to end the session, though the main description itself does not broadly compare this tool to siblings like query or load_snapshot.

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

check_statusA

Check the status of a profiling session and discover which subsystems were recorded. Can be used to stop recording. When the data is ready provides information about the recorded subsystems (e.g. cpu, jdbc, http_client).

NameRequiredDescriptionDefault
stopRecordingNoOptionally request the recording to be stopped now.

TDQS

A3.9/5.0
Behavior3/5

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

No annotations provided, so description must cover behavioral traits. It discloses the ability to stop recording, but does not explain side effects, permissions, or data readiness conditions beyond 'when the data is ready'.

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 sentences with no redundant words. The primary purpose is front-loaded in the first sentence, and additional capability in the second.

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

Completeness3/5

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

With one optional parameter and no output schema, the description is adequate but lacks details on the output format or error conditions, which would be helpful for an agent.

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

Parameters3/5

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

The single parameter stopRecording is fully described in the schema (100% coverage). The tool description adds no further nuance, so it meets the baseline without adding value.

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?

The description clearly states it checks profiling session status and discovers subsystems, with optional stop recording. This distinguishes from sibling tools like prepare_profiling or create_heap_dump.

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

Usage Guidelines4/5

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

The description mentions 'Can be used to stop recording' implying a specific use case, but lacks explicit guidance on when to use vs alternatives or prerequisites.

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

create_heap_dumpA

Dump the heap of a locally running JVM or of a JVM inside a Docker container and load it for analysis. If allocation data is recorded for the JVM, the heap dump includes per-object allocation data. A recording session delivers a single heap dump, for a later dump attach again. You must call check_status to check the loading progress and - after this returns 'data_ready' - retrieve data with the query tool. You can use list_jvms to discover JVMs.

NameRequiredDescriptionDefault
pidNoThe PID of a local JVM process, or the container PID (NSpid) of a JVM inside the specified container. If a container is specified and this is omitted, the topmost JVM in the container is used.
containerNameOrIdNoThe name or ID of a Docker container. When specified, profiling attaches to a JVM inside this container.

TDQS

A4.1/5.0
Behavior4/5

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

With no annotations, the description carries the load and does disclose key behavior: the operation is asynchronous (poll check_status until 'data_ready'), one dump per recording session, and allocation data is only included when recorded. It omits cost/size/time implications, failure modes (no JVM found, container not running), and whether the dump is persisted or discarded.

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

Conciseness4/5

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

Five compact sentences, front-loaded with the action and followed by the workflow. Each sentence carries information (state, sequencing, constraint), though the session/attach caveat could be tightened.

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

Completeness4/5

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

No output schema exists, but the description compensates by explaining that results are not returned directly and must be fetched via check_status plus the query tool. For a zero-required-param dump trigger this is nearly complete; only error/edge-case behavior is missing.

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

Parameters3/5

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

Schema description coverage is 100%, so pid and containerNameOrId (including the NSpid and topmost-JVM fallback semantics) are already fully documented in the schema. The description adds only the hint that list_jvms can be used to discover JVM identifiers, which is marginal. Baseline 3 applies.

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?

States a specific verb and resource ('Dump the heap of a locally running JVM or of a JVM inside a Docker container') plus the post-condition ('load it for analysis'). It also routes to siblings (list_jvms, check_status, query), so an agent can distinguish it from attach/load_snapshot without opening schemas.

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

Usage Guidelines4/5

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

Gives explicit sequencing: call check_status, wait for 'data_ready', then retrieve with query; use list_jvms to discover JVMs. Also notes one heap dump per recording session and that a later dump requires attaching again. It never explicitly excludes the sibling attach/load_snapshot paths, which keeps it short of a 5.

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

list_jvmsA

List locally running JVMs or JVMs running in a Docker container with their command line and PID. Use the information to call attach or create_heap_dump.

NameRequiredDescriptionDefault
containerNameOrIdNoOptionally specify the name or ID of a Docker container.

TDQS

A4.2/5.0
Behavior3/5

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

No annotations are provided, so the description carries the full burden. It explains what is returned and where it looks, but does not disclose side effects, permissions, or whether the operation is safe to repeat. It vaguely describes query behavior without explicit reassurance of non-destructiveness.

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?

The description is two sentences with no wasted words. The first sentence states the core purpose; the second gives usage guidance. It is efficiently front-loaded.

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

Completeness4/5

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

Given no output schema, the description covers return contents (command line and PID). It could be improved by specifying the output format (e.g., array of objects). Still, it's complete enough for a simple list tool that feeds into other tools.

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 coverage is 100% for the one optional parameter. The description adds value by explaining the parameter's role in filtering to Docker containers, and implicitly that absence means local JVMs. This goes beyond the schema's terse description.

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?

The description clearly states the tool lists locally running JVMs or those in Docker containers, providing command line and PID. It uses specific verbs and resources, and distinguishes from sibling tools like attach and create_heap_dump which are actions to take after listing.

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

Usage Guidelines4/5

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

The description explicitly says 'Use the information to call attach or create_heap_dump,' providing clear context for when to use this tool. However, it does not mention when not to use it or other alternatives, which would be helpful.

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

load_snapshotA

Load an existing .jps, .hprof, or .jfr file for analysis. You must call check_status to check the loading progress and - after this returns 'data_ready' - retrieve data with the query tool. To compare two performance snapshots, load both in a single call: set filePath to the run to analyze and baselineFilePath to the baseline; the differences are then reported in the hotspots and call trees of that run.

NameRequiredDescriptionDefault
filePathYesThe absolute path to the snapshot file
baselineFilePathNoAn optional baseline snapshot for performance comparisons

TDQS

A4.6/5.0
Behavior4/5

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

With no annotations, the description carries the burden and does well: it discloses the asynchronous loading protocol (must poll before querying) and that comparison differences surface in hotspots and call trees of the analyzed run. It does not cover failure modes (bad path, unsupported file, large-file limits) or whether loading is idempotent, leaving a minor gap.

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?

Purpose is front-loaded in the first sentence, followed by the required follow-up workflow and then the comparison option. Dense but every clause carries actionable information with no filler.

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

Completeness4/5

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

For a two-param loader with no output schema, the description covers the purpose, the mandatory polling step, the retrieval tool, and comparison semantics. Only error/precondition behavior is absent, which is a modest gap for a tool whose output is consumed via query.

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 coverage is 100%, so both parameters are already documented. The description goes beyond the schema by explaining what baselineFilePath actually does behaviorally – differences are reported in the hotspots and call trees of the primary run, not the baseline. That adds real meaning.

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?

States a specific verb (load), the resource (snapshot file), and enumerates the supported formats (.jps, .hprof, .jfr) with the goal (for analysis). This clearly separates it from siblings like query or check_status, which are downstream steps.

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?

Gives an explicit mandatory workflow: call check_status to poll progress and only retrieve data with query after 'data_ready'. It also describes the alternative comparison mode (set baselineFilePath) and when to use it. Both when-to-use and sequencing are spelled out.

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

prepare_profilingA

Prepare a profiling session by retrieving a JVM parameter to be added to a Java process call to record performance data with stack traces for the following subsystems: cpu, jdbc, jpa, mongo_db, cassandra, http_server, http_client, ws, jndi, jms, kafka_consumer, rmi, grpc, ai, process. The result is a JSON object containing a 'jvmParameter' to be added (quoted) to the Java process at startup. Add it verbatim and do not create or modify any files; the configuration is already set up for you. If the result contains 'additionalJvmParameters' (discovery of injected custom probes), add each element as a separate VM argument as well. Keep this MCP server running and run the Java process. It waits for the server to connect before application startup. During recording, attached_action can perform live actions. The recording is saved automatically when the JVM terminates, after the optional maximum duration, or when check_status is called with 'stopRecording: true'. Then call check_status to access the data - do not load the saved snapshot file yourself. Saving disconnects from the JVM. Use attach with its PID for another recording if it is still running.

NameRequiredDescriptionDefault
delayNoAn optional recording delay in seconds measured from the successful connection to the JVM.
maximumDurationNoAn optional maximum recording duration in seconds measured from recording startup. If not specified, data will be saved at JVM termination or when check_status is called with 'stopRecording: true'.
recordingConfigNoWhat to record in this session. Every key is optional and omitted keys keep their defaults - set only the keys this analysis needs, such as recordMonitors for lock contention analysis, recordAllocations for allocation sites, triggers for automatic captures during the recording, or advanced.methodCallRecordingType instrumentation when invocation counts are needed.

TDQS

A4.4/5.0
Behavior5/5

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

With no annotations, the description carries the full burden and does so well: it discloses the return shape (JSON with 'jvmParameter' and optional 'additionalJvmParameters'), that parameters must be added verbatim, the no-file-modification constraint, that the server blocks until connection, when the recording is saved (JVM termination, maximumDuration, or stopRecording), and that saving disconnects from the JVM.

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

Conciseness4/5

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

Purpose is front-loaded in the first sentence and the operational steps follow logically. It is a dense single paragraph that runs long, but nearly every sentence carries actionable constraint information (verbatim add, keep server running, wait for connection, save triggers).

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?

For a 3-param tool with a very rich nested schema and no annotations or output schema, the description supplies the missing lifecycle detail: connection blocking, save triggers, disconnection semantics, and follow-up via check_status. Nothing an agent needs to invoke it correctly appears to be missing.

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

Parameters3/5

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

Schema description coverage is 100% and the nested schema is extremely detailed, so the schema does the heavy lifting. The description adds only light context (maximumDuration as an optional recording bound, delay implications), so a baseline 3 is appropriate.

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?

States a specific verb+resource ('Prepare a profiling session by retrieving a JVM parameter') and enumerates the exact purpose (recording performance data with stack traces). It clearly delineates itself from attach by framing this as the startup-parameter step versus attaching to an already-running PID.

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

Usage Guidelines4/5

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

Provides clear workflow context: add the returned parameter at startup, keep the MCP server running, then use attach with a PID for further recordings, and call check_status to retrieve data. It names the relevant siblings (attach, check_status, attached_action) and their conditions, though it does not explicitly state when *not* to use this tool versus attach beyond implication.

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

queryA

Query a performance or heap dataset with a jq expression and return the result. The dataset is materialized lazily and cached per session. Each query is independent, there is no current object: builtins take explicit ids bound from earlier results, e.g. .instances[0].id as $id | {value: preview($id), keptAliveBy: pathToRoot($id).paths[0].path | map(.class)}

NameRequiredDescriptionDefault
idNoThe expansionId of a row from a previous hotspots, callTree, allocation, probe.events, probe.controlObjects or threads.dumps query for the expand dataset, or the id of a biggest object from heap.biggestObjects for the retained dataset
opNoThe filter operation for field: string comparisons (contains, startsWith, endsWith, equals, regexp), object fields (null, nonNull), numeric equals or a from/to range
toNoInclusive upper bound for a numeric range filter or the end of the time window in seconds since recording start (telemetry.series, monitor.*)
setNoOptional for heap.instances, heap.sizes and heap.inspectionResult: a set value from a previous heap result, the operation runs on that object set instead of a class or the whole heap; class, packageFilter and the value filter cannot be combined, filterScript and generation still apply
argsNoArguments for parametric datasets, see the jprofiler://datasets resource or the datasets list in check_status
fromNoInclusive lower bound for a numeric range filter or the start of the time window in seconds since recording start (telemetry.series, monitor.*)
lineNoOptional for telemetry.series: restrict the series to one line by name
nameNoOptional for mbean.snapshots: an MBean object name, requires the snapshot argument
sortNoOptional for probe.events: the global selection and output order - 'duration' (default) keeps and returns the slowest events, 'startTime' the most recent ones
textNoOptional for probe.events and probe.controlObjects: text filter matched against the event description and all text payloads or the object name and text properties, comma-separated alternatives, matching per matchMode
classNoRequired for heap.instances: the class to list instances of, a name value from heap.classes (after the first query, omitting it continues with the last used class)
fieldNoOptional value filter on heap.instances: a field path like customer.name or orders[].id
limitNoOptional row limit for heap.instances, javascript.origins, monitor.history and threads.list, the defaults and caps are documented per dataset in the check_status catalog
scopeNoOptional for javascript.origins: 'recorded' (default) lists only the origins whose requests reached the profiled application, 'all' every origin the browser extension reported, with a recorded flag per row
stateNoOptional for probe.controlObjects: 'open' (default) lists only objects still open, 'closed' only closed objects, 'all' both, 'collectedWithoutClose' (only jdbc with leak recording) connections that were garbage collected without close
typesNoOptional for probe.events: event type names to include, comma-separated or as a JSON array, e.g. the type values of previous rows (open/close names or probe-specific names like 'Statement execution')
valueNoThe comparison value for field and op
columnNoOptional for probe.eventHistogram: the measured value, 'duration' (default), 'throughput' for file/socket probes, or a numeric payload property name from probe.events rows
metricNoOptional for performance datasets of probe subsystems that record a size or token measurement (file, socket, AI): the measurement the hotspots and call tree are ranked by. 'duration' (default) measures event durations, the alternatives are listed in the probeMetrics section of check_status (e.g. write_throughput). Value properties in the result are then named by the metric unit (bytes, tokens) instead of micros. Cannot be combined with threadStatus
threadNoOptional for performance datasets: restrict the analysis to selected threads. 'all' (default) merges all threads, 'virtual' merges all virtual threads into one, an integer thread id selects a single thread - use a threadId from threads.list rows (the same ids the monitor datasets use). Cannot be combined with threadGroup
datasetYesThe dataset to query. The jprofiler://datasets resource documents all datasets with arguments, row formats and examples, check_status lists them with availability for the current session
groupByNoOptional for monitor.stats: the aggregation grouping, default monitors
minCountNoOptional for performance.outliers: only methods with at least this many invocations, default 10
snapshotNoOptional for mbean.snapshots: the index of an MBean snapshot from the catalog
threadIdNoOptional for monitor.history and monitor.graph: restrict to one waiting or owning thread id from monitor.stats
eventTypeNoOptional for monitor.history: restrict to one event type
matchModeNoOptional for probe.events and probe.controlObjects: how text is matched, default contains
maxEventsNoOptional for probe.events: page size of the global top-N selection, default 1000, max 10000
maxMicrosNoOptional for probe.events: maximum event duration in microseconds
maxPointsNoOptional for telemetry.series and monitor.timeline: number of consolidated points per line, default 120, max 500
minMicrosNoOptional for probe.events: minimum event duration in microseconds
monitorIdNoOptional for monitor.history and monitor.graph: restrict to one monitor id from monitor.stats
subsystemNoThe subsystem to analyze, a value from availableSubsystems in check_status (e.g. cpu, jdbc). If the session recorded a single subsystem it is used automatically
telemetryNoRequired for telemetry.series: the telemetry to fetch, an id from telemetry.list (e.g. heap, cpu, threads, heap/PS Eden Space, gc/G1 Young Generation, custom/<name>, jdbc/<group>)
expressionYesThe jq expression, passed as a plain JSON string without surrounding quotes. . returns the dataset unchanged. Datasets are objects, the rows are in the hotspots, callTree, classes or biggestObjects array. Filtering, sorting, projection and aggregation belong in the expression. Examples: .hotspots | sort_by(-.percent) | .[0:10], .hotspots | map({method, percent, expansionId}) | .[0:5] (keep expansionId for drill-downs) or .hotspots | group_by(.method | split(".")[0]) | map({pkg: .[0].method, hotspots: length}) (delivered rows only, exact rollups of the complete recording come from the aggregation parameter). Project tree rows one level at a time: .callTree | map({method, micros, children: [(.children // [])[] | .method]}) - children and callers are omitted on leaves and omitted arrays cannot be iterated, and multi-step values in an object construction must be wrapped in parens: {key: (expr | filter)}. Drill down with the builtin expand(expansionId) inline: .hotspots | sort_by(-.percent) | .[0] | {method, callers: expand(.expansionId).callers}. Retained classes of a biggest object with the builtin retained(id): .biggestObjects | sort_by(-.retainedSize) | .[0] | {class, retained: retained(.id).classes}. Combined size analysis of an object set with the builtin sizes([ids]): .biggestObjects | {top: .[0:3] | map(.class), sizes: sizes([.[0:3][].id])}. References of a heap object with the builtins incoming(id)/outgoing(id): .instances[0] | {name, heldBy: incoming(.id).referrers | map(.class)}. GC root paths with pathToRoot(id) and value previews with preview(id): .instances[0] | {name, value: preview(.id), keptAliveBy: pathToRoot(.id).paths[0].path | map(.class)}. Capture the input before binding variables: . as $rows | ((map(.micros) | add) as $t | ...), wrap generators in constructions with [...]. Keep results small: project fields and slice with .[0:N].
filterPathNoOptional with filterScript: a field path like customer.name or orders[].id, the script is evaluated on the objects the path navigates to instead of the instances of the class
generationNoOptional on heap.classes, heap.biggestObjects and heap.instances: restrict to objects allocated after (new) or before (old) the last markHeap action of the recorded session
ignoreCaseNoIgnore case for string comparisons, default false
inspectionNoRequired for heap.inspectionResult: the inspection to run, an id from heap.inspections
limitBytesNoOptional byte budget for the result, default 24000. Larger results are truncated and marked as such
maxBucketsNoOptional for probe.eventHistogram: maximum bucket count, default 100, max 1000 - the histogram adapts its bucket size to stay below
maxObjectsNoOptional for probe.controlObjects: maximum number of objects per state, default 200, max 2000
aggregationNoOptional for performance and allocation datasets: the rollup level of the tree nodes. 'method' (default) aggregates per method, 'class' per class, 'package' per package, 'component' by Spring, JEE and JPA component class (controllers, services, repositories, empty for apps without such components). Class, package and component rollups are exact, they include everything below the row cutoffs of the method view, and they shrink huge deep trees to an overview. Drill back in with 'method' and a packageFilter
groupScriptNoRequired for the custom_grouping inspection: a Java script evaluated per object that returns the group key string, null skips the object. Read the jprofiler://api/heap-scripts resource for the script API before writing a script
threadGroupNoOptional for performance datasets: restrict the analysis to one thread group, a group value from threads.list rows (platform threads only, virtual threads have no groups). Cannot be combined with thread
filterScriptNoOptional for heap.instances and heap.sizes: a Java script evaluated per object, keeping objects where it returns true - for predicates the value filter cannot express. Read the jprofiler://api/heap-scripts resource for the script API before writing a script
minMaxMicrosNoOptional for performance.outliers: only methods whose slowest invocation took at least this many microseconds, default 10000
threadStatusNoOptional for performance datasets: the thread state whose time is counted. 'running' (default for cpu) counts only time while the thread is scheduled by the OS, waiting on sockets, locks or other threads is not included. 'all' (default for probes) counts wall clock time in all states. 'net_io' counts time waiting on network or file I/O, the state of slow database or REST calls. 'waiting' and 'blocked' count time waiting on other threads or blocked on a monitor, for inter-thread handoff and lock contention analysis. Only 'all' and 'running' carry invocation counts for cpu. Not available for JFR probe subsystems
packageFilterNoOptional package filter to focus on classes of interest (heap datasets and performance subsystems), comma-separated or as a JSON array
payloadFilterNoOptional filter on payload descriptions (SQL statements, URLs) for probe subsystems, applied to hotspots and call trees before the row cutoffs. Each pattern keeps descriptions that contain it, case-sensitive, * and ? are literal characters (a lone * means no filter), comma-separated or as a JSON array, a pattern with a comma needs the array form
controlObjectIdNoOptional for probe.events: restrict to the events of one control object, a controlObjectId from probe.controlObjects or probe.events rows
minDurationMicrosNoOptional for monitor.history: minimum event duration in microseconds

TDQS

A3.5/5.0
Behavior3/5

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

With no annotations, the description must carry the behavioral burden. It usefully discloses that datasets are materialized lazily and cached per session, and that queries are independent rather than operating on a mutable current object. It does not explicitly state that the operation is read-only, whether it can cause side effects, how errors are surfaced, or any permission or rate-limit considerations.

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

Conciseness4/5

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

The description is front-loaded with the core purpose, followed by concise behavioral context and a compact jq example. The example earns its place by showing the explicit-id binding pattern required for builtins. The only inefficiency is the overly narrow 'performance or heap dataset' phrasing in the opening sentence.

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

Completeness4/5

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

For a complex 52-parameter tool with no output schema, the schema itself provides very rich parameter documentation and points to external dataset resources. The description supplies the critical jq-expression model and builtin usage pattern that an agent needs in order to construct queries correctly. It is still somewhat thin on result behavior and dataset availability, but the structured schema compensates for much of that.

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

Parameters3/5

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

Schema description coverage is 100%, so the baseline is 3 even without additional parameter explanations. The description reinforces the expression parameter with builtin examples and the 'no current object' model, but most dataset and argument semantics are already covered in the schema. It adds limited meaning beyond the structured parameter documentation.

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

Purpose4/5

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

The description gives a clear verb-resource pairing: query a dataset using a jq expression and return the result. It distinguishes the tool from lifecycle-oriented siblings such as prepare_profiling and check_status. However, it says 'performance or heap dataset' even though the schema supports telemetry, monitor, probe, threads, GC, and other datasets, so the stated scope is narrower than the actual tool.

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

Usage Guidelines3/5

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

The description explains that each query is independent and that there is no 'current object', which is useful operating guidance. It also demonstrates how to bind ids from earlier results for builtins. It does not explicitly say when to use this tool versus check_status, load_snapshot, or ad-hoc query alternatives, nor does it state any exclusions beyond the no-current-object model.

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.

  1. 6 tool updatesv16.3.0
    • Addedattach
    • Addedattached_action
    • Addedcheck_status
    • Addedload_snapshot
    • Changedprepare_profiling3 fields changed
      • changedInput schema / properties / delay / description
        Previous value: -"An optional recording delay in seconds measured from the jvm start."New value: +"An optional recording delay in seconds measured from the successful connection to the JVM."
      • changedInput schema / properties / maximumDuration / description
        Previous value: -"An optional maximum recording duration in seconds. If not specified, data will be saved at JVM termination or when check_status is called with 'stopRecording: true'."New value: +"An optional maximum recording duration in seconds measured from recording startup. If not specified, data will be saved at JVM termination or when check_status is called with 'stopRecording: true'."
      • addedInput schema / properties / recordingConfig
        Added value: +{
        +  "description": "What to record in this session. Every key is optional and omitted keys keep their defaults - set only the keys this analysis needs, such as recordMonitors for lock contention analysis, recordAllocations for allocation sites, triggers for automatic captures during the recording, or advanced.methodCallRecordingType instrumentation when invocation counts are needed.",
        +  "properties": {
        +    "advanced": {
        +      "description": "Settings that are off by default. Only change them for a concrete reason, never speculatively - more data is not better, and a wrong value can silently lose data. Valid reasons are e.g. check_status reporting possibleInlineAsyncTypes, an application that hands work to thread pools, coroutines or event dispatch threads, an analysis that needs invocation counts, or a previous recording showing that the default filters hide relevant code. The keys without a description correspond to session configuration attributes (such as splittingCap for the call tree split cap mentioned in capped_split warnings) and are documented in the resource jprofiler://config/session.",
        +      "properties": {
        +        "allocTreeRecordingType": {
        +          "enum": [
        +            "live",
        +            "liveAndGcNoClassResolution",
        +            "liveAndGc"
        +          ],
        +          "type": "string"
        +        },
        +        "allocationSamplingInterval": {
        +          "type": "integer"
        +        },
        +        "annotateCustomPayloads": {
        +          "type": "boolean"
        +        },
        +        "asyncBufferPercentage": {
        +          "type": "integer"
        +        },
        +        "asyncNativeSampling": {
        +          "type": "boolean"
        +        },
        +        "asyncThreadResolution": {
        +          "type": "boolean"
        +        },
        +        "complexityMethods": {
        +          "description": "Measure how the invocation time of the given methods scales with an input size computed per invocation by a script: the complexity.methods dataset then holds the recorded (input size, time) points and curve fits, answering questions like 'is this method O(n^2) in the payload size'. This is the second step after performance.hotspots has identified a suspicious method whose inputs vary in size - re-record with this setting pointing at that method. Example: [{\"method\": \"com.example.Service.process(java.util.List)\", \"script\": \"return param0.size();\"}]. Works with any methodCallRecordingType. Recording starts with the session and stops before the snapshot is saved; bound the measurement window with startRecording/stopRecording actions (\"complexity\": true) in triggers or attached_action. The script API is documented in the jprofiler://api/method-scripts resource.",
        +          "items": {
        +            "properties": {
        +              "method": {
        +                "description": "The method whose scaling is measured, in the format com.foo.Bar.method(long, java.lang.String), with () for no parameters. The method does not have to match the package filter.",
        +                "type": "string"
        +              },
        +              "script": {
        +                "description": "Java code returning the input size of the invocation as a long, for example 'return param0.size();' for a collection parameter. Same environment as 'splitMethods' scripts (scriptContext, clazz, currentObject, param0, param1, ...).",
        +                "type": "string"
        +              }
        +            },
        +            "type": "object"
        +          },
        +          "type": "array"
        +        },
        +        "descriptorCap": {
        +          "type": "integer"
        +        },
        +        "exactSamplingMonitorCallStacks": {
        +          "type": "boolean"
        +        },
        +        "exceptionalCap": {
        +          "type": "integer"
        +        },
        +        "exceptionalMethods": {
        +          "description": "Methods whose slowest invocations are kept as separate, individually expandable nodes in performance.callTree (marked with exceptionalRun) instead of being merged into the average. Use after performance.outliers shows a method whose maxMicros deviates strongly from its avgMicros. Format: com.foo.Bar.method(long, java.lang.String), exactly as printed in the method field of performance.outliers; the argument list is required, use () for no parameters. Requires methodCallRecordingType 'instrumentation'. Not recorded for virtual threads.",
        +          "items": {
        +            "type": "string"
        +          },
        +          "type": "array"
        +        },
        +        "exceptionalTimeType": {
        +          "enum": [
        +            "all",
        +            "running",
        +            "waiting",
        +            "blocking",
        +            "netio"
        +          ],
        +          "type": "string"
        +        },
        +        "filter": {
        +          "description": "Comma-separated list of project packages to profile (e.g. 'com.example.app,org.service'). A wrong package silently excludes relevant code from the recording.",
        +          "type": "string"
        +        },
        +        "hotspotPayloadCap": {
        +          "type": "integer"
        +        },
        +        "inlineAsyncTypes": {
        +          "description": "Record async request tracking for the given types, one or more of executor, kotlin_coroutines, awt, swt, virtual_thread, platform_thread. Async executions are then inlined under their call sites in the call tree and hotspot datasets. Off by default because tracking adds overhead - enable when analyzing applications that hand work to thread pools, coroutines or event dispatch threads, or when check_status reports possibleInlineAsyncTypes after a previous recording.",
        +          "items": {
        +            "enum": [
        +              "executor",
        +              "kotlin_coroutines",
        +              "awt",
        +              "swt",
        +              "virtual_thread",
        +              "platform_thread"
        +            ],
        +            "type": "string"
        +          },
        +          "type": "array"
        +        },
        +        "instrumentNativeMethods": {
        +          "type": "boolean"
        +        },
        +        "internalExcludes": {
        +          "type": "boolean"
        +        },
        +        "libraryDebugParameters": {
        +          "type": "string"
        +        },
        +        "lineNumbers": {
        +          "type": "boolean"
        +        },
        +        "methodCallRecordingType": {
        +          "description": "How CPU method calls are recorded. 'sampling' (default) takes periodic call stack samples: very low overhead that does not depend on the package filter, accurate times, but no invocation counts, and methods shorter than the sampling period or called rarely can be missed. 'instrumentation' modifies the bytecode of profiled classes to track method entry and exit: the only mode with exact invocation counts (the count field in the performance datasets) and reliable timing of small, frequently called methods, and it makes allocation stack traces exact; the cost is high overhead and distorted CPU times in CPU-bound code, so it requires a package filter (filter in this object) that restricts instrumentation to the relevant packages. 'async_sampling' samples asynchronously without safepoint bias: the most accurate CPU times for highly multithreaded CPU-bound code, but only on macOS and Linux with a HotSpot JVM (otherwise the agent falls back to sampling), no wall clock times (threadStatus all has no effect) and no invocation counts. Use instrumentation when the analysis needs call counts, otherwise keep the default.",
        +          "enum": [
        +            "instrumentation",
        +            "sampling",
        +            "async_sampling"
        +          ],
        +          "type": "string"
        +        },
        +        "payloadCap": {
        +          "type": "integer"
        +        },
        +        "probeConfig": {
        +          "additionalProperties": {
        +            "type": "object"
        +          },
        +          "description": "Probe-specific settings: a map of subsystem name to a map of attribute name to value, applied to the probe configuration of the recording. Examples: {\"jdbc\": {\"preparedStatementParameters\": true}} records prepared statement parameters in the jdbc hotspots, {\"http_server\": {\"split\": false}} disables URL call tree splitting of the HTTP server probe, {\"http_server\": {\"splitType\": \"script\", \"requestResolvers\": [\"...\"]}} splits the call tree by script-computed request names. Custom probes of the profiled application use the key \"custom:<fully qualified probe class name>\" with the attributes \"events\" (record individual events for the probe.events dataset) and \"injected\" (prepare_profiling and attach pass the probe discovery VM parameter), e.g. {\"custom:com.example.MyProbe\": {\"events\": true, \"injected\": true}} - unknown attributes of custom probes are errors. Script probes defined in 'scriptProbes' use the key \"script:<name>\" with the attribute \"events\". Attribute names and values are those of the JProfiler session configuration, the reference with all attributes of all probes is the resource jprofiler://config/probes. Unknown attributes are silently ignored, the applied settings are reported as probeSettings in check_status.",
        +          "type": "object"
        +        },
        +        "probeFileMBCap": {
        +          "type": "integer"
        +        },
        +        "recordArrayAlloc": {
        +          "type": "boolean"
        +        },
        +        "retainStackForHotspotConsolidation": {
        +          "type": "boolean"
        +        },
        +        "sampleUnmountedVirtualThreads": {
        +          "type": "boolean"
        +        },
        +        "samplingFrequency": {
        +          "type": "integer"
        +        },
        +        "samplingNoFilters": {
        +          "type": "boolean"
        +        },
        +        "samplingPayloadCallStacks": {
        +          "type": "boolean"
        +        },
        +        "scriptClassPath": {
        +          "description": "Additional compile classpath for all scripts in this object ('splitMethods', 'complexityMethods' and script properties in 'probeConfig'): absolute paths to JAR files, to directories containing JAR files, or wildcard patterns like /path/to/lib/*.jar. Only needed when a script references classes beyond the JDK and the JProfiler classes, typically application classes. Used for compilation on this machine only - at runtime the classes must be present in the profiled JVM, which is normally the case for application classes.",
        +          "items": {
        +            "type": "string"
        +          },
        +          "type": "array"
        +        },
        +        "scriptProbes": {
        +          "description": "Define script probes: lightweight probes declared as scripts, compiled by this server and pushed to the profiled JVM - no code, build or deployment in the profiled application, works on attach. Each probe intercepts the given methods, the script computes the payload string per invocation. Defining a script probe records it: it appears as subsystem 'script:<name>' with payload hot spots in performance.hotspots/callTree; individual events are recorded with 'probeConfig': {\"script:<name>\": {\"events\": true}}. Example: [{\"name\": \"Order processing\", \"methods\": [{\"method\": \"com.example.Shop.processOrder(int)\", \"script\": \"return \\\"order \\\" + param0;\"}]}]. Script probes cannot split the call tree, access return values or create control objects, custom event types or telemetries - for those write a custom probe, see jprofiler://probes/custom. The script API is documented in the jprofiler://api/method-scripts resource.",
        +          "items": {
        +            "properties": {
        +              "annotatePayloads": {
        +                "description": "Optional: annotate the CPU call tree with the payload strings. Default false.",
        +                "type": "boolean"
        +              },
        +              "description": {
        +                "description": "Optional explanation of the probe's purpose.",
        +                "type": "string"
        +              },
        +              "methods": {
        +                "items": {
        +                  "properties": {
        +                    "method": {
        +                      "description": "The intercepted method, in the format com.foo.Bar.method(long, java.lang.String), with () for no parameters. The method does not have to match the package filter.",
        +                      "type": "string"
        +                    },
        +                    "script": {
        +                      "description": "Java code returning the payload string for the invocation, or null for no payload. Same environment as 'splitMethods' scripts (scriptContext, clazz, currentObject, param0, param1, ...).",
        +                      "type": "string"
        +                    }
        +                  },
        +                  "type": "object"
        +                },
        +                "type": "array"
        +              },
        +              "name": {
        +                "description": "The probe name. The probe is recorded as subsystem 'script:<name>'.",
        +                "type": "string"
        +              }
        +            },
        +            "type": "object"
        +          },
        +          "type": "array"
        +        },
        +        "splitMethods": {
        +          "description": "Split the call tree below the given methods by a script-computed key: each distinct returned string gets its own subtree (type method_split in performance.callTree), for example to analyze request handling per message type. Example: [{\"method\": \"com.example.Handler.onMessage(javax.jms.Message)\", \"script\": \"return param0.getJMSType();\"}]. Works with any methodCallRecordingType. The script runs on every invocation of the method, so do not split extremely hot methods. The number of distinct keys per split location is capped ('splittingCap', see jprofiler://config/session), further keys are merged into a capped_split node. The script API is documented in the jprofiler://api/method-scripts resource.",
        +          "items": {
        +            "properties": {
        +              "method": {
        +                "description": "The method below which the call tree is split, in the format com.foo.Bar.method(long, java.lang.String), with () for no parameters. The method does not have to match the package filter.",
        +                "type": "string"
        +              },
        +              "script": {
        +                "description": "Java code returning the split key string, or null to leave the invocation unsplit. Available parameters: scriptContext (com.jprofiler.api.agent.ScriptContext, stores per-script state with putObject/getObject and putLong/getLong), clazz (the Class of the declaring class), currentObject (the instance the method is invoked on, null for static methods), param0, param1, ... (the declared method parameters in order). Parameters are statically typed when their class is on the compile classpath and Object otherwise - add application JARs with 'scriptClassPath' to get static typing.",
        +                "type": "string"
        +              }
        +            },
        +            "type": "object"
        +          },
        +          "type": "array"
        +        },
        +        "splittingCap": {
        +          "type": "integer"
        +        },
        +        "utilConcurrentHandling": {
        +          "type": "boolean"
        +        }
        +      },
        +      "type": "object"
        +    },
        +    "blockingThresholdMicros": {
        +      "description": "Optional minimum duration in microseconds for blocked monitor events when 'recordMonitors' is true, shorter events are discarded. Default 1000",
        +      "type": "integer"
        +    },
        +    "recordAllocations": {
        +      "description": "Record allocation data with call stacks instead of performance data. The two are exclusive because recording both distorts the results. Valuable on its own via the allocation datasets, and a heap dump taken in such a session additionally carries per-object allocation sites (heap.allocation* datasets). Allocation data is sampled, not exact. Default false",
        +      "type": "boolean"
        +    },
        +    "recordMonitors": {
        +      "description": "Also record monitor and lock events: threads blocked on monitors, waiting in Object.wait or parked, with stack traces. Composes with performance and allocation recording and enables the monitor.* datasets for contention, lock-order inversion and deadlock analysis. Default false",
        +      "type": "boolean"
        +    },
        +    "subsystems": {
        +      "description": "The subsystems to record in this session. Subsystems not listed are not recorded. Built-in values: cpu, jdbc, jpa, mongo_db, cassandra, http_server, http_client, ws, jndi, jms, kafka_consumer, rmi, grpc, ai, socket, file, process, gc. Custom probes of the profiled application (embedded or injected probe classes) are recorded as 'custom:<fully qualified probe class name>', e.g. custom:com.example.MyProbe. Script probes are not listed here, they are defined in 'advanced.scriptProbes' and recorded as 'script:<name>'. Default: cpu, jdbc, jpa, mongo_db, cassandra, http_server, http_client, ws, jndi, jms, kafka_consumer, rmi, grpc, ai, process, gc.",
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "triggers": {
        +      "description": "Actions executed automatically when an event occurs during the recording. Use them for conditions that interactive tool calls cannot catch: recordings from JVM start, long-running sessions and transient states like heap spikes, or work scoped to a method with 'methodInvocation'. MBean snapshots and heap dumps captured by triggers become part of the session snapshot and are queried like manually captured ones. Example: {\"on\": \"timer\", \"intervalSeconds\": 60, \"actions\": [{\"type\": \"mbeanSnapshot\"}]}",
        +      "items": {
        +        "properties": {
        +          "actions": {
        +            "description": "The actions to run when the event fires, in order.",
        +            "items": {
        +              "properties": {
        +                "allocations": {
        +                  "description": "Optional for 'startRecording'/'stopRecording': include allocation recording.",
        +                  "type": "boolean"
        +                },
        +                "complexity": {
        +                  "description": "Optional for 'startRecording'/'stopRecording': include complexity recording - requires recordingConfig.advanced.complexityMethods in the same session. Use it to bound the measurement window, for example scoped to a method with a methodInvocation trigger, or to exclude a warmup phase.",
        +                  "type": "boolean"
        +                },
        +                "cpu": {
        +                  "description": "Optional for 'startRecording'/'stopRecording': include CPU recording.",
        +                  "type": "boolean"
        +                },
        +                "filter": {
        +                  "description": "Optional for 'mbeanSnapshot': regular expression matched against the domain and each property value of the MBean object names: \"java.lang|com.mycompany.*\" captures all MBeans in those domains, \"Memory\" the java.lang:type=Memory MBean. Without a filter all MBeans are captured, the right choice for exploration.",
        +                  "type": "string"
        +                },
        +                "fullGc": {
        +                  "description": "Optional for 'heapDump': run a full GC before the dump so only live objects are captured. Default true.",
        +                  "type": "boolean"
        +                },
        +                "includeVirtualThreads": {
        +                  "description": "Optional for 'threadDump': take a virtual thread dump that includes all virtual threads and the thread container hierarchy in addition to the platform threads. Default false (platform threads only). Virtual threads require JDK 21+.",
        +                  "type": "boolean"
        +                },
        +                "label": {
        +                  "description": "Optional for 'mbeanSnapshot' and 'threadDump': label shown in the mbean.snapshots resp. threads.dumps dataset. In triggers the default is a name derived from the event.",
        +                  "type": "string"
        +                },
        +                "monitors": {
        +                  "description": "Optional for 'startRecording'/'stopRecording': include monitor recording.",
        +                  "type": "boolean"
        +                },
        +                "probes": {
        +                  "description": "Optional for 'startRecording'/'stopRecording': probe names to start or stop, e.g. [\"jdbc\"], \"custom:<fully qualified probe class name>\" for custom probes of the profiled application, or \"script:<name>\" for a script probe defined in recordingConfig.advanced.scriptProbes.",
        +                  "items": {
        +                    "type": "string"
        +                  },
        +                  "type": "array"
        +                },
        +                "seconds": {
        +                  "description": "Required for 'sleep': the wait time in seconds.",
        +                  "type": "integer"
        +                },
        +                "type": {
        +                  "description": "'mbeanSnapshot': capture the current JMX MBean attribute values into the session snapshot (mbean.snapshots dataset). 'heapDump': take a heap dump that becomes part of the session snapshot (heap.* datasets) - expensive, use it with rare events like 'stop' or a high 'heapThreshold', not with 'timer' or 'start'. 'threadDump': take a thread dump that becomes part of the session snapshot (threads.dumps dataset) - cheap, suitable for 'timer' and threshold triggers. 'monitorDump': capture the currently held and waited-on monitors with the involved threads and stack traces (monitor.current dataset) - only the latest dump is kept, repeated fires overwrite it, so prefer events like 'stop' or thresholds over 'timer'. 'markHeap': mark all current heap objects as old, so a heap dump taken later distinguishes objects allocated afterwards (generation 'new' in the heap.* datasets). 'startRecording'/'stopRecording': start or stop recording of subsystems, at least one of 'cpu', 'allocations', 'monitors', 'probes', 'complexity' is required. 'waitForFinish': only for 'methodInvocation', splits the actions into on-entry and on-exit. 'sleep': wait, delays the following actions.",
        +                  "enum": [
        +                    "mbeanSnapshot",
        +                    "heapDump",
        +                    "threadDump",
        +                    "monitorDump",
        +                    "markHeap",
        +                    "startRecording",
        +                    "stopRecording",
        +                    "waitForFinish",
        +                    "sleep"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "count": {
        +            "description": "Optional for 'on': 'timer': fire at most this many times. Default unlimited.",
        +            "type": "integer"
        +          },
        +          "intervalSeconds": {
        +            "description": "Required for 'on': 'timer': the period in seconds.",
        +            "type": "integer"
        +          },
        +          "method": {
        +            "description": "Required for 'on': 'methodInvocation': the method in the format com.foo.Bar.method(long, java.lang.String) as printed by the performance.outliers dataset; the argument list is required, use () for no parameters. Method triggers instrument only the named method and work with any method call recording type, including the default sampling. Recursive calls fire only once per outermost invocation.",
        +            "type": "string"
        +          },
        +          "offsetSeconds": {
        +            "description": "Optional for 'on': 'timer': delay of the first fire in seconds. Default 0. With a 0 offset the first fire can land before the application has registered its MBeans or reached its working state, a small offset like 1 avoids a mostly empty first capture.",
        +            "type": "integer"
        +          },
        +          "on": {
        +            "description": "When the actions run: 'start' when the recording starts (after the optional delay for prepare_profiling, right after attaching for attach), 'stop' when the recording stops (JVM exit, maximumDuration or check_status with stopRecording for prepare_profiling, check_status with stopRecording for attach), 'timer' periodically, 'heapThreshold' when the used heap stays above 'percent' of the maximum heap, 'cpuThreshold' when the CPU usage stays above 'percent'. Threshold triggers fire at most about once a minute while the condition holds. 'methodInvocation' fires when the method given in 'method' is entered; with 'waitForFinish' in the actions, the actions before it run on method entry and the actions after it on method exit. A subsystem started by a method trigger is not started automatically at recording start, so the trigger defines the recording scope.",
        +            "enum": [
        +              "start",
        +              "stop",
        +              "timer",
        +              "heapThreshold",
        +              "cpuThreshold",
        +              "methodInvocation"
        +            ],
        +            "type": "string"
        +          },
        +          "percent": {
        +            "description": "Required for 'heapThreshold' and 'cpuThreshold': the threshold in percent. Choose a high value such as 80, the actions fire every time the condition holds.",
        +            "type": "integer"
        +          }
        +        },
        +        "required": [
        +          "on",
        +          "actions"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "waitingThresholdMicros": {
        +      "description": "Optional minimum duration in microseconds for waiting and parked monitor events when 'recordMonitors' is true, shorter events are discarded. Default 100000",
        +      "type": "integer"
        +    }
        +  },
        +  "type": "object"
        +}
    • Addedquery
  2. 6 tool updatesv16.2.0
    • Removedattach
    • Removedcheck_status
    • Removedexpand_performance_hotspot
    • Removedget_heap_data
    • Removedget_performance_hotspots
    • Removedload_snapshot
  3. 9 tool updatesv16.1.9
    • Changedattach2 fields changed
      • removedInput schema / $defs
        Removed value: -{}
      • removedInput schema / definitions
        Removed value: -{}
    • Changedcheck_status2 fields changed
      • removedInput schema / $defs
        Removed value: -{}
      • removedInput schema / definitions
        Removed value: -{}
    • Changedcreate_heap_dump2 fields changed
      • removedInput schema / $defs
        Removed value: -{}
      • removedInput schema / definitions
        Removed value: -{}
    • Changedexpand_performance_hotspot2 fields changed
      • removedInput schema / $defs
        Removed value: -{}
      • removedInput schema / definitions
        Removed value: -{}
    • Changedget_heap_data2 fields changed
      • removedInput schema / $defs
        Removed value: -{}
      • removedInput schema / definitions
        Removed value: -{}
    • Changedget_performance_hotspots2 fields changed
      • removedInput schema / $defs
        Removed value: -{}
      • removedInput schema / definitions
        Removed value: -{}
    • Changedlist_jvms2 fields changed
      • removedInput schema / $defs
        Removed value: -{}
      • removedInput schema / definitions
        Removed value: -{}
    • Changedload_snapshot2 fields changed
      • removedInput schema / $defs
        Removed value: -{}
      • removedInput schema / definitions
        Removed value: -{}
    • Changedprepare_profiling2 fields changed
      • removedInput schema / $defs
        Removed value: -{}
      • removedInput schema / definitions
        Removed value: -{}
  4. 9 tool updatesv0.1.0
    • First observedattach
    • First observedcheck_status
    • First observedcreate_heap_dump
    • First observedexpand_performance_hotspot
    • First observedget_heap_data
    • First observedget_performance_hotspots
    • First observedlist_jvms
    • First observedload_snapshot
    • First observedprepare_profiling

TDQS

A4/5.0

Scored across 8 tools

Disambiguation4/5

Most tools target distinct stages of the profiling workflow: discovery, session start, attachment, status, heap dump, snapshot loading, and querying. There is some overlap between check_status and attached_action around controlling recording, and between create_heap_dump and attached_action's heap-dump actions, but the descriptions make the intended boundaries reasonably clear.

Naming Consistency3/5

The set is mostly snake_case, with verb_noun names such as prepare_profiling, load_snapshot, check_status, create_heap_dump, and list_jvms. However, query and attach are bare verbs, and attached_action is an adjective_noun form rather than an imperative verb, so the convention is readable but not fully consistent.

Tool Count5/5

Eight tools is well scoped for a JVM profiling server: each covers a distinct part of the lifecycle from discovering JVMs to recording, loading snapshots, and querying results. There are no obviously redundant tools or missing slots that would suggest the count is off.

Completeness5/5

The surface covers the full expected workflow: list_jvms for discovery, prepare_profiling and attach for starting sessions, check_status and attached_action for control, create_heap_dump for heap capture, load_snapshot for existing files, and query for analysis. No major lifecycle operation appears to be missing.

Maintenance

ActivityMaintained
ResponsivenessUnresponsive

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    C
    maintenance
    MCP server for profiling Java applications via JDK utilities (jcmd, jfr, jps). Enables AI assistants to diagnose performance, analyze threads, and inspect JFR recordings without manual CLI usage.
    26
    40 npm
    10
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    Live .NET runtime diagnostics for AI assistants. Ask Claude to diagnose memory leaks, GC pressure, LOH fragmentation, and thread starvation in any running .NET process — no code changes required.
    7
    2
    MIT