Diagnostic capture keeps recent application evidence in memory so an authorized operator can inspect a running process. Attach it during application composition, then publish only the owner-provided tools your operators need. Capture does not mount an endpoint, install authentication, or turn REST routes into MCP tools.
Start with your existing application composition and MCP server. Transport construction and client setup stay there; exporter configuration stays in Telemetry.
Attach Capture
Inside the composition callback passed to app.Start or app.Run, obtain the
application handles you will use and attach capture once. Here composer is the
callback’s *application.Composer, with application imported from
arkoren.dev/core/application:
logger := composer.App().Logger()
telemetry := composer.App().Telemetry()
tools, err := composer.MCPTools("app")
composer.Require(err)
The result is []mcp.Tool, not a handler. composer.Require stops composition
on error before those definitions are used. The nonempty prefix app names the
tools directly: app.info, app.logs, and app.traces, for example. Their CLI
group is also app.
Application span, metric, and log recording becomes active after successful
composition and before Starting listeners and startup callbacks. Handles
obtained earlier still reach that recording. Event metadata capture begins when
the listener is attached, so it can also observe events during composition.
A valid span context can supply log correlation IDs before startup without
enabling capture recording.
If you configured application telemetry, capture observes that backend’s trace IDs without replacing it. Otherwise the application enables local recording at startup. Attaching capture does not itself start the primary telemetry driver, configure an exporter, or change process-wide logging and telemetry defaults. The application manages capture with its lifecycle.
Call the factory once per application. Every call attaches another capture;
declaration errors can occur after attachment without rollback. Do not retry
blindly. Calls outside synchronous composition return
application.ErrInvalidPhase; an empty prefix is rejected before attachment.
Bound Storage
New capture retains up to 2000 finished spans, 5000 logs, 1000 distinct label combinations per metric instrument, and 500 event records. These are count limits, not a byte budget: application log text and attributes still affect memory use. Capture is process-local evidence, not a durable audit log.
If you need a smaller log window, replace the preceding attachment with this alternative; do not call both:
tools, err := composer.MCPTools("app", func(tools *application.MCPToolsBuilder) {
tools.Limits(application.CaptureLimits{Logs: 1000})
})
composer.Require(err)
Zero fields select the defaults. Negative fields disable that signal’s
retention; a negative Events also omits the events tool. Other diagnostic tools
remain available even with retention disabled. If the application already uses
memory telemetry, capture reuses its capacities rather than resizing it.
Events retain names, payload types, and trace IDs, never payload values. Spans appear only after they finish. Eviction, reset, and process replacement lose history; raising a limit later cannot recover it. The retention contract also describes standalone stores. Review Telemetry Privacy before adding application-specific messages or attributes.
Select Owners
Use the router and scheduler that already serve your application. Here public
is your *router.Router from arkoren.dev/core/http/router, and scheduler is
your *schedule.Scheduler from arkoren.dev/core/service/schedule:
tools = append(tools, public.MCPTools("public")...)
tools = append(tools, scheduler.MCPTools("jobs")...)
These factories neither start their owners nor register listeners. Distinct prefixes avoid name collisions between instances. The owner prefixes reference gives the exact protocol names and default CLI groups.
For an inspection-only endpoint, select read-only definitions before registering
them. Import mcp from arkoren.dev/core/mcp; validate every definition so an
invalid declaration cannot disappear during filtering:
var selected []mcp.Tool
for _, tool := range tools {
composer.Require(tool.Err())
if tool.Describe().Annotations.ReadOnly {
selected = append(selected, tool)
}
}
This excludes the scheduler’s run action. The selection trusts these shipped
owner definitions; annotations themselves are not authorization. Even a
read-only health tool can execute dependency checks when called with fresh.
If different callers need different capabilities, apply
tool.WithAvailability(policy) to copies before registration. The application
supplies that policy from its authenticated operator identity. Availability
controls discovery and invocation, not access to an individual resource. Keep
resource checks in shared typed application handlers; see Availability and
Authorization.
Manual scheduler runs execute application code and bypass driver-owned overlap guards. Leave
rununregistered unless you explicitly authorize that capability and establish overlap and duplicate-effect safety. Never retry it automatically after a lost response.
Protect Registration
Protect the endpoint before making the tools reachable. Diagnostic reads reveal source paths, handler identities, log text, telemetry attributes, and possibly approved health error details. Restrict access to authorized operators and protect any saved output as well as the live endpoint.
In your existing mcpserver.New callback, register selected with the shared
application handles obtained above. Here listener is the
*mcpserver.Builder from arkoren.dev/driver/mcp/mcpserver:
listener.Tools(selected...)
listener.Logger(logger)
listener.Telemetry(telemetry)
Keep the admin listener private, authenticate and admit requests before the
/mcp mount, and apply the Host/Origin and TLS controls in
Securing MCP. A loopback listener with an authenticated
tunnel limits reachability, but the tunnel does not replace endpoint
authentication. Tool construction creates no inspection token or access policy.
Keep application HealthDetails disabled unless every affected surface is
operator-protected. Enabling it exposes check error text through MCP health,
fail-fast details, and verbose HTTP readiness; it is not a per-endpoint permission.
Verify Exposure
After starting the application, use an authenticated CLI connection to inspect the published catalog:
arkoren tools --json
Confirm that only the intended tools appear for that operator. Then check the process identity and the existing router:
arkoren app:info
arkoren public:routes
The identity should match the intended process, and the routes should match the live router. If a tool is absent, check registration, selection, and caller availability before changing names. Continue with Application Diagnosis to investigate a request using retained evidence.
For factory settings, see the application API.