Skip to content

Commit 11a4d71

Browse files
committed
feat(session): add force flag to delete attached sessions
1 parent 572c933 commit 11a4d71

2 files changed

Lines changed: 15 additions & 6 deletions

File tree

src/tools/session/delete-session.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
11
import { getSessionOwnership, safeDeleteSession } from '../../session-store.js';
22
import { errorResult, textResult, toolErrorMessage } from '../tool-response.js';
33

4-
export async function deleteSessionAction(sessionId?: string): Promise<any> {
4+
export async function deleteSessionAction(
5+
sessionId?: string,
6+
force?: boolean
7+
): Promise<any> {
58
const ownership = getSessionOwnership(sessionId);
69
if (!ownership) {
710
return errorResult(
811
sessionId ? `Session ${sessionId} not found.` : 'No active session found.'
912
);
1013
}
11-
if (ownership === 'attached') {
14+
if (ownership === 'attached' && !force) {
1215
return errorResult(
1316
sessionId
14-
? `Session ${sessionId} is attached from a remote server. Use action=detach to remove it from MCP without deleting the remote session.`
15-
: 'Active session is attached from a remote server. Use action=detach to remove it from MCP without deleting the remote session.'
17+
? `Session ${sessionId} is attached from a remote server. Use action=detach to remove it from MCP without deleting the remote session, or pass force=true to delete the remote session.`
18+
: 'Active session is attached from a remote server. Use action=detach to remove it from MCP without deleting the remote session, or pass force=true to delete the remote session.'
1619
);
1720
}
1821

src/tools/session/session.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ const schema = z.object({
4444
`create: ${CREATE_SESSION_DESCRIPTION}` +
4545
'attach: Attach MCP Appium to an existing remote Appium session without taking ownership of its lifecycle. Requires remoteServerUrl and sessionId. Always pass capabilities with at least platformName (e.g. \'{"platformName":"iOS"}\' or \'{"platformName":"Android"}\') so the client is configured with the correct protocol commands.' +
4646
'detach: Remove an attached Appium session from MCP Appium without deleting the real remote session. Defaults to the active session.' +
47-
'delete: Delete an MCP-owned mobile session and clean up resources. Does not delete attached remote sessions; use detach for those. If sessionId is omitted, deletes the active session.' +
47+
'delete: Delete an MCP-owned mobile session and clean up resources. Attached remote sessions are rejected unless force=true; use detach to drop attached sessions from MCP without terminating the remote session. If sessionId is omitted, deletes the active session.' +
4848
'list: List all active Appium sessions managed by this MCP server, including active flag, ownership, and current context.' +
4949
'select: Set an existing Appium session as the active session for subsequent tool calls (requires sessionId).'
5050
),
@@ -77,6 +77,12 @@ const schema = z.object({
7777
.describe(
7878
'For attach: existing session to connect to. For delete: session to remove (defaults to active). For detach: attached session to remove from MCP (defaults to active). For select: session to activate. Required for attach and select.'
7979
),
80+
force: z
81+
.boolean()
82+
.optional()
83+
.describe(
84+
'For delete only: when true, also terminate an attached remote Appium session. Defaults to false.'
85+
),
8086
});
8187

8288
export default function session(server: FastMCP): void {
@@ -139,7 +145,7 @@ export default function session(server: FastMCP): void {
139145
}
140146

141147
if (args.action === 'delete') {
142-
return deleteSessionAction(args.sessionId);
148+
return deleteSessionAction(args.sessionId, args.force);
143149
}
144150

145151
if (args.action === 'list') {

0 commit comments

Comments
 (0)