session-manager-mcp
Starts Claude Code sessions in isolated git worktrees and supports syncing a session's worktree with its base branch when git is available.
Checks on pull requests opened by sessions and provides pull request tools through the GitHub CLI (gh) when available.
Can act on live Claude Code sessions running under the Swttch JetBrains plugin, asking it to deliver messages, interrupt turns, switch models, and change permission modes.
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
@swttch/session-manager-mcp
An MCP server that lets one Claude Code session look after your other Claude Code sessions.
From inside a session you can ask Claude to list and search your sessions, read what another one did, send it a message or stop it, rename, pin, group and archive sessions, start new ones (optionally in their own git worktree), and check on the pull request a session opened.
It is a plain local process with no runtime dependencies. It talks to the Claude CLI only through its documented commands (claude agents --json, claude --resume -p, claude mcp list), reads the session transcripts the CLI writes to disk, and keeps its own small state in plain text files. It does not need Swttch, a desktop app, or a network connection to the Swttch project. Where a feature genuinely needs another program (for example a screen to show a layout), the tool says so instead of pretending.
Part of Swttch. It also ships inside the Swttch Desktop and can be used on its own, as described here.
Requirements
Node.js 20 or newer
The Claude Code CLI (
claude) on yourPATHOptional:
git(worktrees,sync_with_base_branch),gh(pull request tools), and@swttch/extend-kit0.11 or newer (plan limits inget_usage)
It runs on macOS, Linux and Windows. The test suite passes on all three.
Related MCP server: Claude Fleet Monitor
Quick start
Add one area as a server of its own:
claude mcp add swttch-sessions -- npx -y @swttch/session-manager-mcp --area session_mgmtThen, inside any Claude Code session:
List my five most recent sessions and tell me which ones are still running.
Find the session where I debugged the websocket reconnect and show me how it ended.
Send "please rebase on main" to the session called
fix-login.
Each area is its own MCP server, so Claude sees tools as mcp__swttch_<area>__<tool> (for example mcp__swttch_sidebar__create_group). Add the areas you want. Together the eleven areas are 70 tools, which takes a real share of every session's context, so start with one or two:
claude mcp add swttch-sessions -- npx -y @swttch/session-manager-mcp --area session_mgmt
claude mcp add swttch-sidebar -- npx -y @swttch/session-manager-mcp --area sidebarYou can also describe the servers in a --mcp-config file or a project .mcp.json:
{
"mcpServers": {
"swttch_session_mgmt": {
"command": "npx",
"args": ["-y", "@swttch/session-manager-mcp", "--area", "session_mgmt"],
"env": { "SWTTCH_SESSION_ID": "<the id of the calling session>" }
}
}
}Telling the server which session is calling
Many tools take "self" for the calling session. The server cannot learn its own session from the CLI, so a host that knows it (Swttch does) passes it as SWTTCH_SESSION_ID. Without it, tools that need "self" answer with a clear error, and everything else still works.
Configuration
Environment variable | Meaning | Default |
| The calling session. What | unset |
| Where the Claude CLI keeps its transcripts. |
|
| Where this server keeps marks, groups, proposals and settings. |
|
| The | found on |
| The folder offered as the project folder by | unset |
What works without anything else
Tools fall into three layers, by what they need:
Layer | Needs | Examples |
Read | the CLI's transcripts on disk |
|
Control | the CLI itself, or the program that is running the session |
|
Screen | a Swttch Desktop that shows the sessions |
|
How control works depends on who is running the session:
Nobody is running it. The server resumes it headlessly with
claude --resume <id> -p "<message>". Settings such as model, effort and permission mode are saved and applied when the session next starts.A Swttch program is running it (the JetBrains plugin, Swttch Desktop, or
swttch browser). The server finds that program in the CLI registry and asks it to act on the live session: deliver a message, interrupt a turn, switch the model, change the permission mode.A terminal, or any other app, is running it. Nothing outside that process can write to its input, so the tools answer
unavailable: ...and name the process that holds the session. They never pretend.
Screen tools do not draw anything. They append a request to a file that a Swttch Desktop watches; the tool answers queued and does not wait for the result. With no desktop having ever run, they answer unavailable.
Tools
Status: works means it does what it says now; needs Swttch Desktop means it queues a request for a desktop to carry out; not yet means it is listed so the whole surface is visible, and answers unavailable: <reason> when called.
session_mgmt (21)
Tool | What it does | Status |
| List the user's other Claude Code sessions, most recently active first. | works |
| Get one session's details by id, or the calling session with "self". | works |
| Search the message text of the user's sessions. | works |
| Read the recent turns of another session as plain text, oldest first. | works |
| Send a message to another session. | works |
| Interrupt another session's in-flight turn. | works |
| Archive a session: it leaves the default list and can be brought back with unarchive_session. | works |
| Restore an archived session to the session list. | works |
| Delete sessions for good: the transcript is removed and cannot be recovered. | works |
| Rename a session ("self" for the calling session). | works |
| Choose the model another session uses. | works |
| Choose a session's effort level (low, medium, high, xhigh, max). | works |
| Choose the permission mode a session starts in. | works |
| The account's plan limits (5-hour, weekly, per-model weekly) with percent used and reset time. | works |
| Turn fast mode on or off for a session. | not yet |
| Switch the output style one session writes in. | not yet |
| Turn remote access on or off for a session. | not yet |
| Clear a session's conversation (/clear). | not yet |
| Move a session you started to the top level. | works |
| Put a session under another one by hand, or take it to the top level. Only the record of who started whom changes. | works |
| Export a session's transcript as a zip. | not yet |
session (7)
Tool | What it does | Status |
| Start a separate Claude Code session for a task while you stay with the user. | works |
| List where start_session can put a session: the folders sessions have run in on this computer. | works |
| Move the task in progress into its own session. | not yet |
| Withdraw a session proposal (made with start_session "own_initiative" or "offer") that the user has not started: it went stale, was done here after all, or you proposed a better one. | works |
| Continue this session as a cloud session. | not yet |
| Mark the start of a new chapter in this session. | not yet |
| Read context from an embedded interactive widget. | not yet |
sidebar (13)
Tool | What it does | Status |
| List the custom sidebar groups in sidebar order. | works |
| Create a custom sidebar group and return its id. | works |
| Rename a custom sidebar group. | works |
| Delete a custom sidebar group. | works |
| List the sidebar sections in order: the built-in ones (pinned, routines, sessions) and one per custom group. | works |
| Create a sidebar section the user can file sessions under (the same record as create_group) and return its id. | works |
| Rename a section that was created by you or the user. | works |
| Delete a section that was created by you or the user; its sessions move back to Sessions (Ungrouped). | works |
| File up to 100 sessions under a custom group, or pass group_id null (or section_id "sessions") to move them back to Ungrouped. | works |
| Pin or unpin a session in the sidebar ("self" for the calling session). | works |
| Mark a session unread (a dot) or read in the sidebar ("self" for the calling session). | works |
| Acknowledge a session's "needs input" or "failed" dot so it reads as completed ("self" for the calling session). | works |
| Change how the sidebar lists sessions. | works |
host (7)
Tool | What it does | Status |
| Open a file from this session's folder in the user's code editor (VS Code, Cursor, Windsurf or Zed), optionally at a line and column. | works |
| Show a file or folder from this session's folder in the system file manager, selected in its parent folder. | works |
| Keep the user's computer from idle-sleeping for work that must outlast the turn: about 30 minutes for "turn_end", about an hour for "session_idle". | works |
| Report how much disk the Claude Code conversation history uses on this computer, and the free space left. | works |
| Free disk by removing the worktrees of sessions with no activity in the last 30, 60 or 90 days. | works |
| Delete the worktree an archived session left on disk because it held uncommitted changes, discarding those changes for good. | works |
| Bring the session's branch up to date with its base branch: fetch the base from origin and merge it into the checked-out branch. | works |
pr (5)
Tool | What it does | Status |
| Read the pull request bound to a session ("self" by default), through gh: number, state, branches, review decision, mergeability and a summary of the checks. | works |
| Bind the calling session to a pull request by its URL, for a pull request that was not picked up on its own. | works |
| Dismiss the bound pull request from this session; bind_pr restores it. | works |
| Enable or disable GitHub auto-merge on a pull request (github.com only). | works |
| Watch the session's pull request and wake the session on CI failures, conflicts and review comments. | not yet |
settings (2)
Tool | What it does | Status |
| Read the user's preferences: each comes back with its current value, the values set_setting accepts, and one line on what it does. | works |
| Change ONE of the user's preferences by its get_settings key. | works |
directory (2)
Tool | What it does | Status |
| Move this session to a different project folder. | not yet |
| Ask for access to a folder outside the session folder. | not yet |
connectors (3)
Tool | What it does | Status |
| List the MCP servers the Claude CLI knows ( | works |
| Re-dial a failed connector. | not yet |
| Turn a connector on or off for this session. | not yet |
turn (2)
Tool | What it does | Status |
| Keep the task list shown for this session. | works |
| Record the end-of-turn recap (two or three sentences: what is now true and where it stands) and, when the user must decide something, one short question with the buttons that answer it. | works |
window (4)
Tool | What it does | Status |
| Describe the desktop window right now: its split-view panes (where each sits, which session it shows, which is focused) and where the calling session is showing, if anywhere. | works |
| Show another session next to this one: "split" adds a split-view pane, "window" opens a pop-out window, "focus" shows it in the main pane. | needs Swttch Desktop |
| Close a split-view pane that you opened with open_session_in; never a pane the user arranged. | needs Swttch Desktop |
| Collapse (true) or expand (false) the desktop's sidebar. | needs Swttch Desktop |
view (4)
Tool | What it does | Status |
| Report where this session is on screen in the desktop (main window pane) and which side panes are open. | works |
| Show one of this session's side panes beside the conversation: diff (optional path, diff_scope), file (path, line), terminal (tab_id), pr, tasks, plan, artifact or preview. | needs Swttch Desktop |
| Close one of this session's side panes. | needs Swttch Desktop |
| Switch how a conversation is drawn: "normal" (tool calls collapsed), "thinking" (also shows thinking summaries) or "verbose" (everything expanded). | needs Swttch Desktop |
Worktrees
start_session can run the new session in its own git worktree:
use_worktree: truecreates<project>/.swttch/worktrees/<name>-<suffix>on a new branch<prefix>/<name>-<suffix>. The prefix is thebranch_prefixsetting (defaultswttch). The folder is added to the project's local.git/info/exclude, so it never shows up in the project's owngit status.Omitted: the session shares the caller's folder, unless the caller itself works in a worktree, in which case the new session gets one of its own.
use_worktree: falsealways shares the folder.archive_sessionremoves a clean worktree (the branch stays) and keeps one that has uncommitted changes, saying so. A later message to the archived session brings the worktree back.delete_session,clean_up_worktreesanddiscard_kept_worktreenever discard uncommitted work unless you ask for it explicitly.
Names
A session's name is the one the CLI keeps: the custom-title entry of its transcript, which the terminal's session list, the editor extensions and the desktop apps all read. set_session_title therefore never stores a name in a file of its own, and never writes the transcript itself:
A Swttch program is running the session. That program is asked to rename it (
renameon its control route), and its CLI records the name. Nothing is added to the conversation.Otherwise. The CLI's own
/rename <name>is run for it:claude -p --resume <id> --restricted --strict-mcp-configwith the command on stdin. It makes no model call and takes about a second; the command and the CLI's answer are added to that session's transcript. A CLI too old for the two flags is asked again without them.
When another program that cannot be asked (a terminal) is running the session, the name is still written, and the answer says that the program may write a name of its own back at the end of its next turn.
The title a session was started with is also kept in its mark, only so that the session can be listed in the moment before the CLI has written its transcript.
Hearing back
When a session started with start_session ends its turn, the session that started it is sent one message: which session it is from, and its last reply (the first 400 characters when the reply is longer). wake_when_done: false turns that off, and the answer of start_session says whether it was set up. detach_session ends it too: a session moved to the top level leaves the family of the session that started it and no longer reports to it.
A message one session sends another (this report, and send_message) is plain text whose first line names the sender: From <title> (session <id>):. That line is a contract for programs that draw transcripts, which show the message as coming from that session. It is not the CLI's own <cross-session-message> tag, because the CLI drops a typed message that is only that tag.
The answer of start_session carries session_id and cwd, which is all a screen needs to open the new session. Its description asks Claude to mention the session as a link, [title](#session_<session_id>), for a screen to turn into a way in.
The server that started the session is the one that waits for it. So the message is sent only while the calling session is still running, and only when the program that holds the calling session can deliver it (see "How control works" above). A calling session that a terminal holds hears nothing.
Proposals
A session can suggest starting another one without starting it: start_session with initiation: "own_initiative" (a full brief) or "offer" (a title only) stores a proposal that expires after seven days. Nothing runs until someone starts it: either by calling start_session again with proposal_id, or by a click in a program that lists proposals. dismiss_task withdraws one.
Commands for programs
Besides the MCP server, the entry script answers a few commands for a program that shows sessions (a settings screen, a session list). Each prints JSON, one object per line, so that such a program never has to open the files these commands read.
Command | Answer |
| puts a session under another, takes it to the top level on purpose, or forgets what was chosen |
| archives a session, brings it back on purpose, or forgets what was chosen |
|
|
| what the Claude desktop app records, by CLI id: |
| one desktop session's own record (title, CLI id, folder, archived, waiting for the person), or |
| stays running and prints a line whenever |
The desktop commands only read the desktop app's session folder (claude-code-sessions/<account>/<workspace>/local_*.json). Its shape is not a contract: a file that cannot be read is skipped, and a machine without the app answers with empty lists.
Data
Everything this server keeps is plain text, one JSON object per line, in <CCG_HOME>/entities/<domain>/<table>.entity.jsonl:
File | Contents |
| pin, unread, archive, group, title, model, effort, permission mode, parent session, worktree, bound pull request |
| named groups and their order |
| how the list is grouped and sorted |
| suggested sessions waiting for a decision |
| a session's task list and last wrap-up |
| preferences set through |
| requests for a desktop to change what is on screen |
The later line for an id is the row, and a line {"id": ..., "deleted": true} removes it. A line that is not valid JSON is skipped and left alone. Writers only ever append, so several programs can use the same files. Session transcripts are never modified; delete_session removes them and says it cannot be undone.
Safety
The tools can delete sessions, stop turns, merge branches and remove worktrees, so they are deliberately conservative:
delete_session(at most 25 per call),archive_sessionandstop_sessionrefuse the calling session, and skip sessions that another program is running.Worktrees and branches with uncommitted or unmerged work are kept unless
force_worktree_cleanup/include_uncommittedis passed.File tools (
open_in_editor,reveal_path) only accept paths inside the calling session's folder.sync_with_base_branchrefuses to run over uncommitted changes and never pushes.Nothing is sent anywhere except by the commands you would run yourself (
claude,git,gh, andswttch-extfor plan limits). The server opens no network port.Your MCP client's own permission prompts apply to every tool call. Read-only tools are good candidates for an allow list; delete, archive and stop are not.
Development
git clone https://github.com/Swttch/session-manager-mcp
cd session-manager-mcp
npm test # node --test, nothing to installThe code is plain ES modules with no build step and no dependencies. src/cli.js is the entry point, src/areas.js lists the areas, and each area lives in src/tools/. See CLAUDE.md for the working rules.
License
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
This server cannot be deployed
Maintenance
Related MCP Connectors
Work on your own computers from Claude or ChatGPT: run commands, edit and search files.
Start and manage Reason cloud coding agents, projects and sessions from any MCP client.
Your AI apps as one team: hand work to Codex or Claude Code on your Mac, with a shared logbook.
The team layer for AI coding agents: shared contracts, collision alerts, E2EE sessions.
Related MCP Servers
- AlicenseAqualityDmaintenanceEnables Claude Code sessions to communicate with each other, allowing discovery, messaging, and synchronous queries across sessions.658 npmMIT
- AlicenseNot gradedqualityFmaintenanceEnables Claude Code sessions to query fleet status, focus terminals, and manage sessions programmatically via MCP tools.2MIT
- AlicenseNot gradedqualityCmaintenanceEnables managing native Codex and Claude Code sessions through a shared interface, allowing agents in one harness to create, read, continue, update, search, and delete sessions in the other.11 npm2MIT
- AlicenseNot gradedqualityBmaintenanceEnables a Claude Desktop or Claude Code session to start, drive, and supervise interactive Claude Code CLI worker runs, including sending prompts, reading terminal output, waiting for completion, stopping runs, and managing settings and permissions.MIT