Skip to content

feat(mcp): add multi-account profile support#263

Merged
JSONbored merged 12 commits into
JSONbored:mainfrom
MkDev11:feat/mcp-profile-support
Jun 2, 2026
Merged

feat(mcp): add multi-account profile support#263
JSONbored merged 12 commits into
JSONbored:mainfrom
MkDev11:feat/mcp-profile-support

Conversation

@MkDev11
Copy link
Copy Markdown
Contributor

@MkDev11 MkDev11 commented Jun 2, 2026

Summary

  • Closes feat(mcp): add multi-account profile support #99.
  • Adds named local MCP profiles so users can keep multiple GitHub/Gittensory sessions isolated.
  • Wires profile selection through login, logout, whoami, status, doctor, and MCP API calls.
  • Documents profile usage and adds CLI regression tests for session isolation, selected-profile logout, missing-profile fallback, and redaction.

Scope

  • This PR is focused and does not mix unrelated backend, UI, MCP, docs, dependency, and deploy changes.
  • This follows CONTRIBUTING.md and does not reintroduce GitHub Pages, VitePress, site/, or CNAME.
  • I linked an issue, or this is small enough that the summary explains why an issue is not needed.

Validation

  • git diff --check
  • npm run actionlint
  • npm run typecheck
  • npm run test:coverage locally; global coverage stays at or above 97% for lines, statements, functions, and branches (aim for 98%+ branch coverage locally so CI variance does not fail near the threshold)
  • npm run test:workers
  • npm run build:mcp
  • npm run test:mcp-pack
  • npm run ui:openapi:check
  • npm run ui:lint
  • npm run ui:typecheck
  • npm run ui:build
  • npm audit --audit-level=moderate
  • New or changed behavior has unit/integration tests for new branches, fallback paths, and sanitizer boundaries

If any required check was skipped, explain why:

  • None. npm run test:ci passed locally. Coverage summary: statements 99.01%, branches 97.09%, functions 98.07%, lines 99.61%.

Safety

  • No secrets, wallet details, hotkeys, coldkeys, user PATs, private keys, raw trust scores, private rankings, or private maintainer evidence are exposed.
  • Public GitHub text stays sanitized, low-noise, and does not imply compensation guarantees or optimization tactics.
  • Auth, cookie, CORS, GitHub App, Cloudflare, or session changes include negative-path tests.
  • API/OpenAPI/MCP behavior is updated and tested where needed.
  • UI changes use live API data or real empty/error/loading states, not production mock/demo fallbacks.
  • Visible UI changes include screenshots or a short recording.
  • Public docs/changelogs are updated where needed; changelogs are only edited for release-prep PRs.

Notes

  • No UI behavior changed; the UI checklist items are not applicable beyond the full UI validation gate passing.
  • Changelogs were not edited because this is not a release-prep PR.

@MkDev11 MkDev11 marked this pull request as ready for review June 2, 2026 06:48
@MkDev11 MkDev11 requested a review from JSONbored as a code owner June 2, 2026 06:48
@dosubot dosubot Bot added the size:S This PR changes 10-29 lines, ignoring generated files. label Jun 2, 2026
@JSONbored JSONbored added the feature New feature or request label Jun 2, 2026
@JSONbored JSONbored moved this from Todo to In progress in gittensory - v1 roadmap Jun 2, 2026
@dosubot
Copy link
Copy Markdown

dosubot Bot commented Jun 2, 2026

Related Knowledge

2 documents with suggested updates are ready for review.

gittensory

Getting Started
View Suggested Changes
@@ -208,6 +208,7 @@
 | Variable | Purpose |
 |---|---|
 | `GITTENSORY_API_URL` | Override the API endpoint (e.g., point at your local Worker: `http://localhost:8787`) |
+| `GITTENSORY_PROFILE` | Specifies which named profile to use for authentication. Profiles enable multi-account session isolation. If not set, the default profile is used. |
 | `GITTENSORY_CONFIG_PATH` or `GITTENSORY_CONFIG_DIR` | Override the default config storage location |
 | `GITTENSORY_API_TOKEN`, `GITTENSORY_MCP_TOKEN`, or `GITTENSORY_TOKEN` | Static token, as an alternative to running `gittensory-mcp login` |
 | `GITHUB_TOKEN` | Used for non-interactive login bootstrap via `gittensory-mcp login` |

✅ Accepted

MCP & Agent Integration
View Suggested Changes
@@ -69,7 +69,7 @@
 1. `GITTENSORY_API_TOKEN` environment variable
 2. `GITTENSORY_TOKEN` environment variable
 3. `GITTENSORY_MCP_TOKEN` environment variable
-4. Session token from the config file (stored by `gittensory-mcp login`)
+4. Active profile's session token from the config file (stored by `gittensory-mcp login`)
 
 Session tokens carry a `login`, `expiresAt`, and `scopes` payload [[11]](https://github.com/JSONbored/gittensory/blob/1e7506f4c5226d0b9b5da8fcd219309d84bacfcd/packages/gittensory-mcp/bin/gittensory-mcp.js#L707-L712). Static beta tokens may not have a verifiable session — this is expected behavior for pre-release access.
 
@@ -108,10 +108,71 @@
 ### Logging out
 
 ```sh
-gittensory-mcp logout
-```
-
-This revokes the remote session and removes the local config file.
+gittensory-mcp logout [--profile <name>]
+```
+
+This revokes the remote session and removes the local profile config. Pass `--all` to clear all profiles at once.
+
+### Multi-Account Profiles
+
+The default profile keeps single-account usage simple. For multiple GitHub/Gittensory identities — personal vs. work, different orgs, or client-specific accounts — use named profiles to keep sessions isolated.
+
+#### Creating and switching profiles
+
+```sh
+# Create a new profile
+gittensory-mcp profile create work
+
+# Log in to the new profile
+gittensory-mcp login --profile work --github-token "$WORK_GITHUB_TOKEN"
+
+# Switch between profiles
+gittensory-mcp profile switch work
+gittensory-mcp whoami
+
+# List all profiles
+gittensory-mcp profile list
+```
+
+Profiles persist in the same config file (`~/.config/gittensory/config.json`) but maintain isolated sessions, tokens, and API URLs.
+
+#### Using profiles with commands
+
+All authentication and diagnostic commands support the `--profile <name>` flag:
+
+```sh
+gittensory-mcp login --profile personal
+gittensory-mcp status --profile personal
+gittensory-mcp doctor --profile work
+gittensory-mcp whoami --profile work
+gittensory-mcp logout --profile personal
+```
+
+You can also set `GITTENSORY_PROFILE` to select the active profile for all commands and MCP API calls:
+
+```sh
+export GITTENSORY_PROFILE=work
+gittensory-mcp whoami
+gittensory-mcp --stdio
+```
+
+#### Logout behavior
+
+By default, `logout` only clears the selected profile:
+
+```sh
+gittensory-mcp logout --profile work
+```
+
+To revoke all profile sessions at once:
+
+```sh
+gittensory-mcp logout --all
+```
+
+#### Profile output redaction
+
+Profile commands redact session tokens and local config paths from their output to prevent accidental exposure in logs or screenshots. Use `--json` for structured output suitable for automation.
 
 ## Running as an MCP Server
 
@@ -507,7 +568,7 @@
 }
 ```
 
-The token priority order is: `GITTENSORY_API_TOKEN` > `GITTENSORY_TOKEN` > `GITTENSORY_MCP_TOKEN` > config file session [[10]](https://github.com/JSONbored/gittensory/blob/1e7506f4c5226d0b9b5da8fcd219309d84bacfcd/packages/gittensory-mcp/bin/gittensory-mcp.js#L968-L970).
+The token priority order is: `GITTENSORY_API_TOKEN` > `GITTENSORY_TOKEN` > `GITTENSORY_MCP_TOKEN` > active profile's session token [[10]](https://github.com/JSONbored/gittensory/blob/1e7506f4c5226d0b9b5da8fcd219309d84bacfcd/packages/gittensory-mcp/bin/gittensory-mcp.js#L968-L970).
 
 ***
 
@@ -529,11 +590,12 @@
 
 | Command | Purpose |
 |---------|---------|
-| `gittensory-mcp login [--github-token <token>]` | Authenticate via GitHub Device Flow (or a static token). Stores a Gittensory session in `~/.config/gittensory/config.json` |
-| `gittensory-mcp logout` | Revoke the remote session and delete the local config |
-| `gittensory-mcp whoami` | Print the authenticated GitHub login |
-| `gittensory-mcp status` | Report package version, npm latest, API health, auth state, and source-upload posture |
-| `gittensory-mcp doctor [--cwd path]` | Run the full diagnostic suite (API health, compatibility, auth, PATH, local scorer) |
+| `gittensory-mcp login [--profile <name>] [--github-token <token>]` | Authenticate via GitHub Device Flow (or a static token). Stores a Gittensory session in `~/.config/gittensory/config.json` |
+| `gittensory-mcp logout [--profile <name>] [--all]` | Revoke the remote session and delete the local config. `--all` clears all profiles |
+| `gittensory-mcp whoami [--profile <name>]` | Print the authenticated GitHub login |
+| `gittensory-mcp status [--profile <name>]` | Report package version, npm latest, API health, auth state, and source-upload posture |
+| `gittensory-mcp doctor [--profile <name>] [--cwd path]` | Run the full diagnostic suite (API health, compatibility, auth, PATH, local scorer) |
+| `gittensory-mcp profile <list\|create\|switch\|remove>` | Manage named profiles for multi-account session isolation. Use `list` to show all profiles, `create <name>` to initialize a new profile, `switch <name>` to set the active profile, or `remove <name>` to delete a profile |
 | `gittensory-mcp changelog` | Print the local `CHANGELOG.md` |
 | `gittensory-mcp init-client --print codex\|claude\|cursor\|mcp` | Print a ready-to-paste MCP client config snippet |
 

✅ Accepted

How did I do? Any feedback?  Join Discord

Copy link
Copy Markdown
Owner

@JSONbored JSONbored left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@MkDev11 the profile support is useful, but token precedence is still wrong.

Required change:

  • Preserve env-token precedence: GITTENSORY_API_TOKEN / GITTENSORY_TOKEN / GITTENSORY_MCP_TOKEN should win over configured profile tokens.
  • Add regression coverage for env-token override while an active profile token exists.

Validation expected:

  • npm run build:mcp
  • npm run test:mcp-pack
  • npm run test:ci

@MkDev11
Copy link
Copy Markdown
Contributor Author

MkDev11 commented Jun 2, 2026

@MkDev11 the profile support is useful, but token precedence is still wrong.

Required change:

  • Preserve env-token precedence: GITTENSORY_API_TOKEN / GITTENSORY_TOKEN / GITTENSORY_MCP_TOKEN should win over configured profile tokens.
  • Add regression coverage for env-token override while an active profile token exists.

Validation expected:

  • npm run build:mcp
  • npm run test:mcp-pack
  • npm run test:ci

addressed it

@JSONbored JSONbored self-requested a review June 2, 2026 22:18
Copy link
Copy Markdown
Owner

@JSONbored JSONbored left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@MkDev11

A few notes:

  • The profile workflow is useful for #99, especially for users who need to keep JSONbored/oktofeesh1-style identities separated locally.
  • The important precedence issue is fixed: GITTENSORY_API_TOKEN, GITTENSORY_TOKEN, and GITTENSORY_MCP_TOKEN now stay ahead of profile sessions.
  • The tests cover profile switching, selected-profile logout, missing-profile behavior, JSON output, and token/path redaction.

No code changes requested.

@dosubot dosubot Bot added the lgtm This PR has been approved by a maintainer label Jun 2, 2026
@JSONbored JSONbored merged commit 5abc9c5 into JSONbored:main Jun 2, 2026
4 checks passed
@github-project-automation github-project-automation Bot moved this from In progress to Done in gittensory - v1 roadmap Jun 2, 2026
@github-actions github-actions Bot mentioned this pull request Jun 3, 2026
12 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature New feature or request lgtm This PR has been approved by a maintainer size:S This PR changes 10-29 lines, ignoring generated files.

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

feat(mcp): add multi-account profile support

2 participants