agentscope-ai / agentscope-ai/agentscope-java

Harness: preserve MCP client ownership across Toolkit.copy and close clients on agent shutdown

Aperta
#2,139 2 commenti 0 reazioni 0 assegnatari Vedi su GitHub
area/harness enhancement
Lingua principale
Java
Stelle
5.6k
Fork
1.3k
Merge medio
4g 12h
PR unite (30g)
77

Descrizione

## Problem

Harness registers workspace `tools.json` MCP clients into `agentToolkit`, then `ReActAgent.Builder` creates the final toolkit through `toolkit.copy()`. `Toolkit.copy()` copies registered tool functions/groups but not `McpClientManager` ownership. The final agent can invoke copied MCP tool functions, but it cannot enumerate or close the registrar-owned client.

`HarnessAgent.close()` shuts down the task repository/workspace index/delegate only; it does not close MCP clients. For stdio transport the child server process remains alive after runtime close.

Observed against `e3a412ed2cc944e401da861c8d5e464b967724e9` with a real JSON-RPC stdio fixture:

1. `tools.json -> McpServerRegistrar -> Toolkit` initializes and calls the fixture successfully.
2. `runtime.agent().getToolkit().removeMcpClient("fixture")` cannot remove the registrar client after the toolkit copy; the MCP tool and process remain.
3. `JCodeHarnessRuntime.close() -> HarnessAgent.close() -> ReActAgent.close()` leaves the fixture process alive.

## Expected ownership contract

The final Harness/agent lifecycle that exposes MCP tools must own the corresponding clients and close them exactly once.

Possible design:

- make `Toolkit` implement an explicit async close/close-all contract and expose a read-only client inventory;
- preserve client ownership across `Toolkit.copy()` using a shared reference-counted lifecycle owner, or avoid copying an already-registered MCP toolkit;
- ensure removing a client removes its tools/groups and closes its transport;
- call close-all from `HarnessAgent.close()` / final agent close;
- define ownership for parent/child toolkit copies so one child cannot close a client still used by another, while the last owner always closes it.

A public list plus application-side loops is insufficient if the final copied toolkit does not retain the original manager.

## Acceptance

1. Real stdio process exits after final Harness close.
2. `removeMcpClient(name)` on the final exposed toolkit removes tools and closes transport.
3. Parent/child toolkit copies have deterministic shared/isolated ownership and no double-close.
4. Failed or partially initialized registration closes the created client.
5. SSE/HTTP clients also close subscriptions/resources.
6. Repeated close is idempotent.
7. Product hosts need no client/process registry or PID cleanup.

The application-side fixture currently performs PID teardown only in test cleanup; no production workaround is installed because MCP lifecycle belongs to AgentScope Toolkit/Harness.

Guida per i contributori

Apri la guida per i contributori

Valutazione

Questa issue non è ancora stata valutata.

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.