BoxLang 🚀 A New JVM Dynamic Language Learn More...

BoxLang MCP Server

v1.4.1+7 BoxLang Modules

⚡︎ BoxLang Module: BoxLang MCP Server

|:------------------------------------------------------:  |
| ⚡︎ B o x L a n g ⚡︎
| Dynamic : Modular : Productive
|:------------------------------------------------------:  |

This module provides a Model Context Protocol (MCP) server for the BoxLang runtime. It exposes a comprehensive set of runtime introspection tools — allowing external MCP clients such as AI coding assistants and monitoring tools to query, inspect, and manage a live BoxLang instance over HTTP.

The tool set now also includes a holistic performance snapshot endpoint that combines memory, garbage collection, threads, top executors, slow queries, slow requests, slow HTTP/SOAP calls, buffer pools, optional web server metrics, and a built-in health report with recommendations.

The server auto-registers with the bx-ai module and exposes an endpoint at /~bxmcp/boxlang.bxm.


Requirements

  • BoxLang 1.12+
  • bx-plus and bx-ai modules
  • A BoxLang+ Subscription is required for use

Installation

box install bx-mcp

Or use the module installer appropriate to your runtime as described in the Module Installation Guide.


Bug Reporting

Feature Requests and Bug Reports may be submitted via JIRA.

If you file a bug report, your issue should contain a title, a clear description of the issue, a way to replicate the issue, and any support files that we might need to replicate your issue. The goal of a bug report is to make it easy for yourself — and others — to replicate the bug and develop a fix for it. All issues that do not contain a way to replicate will not be addressed.


Support Questions

If you have any questions on usage, professional support or just ideas to bounce off the maintainers, please do not create an issue. Leverage our support channels first.


Configuration

All settings are configured in the module's boxlang.json entry under modules.bxmcp.settings.

{
    "modules": {
        "bxmcp": {
            "enabled": true,
            "settings": {
                "enabled": true,
                "authToken": "FILL_THIS_OUT_ALWAYS",
                "allowedIPs": ["127.0.0.1"],
                "corsAllowedOrigins": [],
                "enableStats": true,
                "maxRequestBodySize": 0,
                "enablePoolLatencyTracking": false,
                "heapDumpDir": "",
                "slowSQL": {
                    "enabled": true,
                    "slowQueryThresholdMs": 1000,
                    "slowQueryBufferSize": 200,
                    "slowQueryCapture": true
                },
                "slowRequests": {
                    "enabled": true,
                    "slowRequestThresholdMs": 1000,
                    "slowRequestBufferSize": 200,
                    "slowRequestCaptureStack": false
                },
                "slowHttp": {
                    "enabled": true,
                    "slowHttpThresholdMs": 1000,
                    "slowHttpBufferSize": 200,
                    "slowHttpCaptureBody": false
                },
                "securityProfiles": {
                    "admin": {
                        "includedTools": ["*"],
                        "excludedTools": []
                    },
                    "readonly": {
                        "includedTools": ["*_get*", "*_has*", "*_search*", "*_read*"],
                        "excludedTools": []
                    }
                },
                "routeMetrics": {
                    "enabled": true,
                    "maxRoutes": 200,
                    "normalizePathParams": true
                },
                "includedTools": ["*"],
                "excludedTools": []
            }
        }
    }
}

Settings Summary

Setting Type Default Description
enabled booleantrue Master switch. When false, the MCP server is not registered at runtime.
authToken string | array"" Bearer token(s) controlling access. Supports a simple string or an array of structs with per-token tool filters. Empty = no auth. See Authentication & Access Control.
allowedIPs array["127.0.0.1"] IP allowlist. Supports individual IPs and CIDR ranges (192.168.0.0/24). Empty array = all IPs allowed.
corsAllowedOrigins array[] CORS allowed origins. Supports wildcards (*.domain.com). Empty = no CORS headers.
enableStats booleantrue Enable MCP server statistics tracking (tool call counts, timing).
maxRequestBodySize numeric0 Max HTTP request body size in bytes. 0 = no limit.
includedTools array["*"] Tool whitelist. ["*"] = all tools. Supports exact names and glob patterns (jvm*, cache_get*).
excludedTools array[] Tools to hide from the MCP client after the whitelist is applied. Supports exact names and glob patterns.
securityProfiles struct{ admin: { includedTools: ["*"], excludedTools: [] }, readonly: { includedTools: ["*_get*","*_has*","*_search*","*_read*"], excludedTools: [] } } Named security profiles that define reusable tool access policies. Profiles are referenced from authToken entries via the profile field. Two built-in profiles (admin and readonly) are always available and can be overridden. See Security Profiles.
enablePoolLatencyTracking booleanfalse Enable HikariCP connection-pool latency histograms for all datasources (acquire/usage/creation percentiles + timeout count). Requires BoxLang 1.14+ with ON_DATASOURCE_INITIALIZED event support.
heapDumpDir string"" Directory where .hprof heap dump files are written by the jvm_trigger_heap_dump tool. Empty = system temp directory. The directory is created automatically if it does not exist.
slowSQL struct{ enabled: true, slowQueryThresholdMs: 1000, slowQueryBufferSize: 200, slowQueryCapture: true } Enable slow SQL capture through the SlowJDBCCollector interceptor. enabled registers the collector; slowQueryThresholdMs sets the slow-query cutoff; slowQueryBufferSize controls the in-memory sample window; slowQueryCapture controls whether rendered SQL text is stored.
slowRequests struct{ enabled: true, slowRequestThresholdMs: 1000, slowRequestBufferSize: 200, slowRequestCaptureStack: false } Enable slow inbound request capture through the SlowRequestCollector interceptor. enabled registers the collector; slowRequestThresholdMs sets the slow-request cutoff; slowRequestBufferSize controls the in-memory rolling window; slowRequestCaptureStack controls whether a completion-time thread stack snapshot is stored.
routeMetrics struct{ enabled: true, maxRoutes: 200, normalizePathParams: true } Enable per-route inbound request metrics. enabled registers the RouteMetricsCollector interceptor; maxRoutes limits tracked unique routes (LRU eviction); normalizePathParams controls whether digit-only and UUID path segments are normalized to {id} to prevent route table explosion.
slowHttp struct{ enabled: true, slowHttpThresholdMs: 1000, slowHttpBufferSize: 200, slowHttpCaptureBody: false } Enable slow outbound HTTP/SOAP call capture through the SlowHttpCollector interceptor. Since SOAP calls transit through the same BoxHttpClient pipeline, they are captured automatically. enabled registers the collector; slowHttpThresholdMs sets the slow-call cutoff; slowHttpBufferSize controls the in-memory sample window; slowHttpCaptureBody controls whether a truncated (500-char) response body snippet is stored.

Security Notes

  • authToken : Strongly recommended for any non-localhost deployment. Clients must send Authorization: Bearer {token}.
  • allowedIPs : Defaults to localhost only. For access from Docker containers or remote machines, add their IPs or CIDR ranges.
  • excludedTools : Use this to hide sensitive operations (e.g., runtime_get_config, cache_clear_all, module_reload_all) from MCP clients. Glob patterns like cache_clear* are supported.

Authentication & Access Control

The authToken setting supports two shapes.

Shape 1 — Simple string

One token, full access to every registered tool:

{
    "modules": {
        "bxmcp": {
            "settings": {
                "authToken": "my-secret-token"
            }
        }
    }
}

Clients send:

Authorization: Bearer my-secret-token

Shape 2 — Array of structs

Multiple tokens, each with independent tool-level access control:

{
    "modules": {
        "bxmcp": {
            "settings": {
                "authToken": [
                    {
                        "token": "admin-token",
                        "includedTools": ["*"],
                        "excludedTools": []
                    },
                    {
                        "token": "readonly-token",
                        "includedTools": ["runtime_get_info", "jvm_get_memory_info", "module_get_all"],
                        "excludedTools": []
                    },
                    {
                        "token": "ops-token",
                        "includedTools": ["*"],
                        "excludedTools": ["jvm_trigger_gc", "cache_clear_all", "module_reload_all"]
                    },
                    {
                        "token": "jvm-readonly-token",
                        "includedTools": ["jvm*", "runtime_get_info"],
                        "excludedTools": []
                    }
                ]
            }
        }
    }
}

Each struct requires a token field. Both includedTools and excludedTools are optional:

Field Default Description
token (required) The Bearer token value the client must send.
profile "admin" Named security profile to apply. References a profile defined in securityProfiles. See Security Profiles.
includedTools ["*"] Tool whitelist. ["*"] means all tools. Provide specific names to restrict access. Overrides the profile's includedTools when set.
excludedTools [] Tools to block even if they match the includedTools whitelist. Merged with the profile's excludedTools.

Filtering rules (applied in order):

  1. If includedTools does not contain "*" and the tool name does not match any pattern → denied.
  2. If the tool name matches any pattern in excludedTools → denied.
  3. Otherwise → allowed.

Both includedTools and excludedTools support glob patterns:

Pattern Matches
"*" All tools
"jvm*" All tools starting with jvm_
"cache_get*" cache_get_all, cache_get_stats, cache_get_keys, …
"*_health*" Any tool with _health in its name
"runtime_get_info" Exact match only

Security Profiles

Security profiles let you define reusable named access policies that can be referenced from multiple authToken entries via the profile field. This avoids repeating the same includedTools/excludedTools patterns across tokens.

Built-in Profiles

Two profiles are built in and always available (you can override them in securityProfiles):

Profile includedTools excludedTools Use Case
admin ["*"] [] Unrestricted access to every tool
readonly ["*_get*", "*_has*", "*_search*", "*_read*"] [] Read-only observability — all inspection tools, no mutation

Custom Profiles

Define additional profiles in the securityProfiles setting:

{
    "modules": {
        "bxmcp": {
            "settings": {
                "securityProfiles": {
                    "operator": {
                        "includedTools": ["*_get*", "*_has*", "module_reload*", "scheduler_*"],
                        "excludedTools": ["app_stop", "runtime_toggle_debug_mode"]
                    },
                    "jvm-only": {
                        "includedTools": ["jvm*", "runtime_get_info"],
                        "excludedTools": ["jvm_trigger_gc", "jvm_trigger_heap_dump"]
                    }
                }
            }
        }
    }
}

Referencing a Profile from a Token

Each authToken entry can reference a profile using the profile field:

{
    "modules": {
        "bxmcp": {
            "settings": {
                "securityProfiles": {
                    "operator": {
                        "includedTools": ["*_get*", "*_has*", "module_reload*", "scheduler_*"],
                        "excludedTools": ["app_stop"]
                    }
                },
                "authToken": [
                    { "token": "admin-token",        "profile": "admin" },
                    { "token": "readonly-token",     "profile": "readonly" },
                    { "token": "operator-token",     "profile": "operator" },
                    {
                        "token": "restricted-ops-token",
                        "profile": "operator",
                        "excludedTools": ["module_reload_all", "scheduler_run_task"]
                    }
                ]
            }
        }
    }
}

When a profile is specified:

  1. The profile's includedTools and excludedTools are loaded as the baseline.
  2. If the token entry also has its own includedTools, it overrides the profile's includedTools.
  3. If the token entry has its own excludedTools, they are merged with the profile's excludedTools.
  4. The standard filtering rules (whitelist → blacklist) are then applied to the merged set.

Profile Inheritance Rules

Token has profile Token has includedTools Token has excludedTools Result
YesNoNoProfile's settings used as-is
YesYesNoToken's includedTools overrides profile
YesNoYesProfile's includedTools + merged excludedTools
YesYesYesToken's includedTools overrides profile + merged excludedTools
NoYes/NoYes/NoNo profile applied; token's own settings used directly

Disabling authentication

Leave authToken empty ("") or omit it entirely to run in open-access mode (no Authorization header required). This is suitable only for localhost-only deployments already protected by allowedIPs.


MCP Tools (154 Total)

The server exposes tools across 17 runtime domains. Each tool is an @mcpTool annotated method discovered automatically via classpath scanning.

Runtime & Configuration — BoxLangTools

Tool Description
runtime_get_info BoxLang version, JVM environment, OS details, start time, uptime, and license status
runtime_get_license_status Current license status: trial mode, validity, expiration, product info (no sensitive tokens)
runtime_get_config Full runtime configuration: datasources, caches, executors, logging, security, schedulers
runtime_get_config_value Get a specific config value by dotted path (e.g. caches.default.provider)
runtime_config_diff Diff live BoxRuntime configuration against boxlang.json on disk
runtime_get_bif_summary BIF counts by category and sorted name list
runtime_get_bif_info Detailed metadata for a specific BIF: signature, parameters, documentation
runtime_search_bifs Search BIFs by keyword
runtime_get_component_summary All registered components with total count
runtime_get_component_info Metadata for a specific component: methods, properties, inheritance
runtime_search_components Search components by keyword
runtime_get_global_services All registered global runtime services
runtime_toggle_debug_mode Toggle BoxLang debug mode on/off
runtime_get_class_resolver_info Class resolver prefixes, cache size, dynamic class loader count
runtime_clear_system_cache Clear compiled class caches (template, function, component, etc.)
runtime_clear_page_pool Clear the Boxpiler page pool of compiled class instances

JVM Diagnostics — JVMTools

Tool Description
jvm_get_memory_info Heap and non-heap memory: used, committed, max, free, percent used
jvm_get_memory_pool_details Memory pool breakdown: Eden, Survivor, Old Gen, Metaspace, Code Cache
jvm_get_thread_info Thread counts: total, daemon, peak, started, by state
jvm_get_thread_dump Full JVM thread dump with stack traces
jvm_get_hot_threads Top-N CPU-consuming threads over a sampling window using ThreadMXBean CPU-time deltas; includes stack traces
jvm_get_top_allocators Top-N thread allocators over a sampling window using per-thread allocated-bytes deltas; includes stack traces and allocation rate
jvm_get_deadlocks Detects deadlocked threads; returns participant stacks, waited lock owner, locked monitors, and synchronizers
jvm_get_cpu_info Available processors, system load average, process CPU time
jvm_get_gc_info GC algorithm statistics: collection count, cumulative collection time
jvm_trigger_gc Manually trigger a garbage collection; returns before/after memory stats
jvm_trigger_heap_dump Trigger an on-demand JVM heap dump (.hprof) to the configured heapDumpDir. Only file metadata (path, size, timing) is returned — the binary dump is not streamed. Pairs with Eclipse MAT for offline leak analysis.
jvm_get_class_loading_info Currently loaded, total loaded, and total unloaded class counts
jvm_get_runtime_info JVM name, vendor, version, uptime
jvm_get_system_properties All JVM system properties
jvm_get_environment_variables JVM environment variables (sensitive values masked)
jvm_get_operating_system_info OS name, version, architecture, available processors
jvm_get_file_descriptors Open and max file descriptor counts plus utilization percent (Unix/Linux/macOS only; returns platform message on Windows)
jvm_get_disk_usage Disk usage for all mounted volumes and BoxLang-relevant paths (temp, logs, home, working directory). Returns total, usable, free space with human-readable sizes and usage percentages.

Hot Threads Sampling Model

jvm_get_hot_threads identifies hot threads by taking a CPU-time snapshot for all threads, waiting for a sampling window, taking a second snapshot, and ranking threads by CPU delta (endNs - startNs).

  • Default arguments: durationMs=3000, topN=5, stackDepth=20
  • This is a single-window delta sampler (not an interval histogram/profiler)
  • Best for quick triage of top CPU consumers without inspecting full thread dumps

Top Allocators Sampling Model

jvm_get_top_allocators identifies allocation-heavy threads by taking a per-thread allocated-bytes snapshot, waiting for a sampling window, taking a second snapshot, and ranking threads by allocation delta (endBytes - startBytes).

  • Default arguments: durationMs=3000, topN=10
  • Single-window allocation delta sampler focused on allocator pressure (not a heap profiler)
  • Best for finding requests driving young-generation GC churn

Deadlock Detection Response Shape

jvm_get_deadlocks returns an empty array when no deadlock exists. When a deadlock is found, each array entry represents one participant thread.

[
    {
        "thread": {
            "id": 51,
            "name": "worker-A",
            "state": "BLOCKED",
            "daemon": false,
            "priority": 5
        },
        "waitingOnLock": {
            "name": "java.lang.Object@4a1f5b2",
            "ownerThreadId": 52,
            "ownerThreadName": "worker-B"
        },
        "stackTrace": ["com.example.Worker.run(Worker.java:42)"],
        "lockedMonitors": [
            {
                "className": "java.lang.Object",
                "identityHashCode": 777123,
                "lockedStackDepth": 1,
                "lockedStackFrame": "com.example.Worker.run(Worker.java:40)"
            }
        ],
        "lockedSynchronizers": [
            {
                "className": "java.util.concurrent.locks.ReentrantLock$NonfairSync",
                "identityHashCode": 998877
            }
        ]
    }
]

Cache Management — CacheTools

Tool Description
cache_get_all All registered cache providers with stats, configuration, status
cache_get_names Cache provider names only
cache_get_stats Detailed cache stats: hits, misses, evictions, performance ratio
cache_get_keys All keys stored in a specific cache
cache_get_size Number of elements in a specific cache
cache_get_key_metadata Metadata for a specific cached object
cache_has_key Check if a key exists in a cache
cache_get_store_metadata Full store metadata report for a cache
cache_clear Clear all elements from a specific cache
cache_clear_item Remove a specific item from a cache
cache_reap Reap (clean up expired entries) from a cache
cache_clear_stats Reset hit/miss/eviction counters for a cache
cache_clear_all Clear all elements from every registered cache
cache_reap_all Reap expired entries from every registered cache
cache_get_health Structured health assessment: status, score, issues with codes per cache

Datasource Management — DatasourceTools

Tool Description
datasource_get_all All registered datasources with configurations and pool metrics
datasource_get_names Datasource names only
datasource_get Single datasource details with pool metrics
datasource_has Check if a datasource is registered
datasource_get_pool_metrics Connection pool metrics: active, idle, total connections, wait times
datasource_get_config Datasource configuration (passwords masked)
datasource_test Test a datasource connection; returns success/failure with timing
datasource_get_health Structured health assessment: status, score, per-datasource pool utilization issues
datasource_get_pool_latency Connection pool latency histograms: acquire/usage/creation p50/p95/p99/max/count + timeout count. Requires enablePoolLatencyTracking: true.

SQL Diagnostics — SQLTools

Tool Description
sql_get_slow_queries Recent captured slow query samples with optional limit and since filter
sql_get_query_stats Aggregate slow query statistics by original SQL and datasource
sql_clear Clear all captured slow-query samples and statistics
sql_get_config Current slow SQL collector configuration
sql_set_config Update slow SQL collector configuration at runtime

HTTP/SOAP Diagnostics — SlowHttpTools

Tool Description
slow_http_get_calls Recent captured slow outbound HTTP/SOAP call samples with optional limit and since filter
slow_http_get_stats Aggregate slow call statistics by destination host (count, average latency, max latency)
slow_http_clear Clear all captured slow-call samples and statistics
slow_http_get_config Current slow HTTP collector configuration
slow_http_set_config Update slow HTTP collector configuration at runtime

Request Diagnostics — RequestsTools

Tool Description
requests_get_slow_requests Recent captured slow request samples with optional limit and since filter
requests_get_stats Aggregate slow-request statistics and collector configuration
requests_get_config Current slow request collector configuration
requests_set_config Update slow request collector threshold, buffer size, and stack capture setting at runtime
requests_clear Clear all captured slow-request samples and counters

Route Metrics — RouteMetricsTools

Tool Description
routes_get_all Per-route request metrics sorted by count, error rate, p99, or last seen time
routes_get_route Detailed metrics for a single route by its exact key (e.g. GET /api/users/{id})
routes_get_summary Aggregate summary: total requests, error rate, route count, top-5 slowest routes by p99
routes_get_config Current route metrics collector configuration
routes_set_config Update route metrics collector config at runtime (maxRoutes, normalizePathParams)
routes_clear Clear all accumulated route metrics data

Performance Snapshot — PerformanceTools

Tool Description
performance_get_snapshot Single round-trip snapshot of memory, garbage collection, CPU, threads, top memory pools, top executors, slow queries, slow requests, slow HTTP/SOAP calls, buffer pools, optional web server metrics, and a structured health report

System Health Aggregator — SystemTools

Tool Description
system_get_health Unified health across all subsystems: datasources, caches, watchers, schedulers, executors, web server. Returns a consolidated structured report with overall status, score, and merged issues

Async Executors — AsyncTools

Tool Description
executor_get_all All registered async executors with status, pool info, task stats
executor_get_names Executor names only
executor_get_info Detailed executor info: type, status, configuration
executor_get_stats Pool utilization, queue status, task counts, health metrics
executor_get_health Structured health report: status, score, per-executor issues with codes
executor_get_health_summary Structured health summary across all executors with status and score

Schedulers — SchedulerTools

Tool Description
scheduler_get_all All registered schedulers with configurations and tasks
scheduler_get_names Scheduler names only
scheduler_get Single scheduler details including tasks and records
scheduler_has Check if a scheduler is registered
scheduler_get_task_stats Execution statistics for a specific task
scheduler_get_task_info Task details: configuration and metadata
scheduler_get_all_tasks All tasks across all schedulers
scheduler_run_task Force-run a scheduled task immediately
scheduler_pause_task Pause a scheduled task
scheduler_resume_task Resume a paused scheduled task
scheduler_pause_persisted_task Pause a disk-persisted task (updates tasks.json)
scheduler_resume_persisted_task Resume a disk-persisted task
scheduler_pause_all_persisted_tasks Pause all disk-persisted tasks (filterable by scheduler/group)
scheduler_resume_all_persisted_tasks Resume all disk-persisted tasks
scheduler_get_health Structured health assessment: status, score, per-scheduler issues
scheduler_get_all_task_stats Task stats summary across all schedulers
scheduler_get_persisted_tasks All scheduled tasks persisted on disk (tasks.json)

Modules — ModuleTools

Tool Description
module_get_all All registered modules with configuration and status
module_get_names Module names only
module_get_info Full configuration and status for a specific module
module_get_settings Settings for a specific module
module_get_paths Registered module search paths
module_reload Reload a specific module (unload, re-register, re-activate)
module_reload_all Reload all registered modules
module_has Check if a module is registered
module_get_stats Module statistics: total count, activated, enabled, etc.

Interceptors — InterceptorTools

Tool Description
interceptor_get_points All registered interception point names (sorted)
interceptor_has_point Check if a specific interception point is registered
interceptor_get_states All interceptor states with listener counts
interceptor_get_state Listener count for a specific event
interceptor_get_summary Registry totals, active states, events with most listeners

Applications — ApplicationTools

Tool Description
app_get_names Active application names
app_get_all All active applications: start times, session counts, class loader counts, expiry status
app_get Full runtime details: session cache metadata, application scope keys, class loaders, uptime
app_has Check if an application is active
app_get_summary Summary: totals, session load, expired apps in registry
app_stop Shut down a running application by name
app_restart Restart a named application, picking up config/code changes
app_sessions_clear Clear all sessions for an application (logs out all users)

Logging — LoggingTools

Tool Description
logging_get_info Log directory, logger count, appender count
logging_get_config Log levels, appenders, retention policies
logging_get_loggers All registered loggers with names and appenders
logging_get_logger Details for a specific logger
logging_get_root_logger Root logger details and attached appenders
logging_get_appenders All registered appenders: file paths, types, configuration
logging_read_entries Last N log entries from a log file
logging_get_last_error Most recent ERROR or FATAL entry from a logger
logging_search_entries Search log entries by keyword or pattern
logging_log_message Write a test log message (verify logging works)

HTTP & SOAP Clients — HttpTools

Tool Description
http_get_client_count Number of active HTTP clients
http_get_client_names HTTP client keys
http_get_clients Per-client stats: connection counts, request counts, error rates
http_get_soap_clients Per-WSDL SOAP client usage details
http_get_executor HTTP executor thread pool status and configuration
http_get_service_summary Consolidated HTTP service summary

File Watchers — WatcherTools

Tool Description
watcher_get_all All registered filesystem watchers with configuration and state
watcher_get_names Watcher names only
watcher_get Single watcher details
watcher_has Check if a watcher is registered
watcher_get_stats Watcher execution statistics
watcher_start Start a stopped watcher
watcher_stop Stop a running watcher
watcher_restart Restart a watcher
watcher_remove Remove a watcher from the registry and stop it
watcher_get_health Structured health assessment: status, score, per-watcher errors

Web Server (Undertow) — UndertowTools

Tool Description
undertow_get_stats Undertow web server statistics: worker pool (core/max/current/busy/queue), IO pool, listener connection/request/error counts, active requests, WebSocket connections
undertow_get_health Structured health assessment: status, score, worker saturation, queue depth, listener error rates with issue codes

These tools auto-detect the deployment mode — BoxLang MiniServer, Runwar/CommandBox, or generic Undertow via JMX — and return rich metrics regardless of which Undertow-based server is running. Worker pool data comes from the XnioWorkerMXBean; listener and request-level metrics are available on MiniServer and Runwar. On non-Undertow deployments, the tools return { available: false }.


Structured Health Reports

All health tools return a consistent structured report that enables clients to rank, filter, and reason about runtime health programmatically.

Standard Shape

{
  "status": "healthy",
  "score": 85,
  "issues": [
    {
      "severity": "warning",
      "code": "DS_POOL_HIGH_UTILIZATION",
      "message": "Datasource 'mainDB' pool is under high load at 87% (28/32 active)",
      "suggestedAction": "Monitor pool utilization and consider increasing pool size",
      "entity": "mainDB",
      "entityMetrics": { "utilization": 87, "active": 28, "max": 32 }
    }
  ],
  "scoreBreakdown": {
    "base": 100,
    "deductions": [
      { "code": "DS_POOL_HIGH_UTILIZATION", "severity": "warning", "penalty": 15 }
    ]
  }
}

Scoring Model

Severity Penalty Score Range
healthy—80 – 100
warning25 per issue50 – 79
critical50 per issue0 – 49
info5 per issueno status change

Issue Code Catalog

Domain Code Severity Trigger
Datasource DS_POOL_NOT_STARTED warningPooling not started
DS_POOL_HIGH_UTILIZATION warning>80% utilization
DS_POOL_SATURATED critical>=95% utilization
DS_POOL_THREADS_AWAITING warningWaiting threads > 0
Cache CACHE_DISABLED warningCache not enabled
CACHE_LOW_HIT_RATE warningHit rate <30%
CACHE_HIGH_EVICTIONS warningEvictions >= size (thrashing)
Watcher WATCHER_STOPPED warningWatcher is stopped
WATCHER_ERRORS warningConsecutive errors > 0
WATCHER_HIGH_ERRORS criticalConsecutive errors >= 10
Scheduler SCHEDULER_NOT_STARTED warningScheduler not started
SCHEDULER_ALL_TASKS_PAUSED warningAll tasks paused
Web Server WEB_WORKER_SATURATED criticalWorker pool saturated
WEB_WORKER_HIGH_LOAD warning>=80% utilization
WEB_QUEUE_HIGH criticalQueue > 50% of max
WEB_LISTENER_HIGH_ERROR_RATE warningError rate >5%
WEB_HIGH_CONNECTION_RATIO infoConnections >> workers
Executor EXECUTOR_UNHEALTHY criticalShutdown/terminated/critical
EXECUTOR_DEGRADED warningDegraded/draining/idle
EXECUTOR_NEAR_SATURATION warningHigh saturation score
Performance JVM_HEAP_CRITICAL criticalHeap >95%
JVM_HEAP_PRESSURE warningHeap >85%
JVM_BLOCKED_THREADS warningBlocked threads > 0
PERF_SLOW_QUERIES infoSlow queries present
PERF_SLOW_REQUESTS infoSlow requests present
PERF_SLOW_HTTP infoSlow HTTP calls present

system_get_health Aggregator

The system_get_health tool calls every subsystem health endpoint in a single round-trip and returns:

{
  "status": "warning",
  "score": 65,
  "issues": [
    { "code": "executors:EXECUTOR_DEGRADED", "severity": "warning", ... }
  ],
  "subsystems": {
    "datasources": { "status": "healthy", "score": 100, "issues": [], ... },
    "caches": { "status": "warning", "score": 85, "issues": [...], ... },
    "watchers": { "status": "healthy", "score": 100, "issues": [], ... },
    "schedulers": { "status": "healthy", "score": 100, "issues": [], ... },
    "executors": { "status": "warning", "score": 65, "issues": [...], ... },
    "webServer": { "status": "healthy", "score": 100, "available": true, ... }
  },
  "scoreBreakdown": {
    "base": 100,
    "subsystems": [
      { "subsystem": "datasources", "score": 100, "status": "healthy" },
      ...
    ]
  }
}

The overall score is the minimum subsystem score (weakest-link model). Issue codes are prefixed with the subsystem name (e.g., executors:EXECUTOR_DEGRADED) so clients can filter by domain.


MCP Prompts (32 Total)

The server registers pre-built MCP prompts that guide AI clients through common diagnostic and administrative workflows. Each prompt instructs the AI agent which tools to call and in what order, and provides system-level context for interpreting results.

Operations & Monitoring

Prompt Description Arguments
runtime_health_check Comprehensive health check: memory, caches, datasources, executors, modules—
full_system_audit End-to-end audit of every subsystem (JVM, threads, web server, caches, datasources, modules, schedulers, executors, logging, watchers)—
performance_troubleshooting Interactive diagnostic guide for a given symptom (slow responses, high memory, CPU spikes, thread pool exhaustion)symptom (required)
diagnose_memory_pressure JVM memory diagnosis: heap, non-heap, pools, GC activity; identifies leaks and misconfigurationthreshold (optional, default: 80)
executor_saturation_check Async executor pool saturation, queue buildup, and rejected tasks—
deployment_validation Validate a deployment after a new release or module update: confirms runtime started cleanly, expected modules loaded, datasources reachable, executor pools healthy, and web server accepting trafficexpectedModules (optional)

Data Layer

Prompt Description Arguments
analyze_cache_performance Cache hit rates, eviction patterns, sizing; optionally focus on a named cachecacheName (optional)
datasource_health_report Datasource connectivity, connection pool utilization, configuration audit—
slow_sql_diagnosis Identify and diagnose slow SQL queries: patterns, datasource hotspots, and tuning recommendationslimit (optional, default: 50)
slow_http_diagnosis Identify and diagnose slow outbound HTTP/SOAP calls: destination host hotspots, error-prone integrations, timeout and connection pool tuning recommendationslimit (optional, default: 50)

Diagnostics

Prompt Description Arguments
thread_dump_analysis JVM thread dump: identifies deadlocks, blocked threads, pool saturation, long-running operations—
investigate_errors Recent log error investigation: patterns, root causes, fixesloggerName, keyword (optional)
logging_infrastructure_review Logging infrastructure audit: log levels, appenders, recent error patterns—
class_loader_diagnostics Class loader health: resolver cache, loader count, deployment mode, runtime home—
jvm_resource_audit OS-level JVM resource audit: file descriptors, disk space on all volumes, CPU load, key system properties — capacity planning and resource leak detection—
cpu_profiling Live CPU profiling via hot-thread and allocation-heavy-thread sampling over a configurable window; correlates with GC activity and thread dumpsdurationMs (optional, default: 3000), topN (optional, default: 10)

Auditing

Prompt Description Arguments
module_audit All registered modules: status, version, BIFs, components, interceptors, configuration—
interceptor_registry_audit Interceptor/event system: registered points, listener counts, coverage gaps—
scheduler_status_report Scheduler task execution history, upcoming runs, failuresschedulerName (optional)
application_lifecycle_status All active applications: uptime, session counts, expired apps, load indicators—
http_connectivity_audit Outbound HTTP and SOAP client activity: connections, pool usage, errors—
file_watcher_health File watcher health check: running vs. stopped state, events processed, error counts; flags stalled or failing watchers—

Web Server & Routing

Prompt Description Arguments
web_server_diagnostics Deep-dive Undertow diagnostics: worker thread pool saturation, IO pool, active/queued requests, listener stats, WebSocket connections—
slow_request_analysis Identify slow inbound HTTP requests: correlates captured samples with per-route metrics to surface worst-performing endpointslimit (optional, default: 50)
route_performance_analysis Per-route HTTP performance: identify slowest and highest-traffic endpoints, error rates, prioritized optimization backlogsortBy (optional, default: avgLatency), limit (optional, default: 20)

Developer

Prompt Description Arguments
bif_component_discovery Explore available BIFs and components; search by keywordkeyword (optional)
application_debug_assistant Targeted debug assistant for a specific application: lifecycle state, log errors, datasource health, cache stats, thread contextappName (required)

Incident Response

Prompt Description Arguments
incident_triage Rapid incident triage: scan errors, threads, memory, web server, datasources, and executors to identify what's broken right now—
error_spike_response Error spike response: correlate timing, identify blast radius, and recommend containment actionskeyword (optional)
cascade_failure_diagnosis Cascade failure diagnosis: trace failure chains across subsystems (datasource timeout → thread saturation → request queuing)—
rollback_decision Rollback decision: structured go/no-go comparison of current state vs. deployment baselineexpectedModules (optional)
post_incident_review Post-incident review: collect timeline, identify impact, determine root cause, and generate improvement actionskeyword (optional)

Usage Example

Once installed, the MCP server is available at http://localhost:8080/~bxmcp/boxlang.bxm. Configure your MCP client (Claude Desktop, Cursor, VS Code, etc.) to connect to this endpoint.

{
    "mcpServers": {
        "boxlang": {
            "url": "http://localhost:8080/~bxmcp/boxlang.bxm",
            "headers": {
                "Authorization": "Bearer your-auth-token"
            }
        }
    }
}

You can also configure it in your VSCode workspace by creating a .vscode/mcp.json file with the following content:

{
	"mcpServers": {
		"boxlang-mcp": {
			"url": "http://localhost:8080/~bxmcp/boxlang.bxm",
			"headers": {
				"Authorization": "Bearer your-auth-token"
			}
		}
	}
}

Replace your-auth-token with the value of authToken from your module settings. If authToken is empty, omit the headers block.

Selectively expose only the tools you need:

{
    "modules": {
        "bxmcp": {
            "settings": {
                "includedTools": [
                    "runtime_get_info",
                    "jvm_get_memory_info",
                    "scheduler_get_all"
                ]
            }
        }
    }
}

Or use glob patterns to expose entire categories:

{
    "modules": {
        "bxmcp": {
            "settings": {
                "includedTools": ["jvm*", "runtime_get_info", "datasource_get_health"]
            }
        }
    }
}

Or exclude sensitive admin tools:

{
    "modules": {
        "bxmcp": {
            "settings": {
                "includedTools": ["*"],
                "excludedTools": [
                    "cache_clear_all",
                    "module_reload_all",
                    "app_stop"
                ]
            }
        }
    }
}

Extending with Custom Tools

You are not limited to the built-in introspection tools. Any module or application can register its own tools, resources, and prompts into the BoxLang MCP server at runtime using the bx-ai BIF mcpServer( "boxlang" ).

Register a Custom Tool

// Get the BoxLang MCP server instance
var server = mcpServer( "boxlang" )

// Register a simple tool with a handler
server.registerTool(
    aiTool(
        "check_deployment_status",
        "Check the current deployment status of the application",
        ( environment ) => {
            var status = deploymentService.getStatus( environment )
            return {
                environment: arguments.environment,
                version: status.version,
                deployedAt: status.deployedAt.toString(),
                healthy: status.healthy
            }
        }
    )
    .addParameter(
        aiToolParam( "environment", "string", "The deployment environment to check (e.g., staging, production)" )
        .required()
    )
)

Register a Custom Prompt

mcpServer( "boxlang" ).registerPrompt(
    "deployment_health_check",
    "Check the health of the current deployment by analyzing application status and recent logs",
    ( args ) => [
        {
            role: "system",
            content: "You are a deployment operations expert. Verify the current deployment by checking the application status and analyzing recent logs."
        },
        {
            role: "user",
            content: "Check the deployment health. Use `check_deployment_status` for the '#args.environment ?: 'production'#' environment and `get_last_error` from the logging tools."
        }
    ],,
    [
        { name: "environment", description: "The deployment environment to check", required: false }
    ]
)

Multiple Ways to Register Tools

The server supports several registration patterns:

  • Direct handler — Pass a BoxLang closure or lambda as the tool handler (shown above)
  • Classpath scanning — Call server.scan( "myapp.tools" ) to auto-discover methods annotated with @mcpTool
  • AITool instances — Create aiTool() objects and register them individually or as an array via server.registerTools( [...] )

You can also access any existing tool by name:

var tool = mcpServer( "boxlang" ).getTool( "runtime_get_info" )
writeOutput( tool.getDescription() )

Best Practice: Module Startup Registration

The ideal time to register custom tools is your application or module startup code. For your application you can use the onApplicationStart lifecycle method, and for modules you can use the onLoad method in your module's main class. This ensures your tools are available as soon as the MCP server is active. If you are in a ColdBox application, you can also register them in your config/ColdBox.cfc in the configure() method, or in the onApplicationStart handler.

mcpServer( "boxlang" )
	.registerTool( aiTool( "my_custom_tool", "Description", handler ) )

Interactive CLI

The module ships with a built-in interactive CLI client that connects to any MCP server endpoint. Launch it from the BoxLang CLI:

boxlang bxmcp [url] [--timeout=ms] [--token=bearer] [--help]
Argument Description
url The MCP server endpoint URL (optional — will prompt if omitted)
--timeout=ms Request timeout in milliseconds (default: 30000)
--token=bearer Bearer token for authenticated MCP servers
--help, -h Show the help message

Examples

# Launch interactively — prompts for URL
boxlang bxmcp

# Connect to a local BoxLang MCP server
boxlang bxmcp http://localhost:8080/~bxmcp/index.bxm

# With authentication and custom timeout
boxlang bxmcp http://localhost:8080/~bxmcp/index.bxm --timeout=5000 --token=secret123

Interactive Commands

Once connected, the CLI provides tab completion and the following commands:

Command Description
help, ? Show available commands and syntax
connect Re-run the connection handshake
tools List all available MCP tools (cached)
prompts List all available MCP prompts (cached)
resources List all available MCP resources (cached)
run <tool> [args] Invoke a tool by name with optional JSON arguments
prompt <name> [args] Get a prompt by name with optional arguments
resource <uri> Read a resource by URI
stats Display MCP client connection statistics
clear Clear the terminal screen
watch <tool> [interval] Poll a tool every N seconds (default 5) until interrupted
exit, quit, q Disconnect and exit

Architecture

The CLI uses BoxLang's MiniConsole with a modular design:

Component File Purpose
MCPConsole cli/MCPConsole.bx Interactive shell loop, command dispatch, MiniConsole integration
MCPCommandParser cli/MCPCommandParser.bx Tokenizes input into command + target + JSON arguments
MCPResponseFormatter cli/MCPResponseFormatter.bx Pretty-prints tables, JSON, errors, banners, stats with ANSI styling
MCPSpinner cli/MCPSpinner.bx ASCII spinner animation during blocking MCP calls
MCPTabProvider cli/MCPTabProvider.bx Tab completion for commands, cached tool/prompt/resource names

Client Interaction Examples

All interactions use JSON-RPC 2.0 over HTTP POST to /~bxmcp/boxlang.bxm.

Replace http://localhost:8080 with your server URL. Add Authorization: Bearer {token} if authToken is configured.

1. List all available tools

curl -s http://localhost:8080/~bxmcp/boxlang.bxm \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"tools/list","id":"1"}' | jq '.result.tools[] | {name, description}'

2. Get BoxLang runtime info

curl -s http://localhost:8080/~bxmcp/boxlang.bxm \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"runtime_get_info","arguments":{}},"id":"2"}' | jq '.result.content[0].text | fromjson'

3. Check JVM memory usage

curl -s http://localhost:8080/~bxmcp/boxlang.bxm \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"jvm_get_memory_info","arguments":{}},"id":"3"}' | jq '.result.content[0].text | fromjson'

4. Capture a JVM thread dump

curl -s http://localhost:8080/~bxmcp/boxlang.bxm \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"jvm_get_thread_dump","arguments":{}},"id":"4"}' | jq '.result.content[0].text | fromjson'

5. Detect deadlocked JVM threads

curl -s http://localhost:8080/~bxmcp/boxlang.bxm \
    -H "Content-Type: application/json" \
    -d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"jvm_get_deadlocks","arguments":{}},"id":"5"}' | jq '.result.content[0].text | fromjson'

6. Get cache health

curl -s http://localhost:8080/~bxmcp/boxlang.bxm \
  -H "Content-Type: application/json" \
    -d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"cache_get_health","arguments":{}},"id":"6"}' | jq '.result.content[0].text | fromjson'

7. Check datasource connectivity

curl -s http://localhost:8080/~bxmcp/boxlang.bxm \
  -H "Content-Type: application/json" \
    -d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"datasource_get_health","arguments":{}},"id":"7"}' | jq '.result.content[0].text | fromjson'

8. Test a specific datasource connection

curl -s http://localhost:8080/~bxmcp/boxlang.bxm \
  -H "Content-Type: application/json" \
    -d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"datasource_test","arguments":{"dsn":"mainDB"}},"id":"8"}' | jq '.result.content[0].text | fromjson'

9. Audit all loaded modules

curl -s http://localhost:8080/~bxmcp/boxlang.bxm \
  -H "Content-Type: application/json" \
    -d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"module_get_all","arguments":{}},"id":"9"}' | jq '.result.content[0].text | fromjson'

10. Search recent log entries for errors

curl -s http://localhost:8080/~bxmcp/boxlang.bxm \
  -H "Content-Type: application/json" \
    -d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"logging_search_entries","arguments":{"loggerName":"runtime","keyword":"error","limit":20}},"id":"10"}' | jq '.result.content[0].text | fromjson'

11. Get all registered schedulers and tasks

curl -s http://localhost:8080/~bxmcp/boxlang.bxm \
  -H "Content-Type: application/json" \
    -d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"scheduler_get_all","arguments":{}},"id":"11"}' | jq '.result.content[0].text | fromjson'

Tip: Pipe through jq to extract and parse the JSON response. The MCP server wraps tool results inside result.content[0].text as a JSON-encoded string.

Calling a Prompt

curl -s http://localhost:8080/~bxmcp/boxlang.bxm \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"prompts/get","params":{"name":"full_system_audit","arguments":{}},"id":"11"}' | jq '.result.messages'

Copyright Since 2023 by Ortus Solutions, Corp
www.boxlang.io | www.ortussolutions.com

Ortus Sponsors

BoxLang is a professional open-source project and it is completely funded by the community and Ortus Solutions, Corp. Ortus Patreons get many benefits like a cfcasts account, a FORGEBOX Pro account and so much more. If you are interested in becoming a sponsor, please visit our patronage page: https://patreon.com/ortussolutions

THE DAILY BREAD

"I am the way, and the truth, and the life; no one comes to the Father, but by me (JESUS)" Jn 14:1-12

Changelog

Unreleased

1.4.1 - 2026-06-11

Fixed

  • Null exception when application was not existent on many collectors

1.4.0 - 2026-06-05

Fixed

  • SlowHTTPCollector was not properly handling the result nested data, causing all calls to be broken.

Changed

  • Route metrics now expose per-status-class statusCounts and 5xx-only serverErrorRate instead of the previous combined errorCount/errorRate fields.

1.3.0 - 2026-06-03

  • Built for BoxLang 1.14.0 with new tool and prompt capabilities, plus a full suite of DevOps-focused tools for JVM introspection, datasource and cache management, logging, web server diagnostics, and more

1.2.0 - 2026-06-01

Added

  • Build process updates to make sure we are consistent with other bx-plus modules
  • Updated core functions for the upcoming 1.14.0 release

1.1.0 - 2026-05-29

Added

  • Undertow web server tools (undertow_get_stats, undertow_get_health) — worker pool, listener, request metrics, WebSocket connections with MiniServer/Runwar/JMX fallback detection
  • Slow SQL diagnostics (sql_get_slow_queries, sql_get_query_stats, sql_set_config, sql_clear) via new SlowJDBCCollector Java interceptor
  • Slow inbound request tracking (requests_get_slow_requests, requests_get_stats, requests_set_config, requests_clear) via SlowRequestCollector interceptor
  • Slow outbound HTTP/SOAP diagnostics (slow_http_get_calls, slow_http_get_stats, slow_http_clear) via SlowHttpCollector interceptor
  • Per-route request metrics (routes_get_all, routes_get_route, routes_get_summary) with count, status-class counts, server error rate, and p50/p95/p99 latency histograms via RouteMetricsCollector interceptor
  • HikariCP connection pool latency histograms (datasource_get_pool_latency) with bucket-based tracking via PoolLatencyTracker
  • System health aggregation (system_get_health) — consolidated datasource, cache, watcher, scheduler, executor, and web server health in one call
  • Performance snapshot (performance_get_snapshot) — combined memory, GC, threads, executors, slow queries/requests, buffer pools, and web server stats
  • JVM introspection extensions — jvm_get_hot_threads, jvm_get_top_allocators, jvm_get_deadlocks, jvm_get_cpu_info, jvm_get_gc_info, jvm_trigger_gc, jvm_trigger_heap_dump, jvm_get_class_loading_info, jvm_get_runtime_info, jvm_get_system_properties, jvm_get_environment_variables, jvm_get_operating_system_info, jvm_get_file_descriptors, jvm_get_disk_usage
  • Cache full toolkit — cache_get_all, cache_get_names, cache_get_stats, cache_get_keys, cache_get_size, cache_get_key_metadata, cache_has_key, cache_get_store_metadata, cache_clear, cache_clear_item
  • Datasource full toolkit — datasource_get_all, datasource_get_names, datasource_get, datasource_has, datasource_get_pool_metrics, datasource_get_config, datasource_test, datasource_get_health
  • Logging full toolkit — logging_get_info, logging_get_config, logging_get_loggers, logging_get_logger, logging_get_root_logger, logging_get_appenders, logging_read_entries, logging_get_last_error, logging_search_entries, logging_log_message
  • Executor full toolkit — executor_get_all, executor_get_names, executor_get_info, executor_get_stats, executor_get_health, executor_get_health_summary
  • Runtime introspection — runtime_get_license_status, runtime_get_config, runtime_get_config_value, runtime_config_diff, runtime_get_bif_summary, runtime_get_bif_info, runtime_search_bifs, runtime_get_component_summary, runtime_get_component_info, runtime_search_components, runtime_get_global_services, runtime_toggle_debug_mode, runtime_get_class_resolver_info, runtime_clear_system_cache, runtime_clear_page_pool
  • RBAC security profiles — built-in admin (full access) and readonly (get/has/search/read only) profiles, plus custom named profiles with glob patterns
  • Multi-token authentication — authToken supports simple string, profile-referenced, or inline per-token includedTools/excludedTools glob arrays
  • Prompt domains — restructured into 7 dedicated classes (DataLayer, Developer, Diagnostics, IncidentResponse, Infrastructure, Operations, WebServer) with 8+ new DevOps/user prompts
  • Linting — cfformat and Spotless formatting configuration

Fixed

  • BLMODULES-208: datasource_get_pool_metrics and datasource_get_health NoSuchMethod on HikariPool
  • Deadlock detection now properly returns structured response instead of throwing
  • Module unloading failures during shutdown/refresh

Changed

  • Breaking: All tool names refactored with domain prefixes for consistency (e.g., get_memory_info → jvm_get_memory_info, get_all_datasources → datasource_get_all)
  • Tool filtering upgraded from exact name matching to glob wildcard patterns (* and ?)
  • Prompts extracted from inline strings into domain-specific BasePrompt subclasses
  • authToken setting now supports string, profile array, or inline glob array formats
  • Module config restructured with slowSQL, slowRequests, slowHTTP, enablePoolLatencyTracking, and heapDumpDir settings
  • Utility code encapsulated into dedicated utility classes
  • AGENTS.md and skill definitions updated with bxmcp-tool-development skill

1.0.0 - 2026-05-16

  • First iteration of this module

$ box install bx-mcp

No collaborators yet.
     
  • {{ getFullDate("2026-05-15T13:56:17Z") }}
  • {{ getFullDate("2026-06-11T14:55:50Z") }}
  • 408
  • 203