Skip to content

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

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

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

Conversation

@mkdev5

@mkdev5 mkdev5 commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

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.

@mkdev5
mkdev5 marked this pull request as ready for review June 2, 2026 06:48
@mkdev5
mkdev5 requested a review from JSONbored as a code owner June 2, 2026 06:48
@dosubot dosubot Bot added the size:S label Jun 2, 2026
@JSONbored JSONbored moved this from Todo to In progress in gittensory - v1 roadmap Jun 2, 2026
@dosubot

dosubot Bot commented Jun 2, 2026

Copy link
Copy Markdown

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

@JSONbored JSONbored left a comment

Copy link
Copy Markdown
Owner

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

@mkdev5

mkdev5 commented Jun 2, 2026

Copy link
Copy Markdown
Contributor Author

@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

@JSONbored JSONbored left a comment

Copy link
Copy Markdown
Owner

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 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
@JSONbored JSONbored added gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier. and removed feature labels Jun 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier.

Projects

No open projects
Status: Done

Development

Successfully merging this pull request may close these issues.

feat(mcp): add multi-account profile support

2 participants