BoxLang 🚀 A New JVM Dynamic Language Learn More...
|:------------------------------------------------------: |
| ⚡︎ 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 server auto-registers with the bx-ai module and
exposes an endpoint at /~bxmcp/boxlang.bxm.
box install bx-mcp
Or use the module installer appropriate to your runtime as described in the Module Installation Guide.
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.
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.
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,
"includedTools": ["*"],
"excludedTools": []
}
}
}
}
| Setting | Type | Default | Description |
|---|---|---|---|
enabled
| boolean | true
| Master switch. When false, the MCP server is
not registered at runtime. |
authToken
| string | ""
| Bearer token clients must send in the
Authorization header. Empty = no auth. |
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
| boolean | true
| Enable MCP server statistics tracking (tool call counts, timing). |
maxRequestBodySize
| numeric | 0
| Max HTTP request body size in bytes. 0 = no limit. |
includedTools
| array | ["*"]
| Tool whitelist. ["*"] = all tools.
Specific names = only those tools. |
excludedTools
| array | []
| Tool names to hide from the MCP client after the whitelist is applied. |
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.,
get_runtime_config, clear_all_caches,
reload_all_modules) from MCP clients.The server exposes tools across 12 runtime domains. Each tool is an
@mcpTool annotated method discovered automatically via
classpath scanning.
BoxLangTools
| Tool | Description |
|---|---|
get_runtime_info
| BoxLang version, JVM environment, OS details, start time, uptime |
get_runtime_config
| Full runtime configuration: datasources, caches, executors, logging, security, schedulers |
get_config_value
| Get a specific config value by dotted path (e.g. caches.default.provider) |
get_bif_summary
| BIF counts by category and sorted name list |
get_bif_info
| Detailed metadata for a specific BIF: signature, parameters, documentation |
search_bifs
| Search BIFs by keyword |
get_component_summary
| All registered components with total count |
get_component_info
| Metadata for a specific component: methods, properties, inheritance |
search_components
| Search components by keyword |
get_global_services
| All registered global runtime services |
toggle_debug_mode
| Toggle BoxLang debug mode on/off |
get_class_resolver_info
| Class resolver prefixes, cache size, dynamic class loader count |
clear_system_cache
| Clear compiled class caches (template, function, component, etc.) |
clear_page_pool
| Clear the Boxpiler page pool of compiled class instances |
JVMTools
| Tool | Description |
|---|---|
get_memory_info
| Heap and non-heap memory: used, committed, max, free, percent used |
get_memory_pool_details
| Memory pool breakdown: Eden, Survivor, Old Gen, Metaspace, Code Cache |
get_thread_info
| Thread counts: total, daemon, peak, started, by state |
get_thread_dump
| Full JVM thread dump with stack traces |
get_cpu_info
| Available processors, system load average, process CPU time |
get_gc_info
| GC algorithm statistics: collection count, cumulative collection time |
trigger_gc
| Manually trigger a garbage collection; returns before/after memory stats |
get_class_loading_info
| Currently loaded, total loaded, and total unloaded class counts |
get_jvm_runtime_info
| JVM name, vendor, version, uptime |
get_system_properties
| All JVM system properties |
get_environment_variables
| JVM environment variables (sensitive values masked) |
get_operating_system_info
| OS name, version, architecture, available processors |
CacheTools
| Tool | Description |
|---|---|
get_caches
| All registered cache providers with stats, configuration, status |
get_cache_names
| Cache provider names only |
get_cache_stats
| Detailed cache stats: hits, misses, evictions, performance ratio |
get_cache_keys
| All keys stored in a specific cache |
get_cache_size
| Number of elements in a specific cache |
get_cache_key_metadata
| Metadata for a specific cached object |
cache_key_exists
| Check if a key exists in a cache |
get_store_metadata_report
| Full store metadata report for a cache |
clear_all
| Clear all elements from a specific cache |
clear_item
| Remove a specific item from a cache |
reap_cache
| Reap (clean up expired entries) from a cache |
clear_cache_stats
| Reset hit/miss/eviction counters for a cache |
clear_all_caches
| Clear all elements from every registered cache |
reap_all_caches
| Reap expired entries from every registered cache |
get_cache_health_summary
| Health overview: total size, hit rates, status across all caches |
DatasourceTools
| Tool | Description |
|---|---|
get_datasources
| All registered datasources with configurations and pool metrics |
get_datasource_names
| Datasource names only |
get_datasource
| Single datasource details with pool metrics |
has_datasource
| Check if a datasource is registered |
get_pool_metrics
| Connection pool metrics: active, idle, total connections, wait times |
get_datasource_config
| Datasource configuration (passwords masked) |
test_datasource
| Test a datasource connection; returns success/failure with timing |
get_datasource_health
| Health summary of all datasources and their pools |
AsyncTools
| Tool | Description |
|---|---|
get_executors
| All registered async executors with status, pool info, task stats |
get_executor_names
| Executor names only |
get_executor_info
| Detailed executor info: type, status, configuration |
get_executor_stats
| Pool utilization, queue status, task counts, health metrics |
get_executor_health
| Health report with issues, recommendations, alerts |
get_executor_health_summary
| Health summary across all executors |
SchedulerTools
| Tool | Description |
|---|---|
get_schedulers
| All registered schedulers with configurations and tasks |
get_scheduler_names
| Scheduler names only |
get_scheduler
| Single scheduler details including tasks and records |
has_scheduler
| Check if a scheduler is registered |
get_task_stats
| Execution statistics for a specific task |
get_task_info
| Task details: configuration and metadata |
get_all_tasks
| All tasks across all schedulers |
run_task
| Force-run a scheduled task immediately |
pause_task
| Pause a scheduled task |
resume_task
| Resume a paused scheduled task |
pause_persisted_task
| Pause a disk-persisted task (updates tasks.json) |
resume_persisted_task
| Resume a disk-persisted task |
pause_all_persisted_tasks
| Pause all disk-persisted tasks (filterable by scheduler/group) |
resume_all_persisted_tasks
| Resume all disk-persisted tasks |
get_scheduler_health
| Health summary of all schedulers and tasks |
get_all_task_stats
| Task stats summary across all schedulers |
get_persisted_tasks
| All scheduled tasks persisted on disk (tasks.json) |
ModuleTools
| Tool | Description |
|---|---|
get_modules
| All registered modules with configuration and status |
get_module_names
| Module names only |
get_module_info
| Full configuration and status for a specific module |
get_module_settings
| Settings for a specific module |
get_module_paths
| Registered module search paths |
reload_module
| Reload a specific module (unload, re-register, re-activate) |
reload_all_modules
| Reload all registered modules |
has_module
| Check if a module is registered |
get_module_stats
| Module statistics: total count, activated, enabled, etc. |
InterceptorTools
| Tool | Description |
|---|---|
get_interception_points
| All registered interception point names (sorted) |
has_interception_point
| Check if a specific interception point is registered |
get_interceptor_states
| All interceptor states with listener counts |
get_interceptor_state
| Listener count for a specific event |
get_interceptor_summary
| Registry totals, active states, events with most listeners |
ApplicationTools
| Tool | Description |
|---|---|
get_application_names
| Active application names |
get_applications
| All active applications: start times, session counts, expiry status |
get_application
| Full runtime details for a specific application |
has_application
| Check if an application is active |
get_application_summary
| Summary: totals, session load, expired apps in registry |
stop_application
| Shut down a running application by name |
LoggingTools
| Tool | Description |
|---|---|
get_logging_info
| Log directory, logger count, appender count |
get_logging_config
| Log levels, appenders, retention policies |
get_loggers
| All registered loggers with names and appenders |
get_logger
| Details for a specific logger |
get_root_logger
| Root logger details and attached appenders |
get_appenders
| All registered appenders: file paths, types, configuration |
read_log_entries
| Last N log entries from a log file |
get_last_error
| Most recent ERROR or FATAL entry from a logger |
search_log_entries
| Search log entries by keyword or pattern |
log_message
| Write a test log message (verify logging works) |
HttpTools
| Tool | Description |
|---|---|
get_http_client_count
| Number of active HTTP clients |
get_http_client_names
| HTTP client keys |
get_http_clients
| Per-client stats: connection counts, request counts, error rates |
get_soap_clients
| Per-WSDL SOAP client usage details |
get_http_executor
| HTTP executor thread pool status and configuration |
get_http_service_summary
| Consolidated HTTP service summary |
WatcherTools
| Tool | Description |
|---|---|
get_watchers
| All registered filesystem watchers with configuration and state |
get_watcher_names
| Watcher names only |
get_watcher
| Single watcher details |
has_watcher
| Check if a watcher is registered |
get_watcher_stats
| Watcher execution statistics |
start_watcher
| Start a stopped watcher |
stop_watcher
| Stop a running watcher |
restart_watcher
| Restart a watcher |
remove_watcher
| Remove a watcher from the registry and stop it |
get_watcher_health
| Health summary of all watchers |
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.
| 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, 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 misconfiguration | threshold
(optional, default: 80)
|
executor_saturation_check
| Async executor pool saturation, queue buildup, and rejected tasks | — |
| Prompt | Description | Arguments |
|---|---|---|
analyze_cache_performance
| Cache hit rates, eviction patterns, sizing; optionally focus on a named cache | cacheName
(optional)
|
datasource_health_report
| Datasource connectivity, connection pool utilization, configuration audit | — |
| 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, fixes | loggerName, 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 | — |
| 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, failures | schedulerName
(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 | — |
| Prompt | Description | Arguments |
|---|---|---|
bif_component_discovery
| Explore available BIFs and components; search by keyword | keyword
(optional)
|
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-tokenwith the value ofauthTokenfrom your module settings. IfauthTokenis empty, omit theheadersblock.
Selectively expose only the tools you need:
{
"modules": {
"bxmcp": {
"settings": {
"includedTools": [
"get_runtime_info",
"get_memory_info",
"get_schedulers"
]
}
}
}
}
Or exclude sensitive admin tools:
{
"modules": {
"bxmcp": {
"settings": {
"includedTools": ["*"],
"excludedTools": [
"clear_all_caches",
"reload_all_modules",
"stop_application"
]
}
}
}
}
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" ).
// 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()
)
)
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 }
]
)
The server supports several registration patterns:
server.scan(
"myapp.tools" ) to auto-discover methods
annotated with @mcpTool
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( "get_runtime_info" )
writeOutput( tool.getDescription() )
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 ) )
All interactions use JSON-RPC 2.0 over HTTP POST to /~bxmcp/index.bxm.
Replace
http://localhost:8080with your server URL. AddAuthorization: Bearer {token}ifauthTokenis configured.
curl -s http://localhost:8080/~bxmcp/index.bxm \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"tools/list","id":"1"}' | jq '.result.tools[] | {name, description}'
curl -s http://localhost:8080/~bxmcp/index.bxm \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"get_runtime_info","arguments":{}},"id":"2"}' | jq '.result.content[0].text | fromjson'
curl -s http://localhost:8080/~bxmcp/index.bxm \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"get_memory_info","arguments":{}},"id":"3"}' | jq '.result.content[0].text | fromjson'
curl -s http://localhost:8080/~bxmcp/index.bxm \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"get_thread_dump","arguments":{}},"id":"4"}' | jq '.result.content[0].text | fromjson'
curl -s http://localhost:8080/~bxmcp/index.bxm \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"get_cache_health_summary","arguments":{}},"id":"5"}' | jq '.result.content[0].text | fromjson'
curl -s http://localhost:8080/~bxmcp/index.bxm \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"get_datasource_health","arguments":{}},"id":"6"}' | jq '.result.content[0].text | fromjson'
curl -s http://localhost:8080/~bxmcp/index.bxm \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"test_datasource","arguments":{"dsn":"mainDB"}},"id":"7"}' | jq '.result.content[0].text | fromjson'
curl -s http://localhost:8080/~bxmcp/index.bxm \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"get_modules","arguments":{}},"id":"8"}' | jq '.result.content[0].text | fromjson'
curl -s http://localhost:8080/~bxmcp/index.bxm \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"search_log_entries","arguments":{"loggerName":"runtime","keyword":"error","limit":20}},"id":"9"}' | jq '.result.content[0].text | fromjson'
curl -s http://localhost:8080/~bxmcp/index.bxm \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"get_schedulers","arguments":{}},"id":"10"}' | jq '.result.content[0].text | fromjson'
Tip: Pipe through
jqto extract and parse the JSON response. The MCP server wraps tool results insideresult.content[0].textas a JSON-encoded string.
curl -s http://localhost:8080/~bxmcp/index.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
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
"I am the way, and the truth, and the life; no one comes to the Father, but by me (JESUS)" Jn 14:1-12
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
$
box install bx-mcp