Skip to main content

Agent Server

Agent Server is a disabled-by-default n3 plugin. It exposes a localhost-only HTTP API for agent and client development on a Java 11 HttpServer bound to 127.0.0.1. v1 has no bearer token, so localhost-only does not protect you from other local processes.

Runtime Model

  • Config group: n3agentserver.
  • Default bind: 127.0.0.1:17631.
  • Direct MCP endpoint: POST /mcp using Streamable HTTP without SSE. GET /mcp returns 405.
  • The sidebar panel shows bind address, port, running state, request count, last error, and plugin-operation availability.
  • Read endpoints snapshot live client state on the RuneLite client thread.
  • Gameplay write endpoints route through InteractionApi.actions.* and return InteractionResult-backed JSON.
  • Agent Server does not request or enforce account setup. Gameplay writes dispatch directly to their typed action and report that action's InteractionResult. Plugins that need account settings must declare and enforce their own requirements.
  • Clients must avoid tight retry loops. Treat PACED and failure responses as pacing signals and retry with randomized/backoff behavior.
  • Plugin operations cover all loaded RuneLite plugins. PacketUtilsPlugin is listed and readable but cannot be disabled because it owns shared suite runtime state.
  • /mcp allows missing Origin for non-browser clients and localhost browser origins only.

JSON Envelopes

Read success:

{ "ok": true, "status": "ok", "data": {} }

Write success or failure:

{
"ok": true,
"status": "SUCCESS",
"message": "Queued dialog continue",
"result": { "status": "SUCCESS" }
}

Errors:

{
"ok": false,
"status": "PACED",
"message": "Action pacing is active"
}

Endpoints

The machine-readable contracts are maintained in both JSON and YAML. The documentation audit requires those two representations to describe the same operations and requires every documented operation to exist in the router. Import either file into Swagger Editor, ReDoc, or an OpenAPI client generator; use http://127.0.0.1:17631 as the local server URL.

For example:

curl.exe http://127.0.0.1:17631/api/v1/state
curl.exe -X POST http://127.0.0.1:17631/api/v1/walk `
-H "Content-Type: application/json" `
-d '{"x":3222,"y":3222,"plane":0}'

Read endpoints:

  • GET /api/v1/state
  • GET /api/v1/stream/status
  • GET /api/v1/navigation/status
  • GET /api/v1/login/modes
  • GET /api/v1/login/status
  • GET /api/v1/widgets/list
  • GET /api/v1/widgets/search?text=...&action=...&limit=...
  • GET /api/v1/widgets/describe?widgetId=...
  • GET /api/v1/inventory
  • GET /api/v1/players
  • GET /api/v1/npcs
  • GET /api/v1/objects (player-nearest objects first, then the requested limit)
  • GET /api/v1/ground-items
  • GET /api/v1/skills
  • GET /api/v1/developer/metrics for a structured developer snapshot including world, player position, skills, inventory, bank state, session/account context, and optional screenshot capture.
  • GET /api/v1/bank/status for bank-open status.
  • GET /api/v1/bank for the bank item snapshot.
  • GET /api/v1/plugins
  • GET /api/v1/plugins/status
  • GET /api/v1/plugins/config?className=...
  • GET /api/v1/plugins/configs
  • GET /api/v1/plugins/logs?className=...&limit=...
  • GET /api/v1/menu-entries
  • GET /api/v1/last-interactions
  • GET /api/v1/varbit?id=...
  • GET /api/v1/varplayer?id=...
  • GET /api/v1/varbit-changes
  • GET /api/v1/suite/capabilities for the current coverage catalog across REST, direct MCP, SDK docs, typed read/write domains, and read-only SDK helpers.
  • GET /api/v1/sdk/read?method=... for simple allowlisted read-only SDK helper calls. Use POST /api/v1/sdk/read when the helper needs structured arguments.
  • GET /api/v1/world
  • GET /api/v1/world-map
  • GET /api/v1/camera
  • GET /api/v1/line-of-sight?fromX=...&fromY=...&fromPlane=...&toX=...&toY=...&toPlane=...
  • GET /api/v1/item-metadata?itemId=...
  • GET /api/v1/prices?itemId=...
  • GET /api/v1/social
  • GET /api/v1/progress?quest=...
  • GET /api/v1/recent-events
  • GET /api/v1/questhelper
  • GET /api/v1/production
  • GET /api/v1/minigames
  • GET /api/v1/loadout/state

Write endpoints:

  • POST /api/v1/widgets/click with widgetId, optional dynamic-child index from widget list/search results, optional action/actions, or raw op. Supply index when multiple live widgets share a packed ID. Prefer named actions; raw op is a live-debug escape hatch for actionless widgets, not the default automation style.
  • POST /api/v1/inventory/interact with name, id, or index, plus optional action/actions.
  • POST /api/v1/drop with name, id, or index.
  • POST /api/v1/npcs/interact with name, id, or index, plus optional action/actions.
  • POST /api/v1/objects/interact with name or id, plus optional action/actions.
  • POST /api/v1/ground-items/pickup with name or id, plus optional action/actions.
  • POST /api/v1/walk with x, y, optional plane, optional reachedDistance, and optional cancelOnNewTarget (default true). Send {"cancel":true} to cancel the active walker path. The endpoint starts or reuses a walker path and stays non-blocking; poll GET /api/v1/state for progress.
  • POST /api/v1/navigation/preview with x, y, and optional plane to inspect a path without starting movement.
  • POST /api/v1/login/profile/apply, POST /api/v1/login/start, and POST /api/v1/login/clear manage memory-only dashboard login profiles. Status responses never include secrets, and login attempts are capped until the profile is cleared or reapplied.
  • POST /api/v1/bank/open.
  • POST /api/v1/deposit.
  • POST /api/v1/withdraw with name or id, amount, and optional noted.
  • POST /api/v1/dialogue/continue.
  • POST /api/v1/dialogue/select with index or text.
  • POST /api/v1/developer/heartbeat with optional webhookUrl, secret, and includeScreenshot to publish a developer metrics heartbeat payload.
  • POST /api/v1/plugins/enable with className.
  • POST /api/v1/plugins/disable with className.
  • POST /api/v1/plugins/config/set with className, key, and value.
  • POST /api/v1/plugins/config/unset with className and key.
  • POST /api/v1/use-item/item with sourceId/targetId or sourceName/targetName.
  • POST /api/v1/use-item/npc with sourceId and npcName.
  • POST /api/v1/use-item/object with sourceId or sourceName, plus objectName.
  • POST /api/v1/use-item/ground-item with sourceId and groundItemId.
  • POST /api/v1/sdk/read with method and any helper-specific arguments. Only explicit read-only SDK helper ids are accepted; mutating helpers and gameplay actions are rejected.
  • POST /api/v1/ge/open, /api/v1/ge/close, /api/v1/ge/collect, and /api/v1/ge/cancel.
  • POST /api/v1/shop/buy with name or id, plus optional quantity of 1, 5, 10, or 50.
  • POST /api/v1/trade/accept, /api/v1/trade/decline, and /api/v1/trade/offer.
  • POST /api/v1/equipment/equip and /api/v1/equipment/unequip.
  • POST /api/v1/prayer/set, /api/v1/prayer/set-only, /api/v1/prayer/disable-all, /api/v1/prayer/quick-toggle, /api/v1/prayer/quick-open, and /api/v1/prayer/quick-set.
  • POST /api/v1/magic/cast, /api/v1/magic/select, and /api/v1/magic/deselect.
  • POST /api/v1/combat/toggle-spec, /api/v1/combat/set-attack-style, and /api/v1/combat/auto-retaliate.
  • POST /api/v1/tab/open.
  • POST /api/v1/production/choose, /api/v1/production/quantity, and /api/v1/production/amount.
  • POST /api/v1/transport/travel with a supported transport type and destination enum name.
  • POST /api/v1/deposit-box/deposit-all, /api/v1/deposit-box/deposit-equipment, /api/v1/deposit-box/deposit, and /api/v1/deposit-box/close.
  • POST /api/v1/bank-inventory/deposit.
  • POST /api/v1/bank-worn-equipment/deposit-all.
  • POST /api/v1/drop-pattern.

Direct MCP Endpoint

/mcp implements MCP Streamable HTTP in non-SSE mode for local agents that can connect directly to the RuneLite plugin:

  • initialize, ping, tools/list, and tools/call return JSON-RPC responses with Content-Type: application/json.
  • notifications/initialized and accepted JSON-RPC notifications return HTTP 202 with no body.
  • GET /mcp returns HTTP 405 because Agent Server does not expose an SSE stream.
  • Protocol failures return JSON-RPC errors. Gameplay and business-logic failures return MCP tool results with isError: true and structured Agent Server or InteractionResult details.
  • SDK documentation tools use the Storm-style names search, get_class, get_method, list_packages, list_classes, and get_examples. Runtime client tools use the n3_ prefix.

Direct MCP adds Storm-style SDK documentation tools: search, get_class, get_method, list_packages, list_classes, and get_examples. It also keeps n3_describe_api, n3_search_api_docs, and n3_read_api_doc for runtime tool discovery and stable-id reads. n3_describe_api returns transport/tool metadata plus an sdk object with schemaVersion, indexVersion, generatedAt, coverage counts, capabilities, recommended ingestion flow, packages, topics, supported docs tools, and stable id formats. The SDK/API index is generated at build time from src/main/java/com/n3plugins/sdk and src/main/java/com/n3plugins/InteractionApi with the JDK compiler tree/doc APIs, then packaged as com/n3plugins/agentserver/mcp/sdk-index.json. Runtime loads that JSON first; packaged source resources remain a fallback only. n3_read_api_doc reads ids such as class:com.n3plugins.InteractionApi.actions.InventoryActions, method:com.n3plugins.InteractionApi.actions.InventoryActions#use(int,java.lang.String...), field:<fqcn>#<name>, enumConstant:<fqcn>#<name>, package:<package>, and topic:banking. Simple compatibility method ids such as method:<fqcn>#<name> still resolve and return overloads when ambiguous. Packaged fallback docs live under src/main/resources/com/n3plugins/agentserver/mcp/docs/. It also adds screenshot tools: n3_capture_screenshot copies the current RuneLite buffer-provider pixels into PNG MCP image content plus structured metadata, and n3_get_last_screenshot returns the latest in-memory capture only. Screenshots are never written to disk. n3_get_suite_capabilities reports practical suite coverage by domain. n3_read_sdk is a restricted generic read-only SDK helper invoker: it accepts only explicit allowlisted static read helpers, dispatches client-thread reads where needed, rejects mutating/action methods, and does not replace typed InteractionResult tools for gameplay writes.

Plugin Operations

Agent Server replaces Microbot-style script lifecycle endpoints with plugin operations. It lists and controls loaded plugins from RuneLite PluginManager.getPlugins() rather than a configured allowlist. PacketUtilsPlugin can be inspected, enabled, and read for config/log data, but disable requests are refused because it owns revision setup, bootstrap, pacing, walker ticking, and branding.

Plugin config endpoints are scoped to the target plugin config group. set and unset accept only keys that belong to the plugin descriptor or are already stored under that plugin group, so callers cannot write arbitrary cross-plugin config groups through these endpoints.

Plugin logs are live-buffer only. Agent Server captures recent SLF4J/Logback events while it is running and filters by the target plugin class/package; it does not read historical RuneLite log files from disk.

MCP Bridge

tools/agent-mcp provides a local MCP stdio bridge for agents that support tool calling. The MCP process is not a RuneLite plugin and does not bypass Agent Server. It calls the same localhost HTTP endpoints above and returns the Agent Server JSON envelope as both MCP text content and structured content. It remains REST-backed for compatibility and is separate from the direct /mcp endpoint.

Setup:

cd tools\agent-mcp
npm install
npm run build

Example MCP client registration:

{
"mcpServers": {
"n3-agent": {
"command": "node",
"args": ["<repo-root>/tools/agent-mcp/dist/index.js"],
"env": {
"N3_AGENT_SERVER_URL": "http://127.0.0.1:17631"
}
}
}
}

The bridge intentionally exposes REST-backed runtime tools only. SDK documentation/search tools (search, get_class, get_method, list_packages, list_classes, get_examples, n3_describe_api, n3_search_api_docs, and n3_read_api_doc) are available on direct /mcp, not through the bridge. Runtime read tools include the state/widget/scene/plugin/menu/varbit tools plus n3_get_suite_capabilities, n3_read_sdk, n3_get_world, n3_get_world_map, n3_get_camera, n3_get_line_of_sight, n3_get_item_metadata, n3_get_prices, n3_get_social, n3_get_progress, n3_get_recent_events, n3_get_questhelper, n3_get_production, n3_get_minigames, and n3_get_loadout_state. Command tools are named after the matching endpoint, including n3_walk, n3_click_widget, n3_interact_inventory, dialogue/plugin/config commands, n3_use_item_on_*, GE, shop, trade, equipment, prayer, magic, combat, tab, production, transport, deposit-box, bank-inventory, bank-worn-equipment, and inventory drop-pattern commands.

The MCP bridge does not retry commands. Treat PACED, not_ready, and failed InteractionResult statuses as live pacing or readiness signals.

GET /api/v1/state includes a navigation object for polling active walks:

  • activeGoal: requested target point, when one is tracked.
  • reachedDistance: accepted radius for a walkNear/Agent Server walk request.
  • pathSize: current tracked path size.
  • state: active WalkerStatus name or IDLE.
  • distanceToDestination: player distance to the tracked target, or -1 when unavailable.
  • playerPosition: current local-player world point when available.

Verification

Automated tests cover request parsing, JSON envelope shape, bootstrap-free action dispatch, global plugin control rules, plugin config scoping, live log buffering, direct MCP lifecycle/tool behavior, screenshot cache behavior, SDK/doc lookup, and MCP bridge request mapping. Live RuneLite verification is still required for endpoint behavior that depends on widgets, scene state, banking, walking, screenshots, item-on-target actions, or plugin manager runtime state.

Recorded read-only evidence

DateClient setupProbeExpectedObservedEvidence
2026-07-10RuneLite 1.12.32, revision 239, logged in, Agent Server enabledn3_get_stateHealthy revision, ready bootstrap, structured navigation/runtime stateRevision 239 healthy; bootstrap ready; walker IDLE; player/world state returnedDirect /mcp tool result
2026-07-10Same clientn3_get_suite_capabilitiesREST, direct MCP, SDK-doc, typed-read, and typed-write catalogsAll catalogs returned; route lists matched the refreshed OpenAPI surfaceDirect /mcp tool result
2026-07-10Same clientn3_describe_apiGenerated overload-safe SDK index is activesource_indexed, schema 1, index 5.5, 296 classes and 2,493 methodsDirect /mcp tool result
2026-07-10Same clientn3_get_pluginsCurrent plugin descriptors are discoverableAgent Server, API Tester, Bank Stander, Packet Utils, and other registered plugins returned with config groups and statusDirect /mcp tool result

These probes establish the read/discovery claims only. To accept a write-domain claim, execute the matching endpoint in a controlled account state, record the request and InteractionResult, and confirm the expected widget, inventory, scene, bank, navigation, or plugin-state change. Do not infer those outcomes from the read-only evidence above.