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 /mcpusing Streamable HTTP without SSE.GET /mcpreturns 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 returnInteractionResult-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
PACEDand failure responses as pacing signals and retry with randomized/backoff behavior. - Plugin operations cover all loaded RuneLite plugins.
PacketUtilsPluginis listed and readable but cannot be disabled because it owns shared suite runtime state. /mcpallows missingOriginfor 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/stateGET /api/v1/stream/statusGET /api/v1/navigation/statusGET /api/v1/login/modesGET /api/v1/login/statusGET /api/v1/widgets/listGET /api/v1/widgets/search?text=...&action=...&limit=...GET /api/v1/widgets/describe?widgetId=...GET /api/v1/inventoryGET /api/v1/playersGET /api/v1/npcsGET /api/v1/objects(player-nearest objects first, then the requested limit)GET /api/v1/ground-itemsGET /api/v1/skillsGET /api/v1/developer/metricsfor a structured developer snapshot including world, player position, skills, inventory, bank state, session/account context, and optional screenshot capture.GET /api/v1/bank/statusfor bank-open status.GET /api/v1/bankfor the bank item snapshot.GET /api/v1/pluginsGET /api/v1/plugins/statusGET /api/v1/plugins/config?className=...GET /api/v1/plugins/configsGET /api/v1/plugins/logs?className=...&limit=...GET /api/v1/menu-entriesGET /api/v1/last-interactionsGET /api/v1/varbit?id=...GET /api/v1/varplayer?id=...GET /api/v1/varbit-changesGET /api/v1/suite/capabilitiesfor 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. UsePOST /api/v1/sdk/readwhen the helper needs structured arguments.GET /api/v1/worldGET /api/v1/world-mapGET /api/v1/cameraGET /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/socialGET /api/v1/progress?quest=...GET /api/v1/recent-eventsGET /api/v1/questhelperGET /api/v1/productionGET /api/v1/minigamesGET /api/v1/loadout/state
Write endpoints:
POST /api/v1/widgets/clickwithwidgetId, optional dynamic-childindexfrom widget list/search results, optionalaction/actions, or rawop. Supplyindexwhen multiple live widgets share a packed ID. Prefer named actions; rawopis a live-debug escape hatch for actionless widgets, not the default automation style.POST /api/v1/inventory/interactwithname,id, orindex, plus optionalaction/actions.POST /api/v1/dropwithname,id, orindex.POST /api/v1/npcs/interactwithname,id, orindex, plus optionalaction/actions.POST /api/v1/objects/interactwithnameorid, plus optionalaction/actions.POST /api/v1/ground-items/pickupwithnameorid, plus optionalaction/actions.POST /api/v1/walkwithx,y, optionalplane, optionalreachedDistance, and optionalcancelOnNewTarget(defaulttrue). Send{"cancel":true}to cancel the active walker path. The endpoint starts or reuses a walker path and stays non-blocking; pollGET /api/v1/statefor progress.POST /api/v1/navigation/previewwithx,y, and optionalplaneto inspect a path without starting movement.POST /api/v1/login/profile/apply,POST /api/v1/login/start, andPOST /api/v1/login/clearmanage 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/withdrawwithnameorid,amount, and optionalnoted.POST /api/v1/dialogue/continue.POST /api/v1/dialogue/selectwithindexortext.POST /api/v1/developer/heartbeatwith optionalwebhookUrl,secret, andincludeScreenshotto publish a developer metrics heartbeat payload.POST /api/v1/plugins/enablewithclassName.POST /api/v1/plugins/disablewithclassName.POST /api/v1/plugins/config/setwithclassName,key, andvalue.POST /api/v1/plugins/config/unsetwithclassNameandkey.POST /api/v1/use-item/itemwithsourceId/targetIdorsourceName/targetName.POST /api/v1/use-item/npcwithsourceIdandnpcName.POST /api/v1/use-item/objectwithsourceIdorsourceName, plusobjectName.POST /api/v1/use-item/ground-itemwithsourceIdandgroundItemId.POST /api/v1/sdk/readwithmethodand 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/buywithnameorid, plus optionalquantityof1,5,10, or50.POST /api/v1/trade/accept,/api/v1/trade/decline, and/api/v1/trade/offer.POST /api/v1/equipment/equipand/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/travelwith a supported transporttypeand 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, andtools/callreturn JSON-RPC responses withContent-Type: application/json.notifications/initializedand accepted JSON-RPC notifications return HTTP 202 with no body.GET /mcpreturns 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: trueand structured Agent Server orInteractionResultdetails. - SDK documentation tools use the Storm-style names
search,get_class,get_method,list_packages,list_classes, andget_examples. Runtime client tools use then3_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.
Navigation State
GET /api/v1/state includes a navigation object for polling active walks:
activeGoal: requested target point, when one is tracked.reachedDistance: accepted radius for awalkNear/Agent Server walk request.pathSize: current tracked path size.state: activeWalkerStatusname orIDLE.distanceToDestination: player distance to the tracked target, or-1when 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
| Date | Client setup | Probe | Expected | Observed | Evidence |
|---|---|---|---|---|---|
| 2026-07-10 | RuneLite 1.12.32, revision 239, logged in, Agent Server enabled | n3_get_state | Healthy revision, ready bootstrap, structured navigation/runtime state | Revision 239 healthy; bootstrap ready; walker IDLE; player/world state returned | Direct /mcp tool result |
| 2026-07-10 | Same client | n3_get_suite_capabilities | REST, direct MCP, SDK-doc, typed-read, and typed-write catalogs | All catalogs returned; route lists matched the refreshed OpenAPI surface | Direct /mcp tool result |
| 2026-07-10 | Same client | n3_describe_api | Generated overload-safe SDK index is active | source_indexed, schema 1, index 5.5, 296 classes and 2,493 methods | Direct /mcp tool result |
| 2026-07-10 | Same client | n3_get_plugins | Current plugin descriptors are discoverable | Agent Server, API Tester, Bank Stander, Packet Utils, and other registered plugins returned with config groups and status | Direct /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.