Skip to main content
Glama
Bayway

janusmcp

JanusMCP

One credential broker. Every account. From the CLI or MCP. Multi-account tool access for AI agents, with credentials kept local.

CI Release License: MIT Status: alpha Website

Add to Cursor Install in VS Code

One-click buttons require the npm package to be published. See RELEASING.md.

The problem

If you work with more than one company, you use the same MCP server (Supabase, GitHub, Slack…) with different identities — a different account, email and token per client. Today most LLM clients hold one account at a time per connector: to switch client you disconnect, reconnect, and redo the OAuth login. Every time.

The MCP protocol has no notion of "account": one session = one identity = one set of credentials. JanusMCP fills that gap.

Related MCP server: qiaomu-llm-mcp

What it does

JanusMCP is a local multi-account tool broker for AI agents. It can be used directly from the CLI or as an MCP server in front of the real upstream servers:

  • Add N accounts once for the same service and keep them all available.

  • Switch identity without reconnecting — no re-login, no fiddling with config.

  • Works with any LLM client — it just speaks standard MCP (stdio + Streamable HTTP).

  • Works without an MCP session too — agents can drive it directly from the CLI (code-execution mode): janusmcp tools / schema / call invoke tools on demand, with no bulk tool definitions loaded upfront.

  • Runs locally — your machine, your keychain, your control.

  • Keeps the context clean — it exposes only the active account's tools, not N×tools.

                 ┌─────────────────────────────┐   ┌─ Supabase (Client A)
LLM client ─MCP─▶│   JanusMCP broker           │─▶ ├─ Supabase (Client B)
(Claude/GPT/     │   active-account · vault ·  │   ├─ GitHub  (Client A)
 Gemini/…)       │   per-session scoping       │   └─ …
                 └─────────────────────────────┘

You drive it with three control tools that appear in any client: janus_list_accounts, janus_use_account, janus_whoami.

Choose your mode

Use from the CLI — Claude Code, Codex, Cursor, scripts

npm install -g @bayway/janusmcp
janusmcp tools
janusmcp schema list_tables
janusmcp call list_tables --args '{"schemas":["public"]}' --json --timeout 30s

The CLI discovers schemas only when needed, accepts JSON through --args or stdin, supports explicit accounts/profiles, and provides stable exit codes. See the CLI guide and copyable agent instructions.

Connect over MCP — desktop and chat clients

npx @bayway/janusmcp serve
# or configure a supported client automatically:
janusmcp install claude-desktop

Both modes share the same config, OS-keychain vault, OAuth tokens and persisted active account. Use janusmcp daemon start to keep upstream sessions warm across repeated CLI calls.

Install

Once released, install via your favorite channel (all published automatically on each tag — see RELEASING.md):

npx @bayway/janusmcp serve                       # npm / MCP mode
brew install bayway/janusmcp/janusmcp     # Homebrew (macOS/Linux)
scoop install janusmcp                               # Windows
docker run --rm -p 7332:7332 ghcr.io/bayway/janusmcp:latest

…or download a prebuilt binary from Releases.

Build from source (60-second quickstart)

git clone https://github.com/bayway/janusmcp
cd janusmcp/go
make build                       # produces ./bin/janusmcp
cp config.example.json config.json   # edit with your accounts
./bin/janusmcp serve             # stdio, for Claude Desktop/Code

Two Supabase clients, PATs kept in your OS keychain (never in the config):

./bin/janusmcp vault set supabase_client_a   # paste the PAT
./bin/janusmcp vault set supabase_client_b
// config.json
{
  "bindingMode": "session",
  "accounts": [
    { "id": "client_a", "service": "supabase", "command": "npx",
      "args": ["-y", "@supabase/mcp-server-supabase@latest", "--read-only", "--project-ref=REF_A"],
      "env": { "SUPABASE_ACCESS_TOKEN": "vault:supabase_client_a" } },
    { "id": "client_b", "service": "supabase", "command": "npx",
      "args": ["-y", "@supabase/mcp-server-supabase@latest", "--read-only", "--project-ref=REF_B"],
      "env": { "SUPABASE_ACCESS_TOKEN": "vault:supabase_client_b" } }
  ]
}

Add it to Claude Desktop:

{ "mcpServers": { "janusmcp": {
  "command": "/abs/path/janusmcp/go/bin/janusmcp", "args": ["serve"],
  "env": { "JANUS_CONFIG": "/abs/path/janusmcp/go/config.json" } } } }

For ChatGPT / Gemini / Cursor / Copilot, run HTTP and point them at the URL:

JANUS_TRANSPORT=http JANUS_HTTP_PORT=7332 ./bin/janusmcp serve
# → http://127.0.0.1:7332/mcp

Commands

Run janusmcp help for the full reference. The essentials:

Command

What it does

janusmcp serve

Run the broker (default). Transports via env: JANUS_TRANSPORT=stdio|http|both, JANUS_HTTP_HOST, JANUS_HTTP_PORT.

janusmcp tools [selector]

Compact tool list for the active (or given) account/profile. --json for full definitions; optional --timeout.

janusmcp schema <tool>

Full JSON definition of one tool. --account <id|profile> disambiguates; optional --timeout.

janusmcp call <tool>

Invoke a tool. Supports --account, --args, stdin, stable --json, and optional --timeout.

janusmcp use <account|profile>

Persist the active selector for future CLI commands and new MCP sessions.

janusmcp daemon start|stop|restart|status

Manage the optional loopback-only daemon that reuses upstream sessions.

janusmcp ui

Open the local control panel — add accounts, log in, set secrets.

janusmcp add <template> [id]

Add an account from a template (janusmcp catalog lists them).

janusmcp catalog

List the built-in account templates.

janusmcp connect <id>

Connect an account; for remote OAuth, opens the browser.

janusmcp status

Show each account's login/secret status (no secret values).

janusmcp vault set <name> / delete <name>

Store / remove a secret in the OS keychain.

janusmcp login <provider> <name>

OAuth loopback login; token referenced as oauth:<name>.

janusmcp providers

List built-in OAuth providers.

janusmcp install <client>

Configure an LLM client to launch JanusMCP.

janusmcp uninstall <client>

Remove JanusMCP from an LLM client's config.

janusmcp version · janusmcp help

Version · this reference.

Supported <client> values for install / uninstall: claude-desktop, claude-code, cursor, vscode, gemini, codex, chatgpt, print. Run janusmcp install list (or uninstall list) to see each target and whether it's already configured.

janusmcp install claude-desktop      # one-command setup
janusmcp uninstall claude-desktop    # clean removal (restart the client afterwards)

Inside any connected client you also get the control tools janus_list_accounts, janus_use_account, janus_whoami, janus_login, janus_use_profile, and janus_with_account.

Profiles — a whole client's stack at once

A profile groups accounts of the same client across different services. Activating it exposes the tools of all its accounts together, and each call is routed to the right upstream:

// config.json
{
  "accounts": [
    { "id": "supabase_a", "service": "supabase", "transport": "http", "url": "https://mcp.supabase.com/mcp", "auth": "oauth" },
    { "id": "github_a",   "service": "github",   "transport": "http", "url": "https://api.githubcopilot.com/mcp/", "auth": "oauth" }
  ],
  "profiles": {
    "client_a": ["supabase_a", "github_a"]
  }
}

Then in chat: janus_use_profile with { "profile": "client_a" } → Supabase and GitHub tools for Client A are available simultaneously. Colliding tool names across accounts are namespaced (<account>_<tool>).

One-shot cross-account calls

janus_with_account runs a single call on another account without changing the active one — e.g. { "account_id": "client_b", "tool": "list_tables" }. Omit tool to list that account's available tools first.

Code-execution mode — context-efficient tools from the terminal

Loading every MCP tool definition into an LLM context is expensive. In code-execution mode an agent (or you) invokes tools on demand from the shell instead — à la "code execution with MCP" — so the context holds only the results it actually asked for:

janusmcp tools                        # compact list for the active account/profile
janusmcp tools client_a               # ...or any account/profile explicitly
janusmcp schema list_tables           # full input schema of ONE tool, only when needed
janusmcp call list_tables --args '{"schemas":["public"]}'
janusmcp call ping --account azienda_b          # cross-account without switching
echo '{"sql":"select 1"}' | janusmcp call db_query   # JSON args via stdin too
janusmcp call ping --json --timeout 30s         # stable envelope for agents

call prints the tool's text content to stdout and exits non-zero on a tool error, so it composes with pipes and scripts. Selectors resolve exactly like in the broker: the persisted active account by default, or any account id / profile name; a name that collides across a profile's accounts must be disambiguated with --account. Secrets resolve through the same vault/OAuth stack as serve — nothing extra to configure.

This makes JanusMCP a first-class citizen for CLI-driven agents (Claude Code, Codex, Cursor agents, or any agent with shell access): instead of registering it as an MCP server, just tell the agent that janusmcp tools / schema / call exist. Discovery, schemas and invocation happen on demand, credentials stay in the keychain, and multi-account switching works the same as over MCP. Both modes share the config and the persisted active account, so you can mix them freely.

For repeated calls, janusmcp daemon start launches an authenticated loopback-only broker. tools, schema, and call auto-detect it and reuse its upstream sessions; --direct bypasses it and --daemon requires it. Set JANUS_DAEMON=auto|require|off to choose a default policy.

Key features

Multi-account, one endpoint

N identities for the same service, no reconnecting

Identity scoping

per-call → per-session → global, via bindingMode: global | session | locked. Session scope needs a real connection: stdio and legacy HTTP have one; MCP 2026-07-28 removed sessions, so there it is per-call (janus_with_account) or global

Dual transport

stdio (local-first clients) + Streamable HTTP (remote-first clients), same process. HTTP serves MCP 2026-07-28 and every earlier revision, each on the transport it requires

Secure vault

OS keychain (macOS/Windows/Linux) + encrypted-file fallback; secrets as vault:<name>

OAuth loopback

janusmcp login (PKCE), tokens stored in the vault, auto-refresh, oauth:<name>

Context-safe

only the active account's tools are exposed; switching emits tools/list_changed

MCP and CLI

same broker as an MCP server or via janusmcp tools / schema / call — no bulk tool definitions loaded upfront

How it's different

The MCP gateway space (MetaMCP, mcp-proxy, IBM ContextForge, …) aggregates different servers behind one endpoint. JanusMCP solves the orthogonal, under-served problem: many identities for the same service, without saturating the model's context, from any LLM, fully local. It's a credential-aware broker, not a flat aggregator.

Built-in connectors

Scaffold an account from a ready-made template with janusmcp add <template> (run janusmcp catalog for the full, up-to-date list). Most use browser OAuth (dynamic client registration); a few need extra setup, noted below.

  • Remote, browser login (OAuth): supabase, github, notion, sentry, stripe, hubspot, paypal, linear, vercel, canva, neon, netlify, zapier.

  • SSE transport (legacy): asana, monday, intercom, webflow, wix, square, globalping.

  • Cloudflare (Streamable HTTP): cloudflare-bindings, cloudflare-observability, cloudflare-radar, cloudflare-builds, cloudflare-browser.

  • Google Workspace (bring-your-own OAuth client): gmail, google-drive, google-calendar, google-chat — see go/docs/google-workspace.md.

  • Per-account URL: activecampaign (paste your Remote MCP URL).

  • Figma: figma-desktop (local, recommended) and figma (remote, restricted — see below).

  • Generic building blocks: http-oauth, sse-oauth, supabase-pat, stdio.

Missing one? Add any remote server with http-oauth / sse-oauth, any local one with stdio, or define your own template in ~/.config/janusmcp/templates.json.

Provider notes

ActiveCampaign

ActiveCampaign ships an official remote MCP server with a unique URL per account (ActiveCampaign → Settings → Developer → Remote MCP URL) and browser-based OAuth — a natural fit for the multi-account broker. Add one account per client:

janusmcp add activecampaign ac_clientA   # then paste that client's Remote MCP URL in config.json
janusmcp connect ac_clientA              # browser login

Because the URL is per-account, the template seeds a REPLACE_ACTIVECAMPAIGN_MCP_URL placeholder you must replace with your own URL. Login uses dynamic client registration, so no client ID/secret is needed.

Google Workspace (Gmail / Drive / Calendar / Chat)

Google offers remote MCP servers for Gmail, Drive, Calendar and Chat, but — unlike most providers here — they require your own OAuth client (created in the Google Cloud Console); they don't support dynamic client registration. JanusMCP supports this via the oauthClientId / oauthClientSecret / scopes fields, preset by the gmail, google-drive, google-calendar and google-chat templates:

export GOOGLE_OAUTH_CLIENT_ID=... GOOGLE_OAUTH_CLIENT_SECRET=...
janusmcp add gmail gmail_clientA
janusmcp connect gmail_clientA           # browser login as client A

Full one-time Google Cloud setup (enable MCP APIs, consent screen, Desktop OAuth client) and scope details are in go/docs/google-workspace.md.

Figma

Figma offers two MCP servers, handled differently here:

  • Local Dev Mode server (recommended). Figma's desktop app hosts an MCP server on http://127.0.0.1:3845/mcp. It's local, needs no OAuth, and works out of the box: enable it in the desktop app (Dev Mode → Inspect → Enable desktop MCP server) and add it with janusmcp add figma-desktop figma_work. Requires a Dev/Full seat on a paid Figma plan.

  • Remote server (https://mcp.figma.com/mcp) — restricted. Figma allowlists the OAuth client_name during dynamic client registration and returns 403 Forbidden to any client that isn't in its MCP catalog (VS Code, Cursor, Claude Code, …). JanusMCP is not (yet) an approved client.

    ⚠️ Workaround — opt-in, use at your own risk. You can make JanusMCP register under an approved name by setting "clientName": "Claude Code" on a remote figma account in your config.json. This impersonates an approved client and may violate Figma's Terms of Service; it can also break whenever Figma updates its allowlist. It is not enabled by default. Prefer the local Dev Mode server above for real work.

    The proper long-term fix is for JanusMCP to be submitted to and approved for Figma's MCP catalog, so no client_name override is needed. This is planned.

Status & roadmap

Alpha — the core is implemented and tested in Go.

  • Active-account model, per-session / global / locked scoping

  • stdio + Streamable HTTP transports

  • MCP 2026-07-28 (stateless core) on both transports, legacy revisions unchanged

  • OS-keychain vault + encrypted-file fallback

  • OAuth loopback (PKCE) with auto-refresh and per-spawn token resolution

  • One-command client install (janusmcp install …), Claude Desktop .mcpb, registry server.json

  • Multi-server "profiles" per client (Supabase + GitHub + Slack of Client A at once)

  • with_account one-shot cross-account calls

  • CLI / code-execution mode (janusmcp tools / schema / call) — invoke tools on demand instead of loading all definitions, to cut token usage

  • SSE upstream transport (in addition to Streamable HTTP + stdio) for SSE-only servers

  • Pre-registered OAuth clients (bring-your-own client for servers without dynamic client registration, e.g. Google Workspace)

  • Built-in connector catalog (25+ services) via janusmcp catalog / add

  • Signed, per-OS release binaries & registry auto-publish in CI

See design-broker-mcp-multi-account.md for the full design.

Repository layout

Project documentation

Privacy Policy

JanusMCP runs entirely on your machine. It has no backend servers, collects no data, and contains no analytics or telemetry — the developers receive nothing about you or your usage. Credentials and tokens are stored in your OS keychain (or, if you opt in, an encrypted local file) and are used only to authenticate to the services you configure; they never pass through the model context. Network connections are made only to the MCP servers and OAuth providers you configure. Because everything is local, data is retained only on your own device for as long as you keep it, and removing it (janusmcp vault delete <name>, or uninstalling) removes it entirely.

Full policy: https://janusmcp.dev/privacy.

Contributing

Contributions are very welcome — see CONTRIBUTING.md. New connector presets, client integration guides, and packaging help are especially appreciated.

License

MIT — see LICENSE.

Available Tools

5 tools
janus_list_accountsA
Read-only

List configured accounts/services and which is active for this session.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, so the safety profile is covered. The description usefully discloses that the result is session-scoped ('active for this session'), which the annotations do not convey, but it says nothing about the idempotentHint=false oddity, pagination, or result shape.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence with zero waste, front-loading the action ('List') and then the two pieces of information returned. Nothing could be trimmed without losing meaning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a parameterless read tool with readOnlyHint, the description covers what is listed and which account is flagged active, which is most of what an agent needs. With no output schema, a brief note on the result shape or ordering would make it fully self-contained.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so there is no parameter semantics to document; the baseline for a parameterless schema is 4. Nothing in the description is needed to clarify inputs.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Specific verb 'List' plus resource 'configured accounts/services', and it adds the active-session detail. It does not name or contrast with siblings like janus_use_account or janus_whoami, but the scope is clear enough to distinguish a listing tool from a switching/identity tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Implicit usage only: listing accounts naturally precedes janus_use_account, and the 'which is active for this session' phrasing hints at session-awareness. There is no explicit when-to-use, no exclusions, and no routing to alternatives such as janus_whoami.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

janus_loginA

Start an OAuth login for in your browser and store the token as . The token is captured locally and saved to the OS keychain — it never passes through this chat. Afterwards reference it from an account env as "oauth:". Built-in providers: github, google, supabase.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYesName to store the token under (used as oauth:<name>).
providerYesOAuth provider preset, e.g. github, google.

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only cover safety hints (readOnly=false, openWorld=true, destructive=false, idempotent=false). The description adds material behavior beyond that: a browser window opens, the token is captured locally and saved to the OS keychain, and it never passes through the chat. This is exactly the security-relevant context an agent needs.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences: action first, token-handling detail second, provider list last. No filler, and the most decision-relevant information is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, so the description carries the return-value burden, which it does by explaining the token is saved locally and how to reference it afterwards. Combined with 100% schema coverage, an agent has everything needed to invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and both parameter descriptions already explain 'name' (used as oauth:<name>) and 'provider' (preset, e.g. github, google). The description largely restates this convention rather than adding new syntax or constraints, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource (start OAuth login for a provider) and the side effect (store token as <name>). It is clearly distinguishable from siblings like janus_list_accounts or janus_whoami, which do not initiate auth flows.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Tells the agent the follow-up step: reference the token via an account env as "oauth:<name>", and lists built-in providers (github, google, supabase). It gives clear context for when this tool is the right one, but doesn't explicitly state when not to use it or prerequisites (e.g., whether a browser must be available).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

janus_use_accountA
Idempotent

Set the active account/identity. Reloads upstream tools and notifies the client. scope: 'session' or 'global' (defaults to the broker bindingMode).

ParametersJSON Schema
NameRequiredDescriptionDefault
scopeNo
account_idYes

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare readOnlyHint=false, idempotentHint=true, destructiveHint=false, so the safety profile is already structured. The description adds genuinely useful side-effect context beyond that: the call reloads upstream tools and notifies the client, which tells an agent the tool list may change after invocation. It does not contradict the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short clauses, front-loaded with the core action before the side effects and the scope note. No filler or restatement of the name. The parenthetical default could be phrased more tightly, but nothing is wasteful.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-parameter state setter with no output schema, the description covers purpose, side effects, and the scope default. Annotations carry the safety profile. The remaining gap is account_id semantics and any failure behavior for an invalid account, which keeps it short of fully complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% for two parameters, so the description must compensate. It does explain the scope enum values and its default ('defaults to the broker bindingMode'), which is real added value. The required account_id gets no semantics at all – no format, no hint that it should come from janus_list_accounts – leaving half the surface undocumented.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'Set the active account/identity.' That is unambiguous and an agent can distinguish it from janus_whoami (read current identity) or janus_list_accounts. It does not explicitly contrast itself with the closest sibling, janus_with_account, which is a scoped variant of the same idea.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by the name and by 'Set the active account/identity' – an agent can infer this is the tool to call when switching identity. However, there is no explicit when-to-use guidance, no statement of when to prefer janus_with_account or janus_login instead, and no mention of prerequisites such as needing an existing authenticated session.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

janus_whoamiB
Read-only

Return the active account for this session and how it was resolved.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, so safety is covered. The description adds real value by signaling that resolution provenance is returned ('how it was resolved'), but it does not explain the odd non-idempotent hint or the shape of the resolution detail.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single tight sentence with the subject front-loaded and no wasted words. Appropriate size for a no-arg query tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-param read tool with annotations covering safety, this is nearly adequate, but with no output schema the description should hint at the returned fields (account identity, resolution source) to fully prepare the agent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so there is nothing for the description to disambiguate; baseline 4 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Return') and resource ('the active account for this session'), plus the extra dimension of 'how it was resolved'. This is clearly distinct from siblings like janus_login or janus_use_account, though it never explicitly names or contrasts with them.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no statement of when to call this versus janus_list_accounts or the other session tools. The phrase 'for this session' implies a diagnostic/context-check use case, but the agent must infer that entirely.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

janus_with_accountA

Run a single tool call on another account WITHOUT changing the active account. Omit 'tool' to first list that account's available tools.

ParametersJSON Schema
NameRequiredDescriptionDefault
toolNoTool to call; omit to list the account's tools.
argumentsNoArguments object for the tool.
account_idYesTarget account id.
full_schemaNoWhen listing, include complete tool definitions. Intended for CLI discovery.

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false, openWorldHint=true, and idempotentHint=false, so the safety posture is partly covered. The description adds the key non-obvious behavior that the active account is left untouched, but does not disclose side effects, auth requirements, or what happens to the invoked tool's writes. Adequate, not rich.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tightly written sentences with the primary behavior and its distinguishing constraint front-loaded, followed by the discovery fallback. No filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For an open-world meta-tool with no output schema, the description covers the core modes (invoke vs. list) and the account-scoping behavior well. It omits behavioral detail on the arbitrary tools it may invoke, which is a minor gap given annotations carry the safety profile.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all four parameters are already documented in the schema. The description's mention of omitting 'tool' to list tools duplicates what the schema already states about the tool parameter, adding no syntax or format detail beyond it. Baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Run a single tool call on another account') plus a critical scope constraint ('WITHOUT changing the active account') that implicitly separates it from the sibling janus_use_account. An agent can tell what this does and what it is not without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The 'WITHOUT changing the active account' clause establishes clear context for when to use this over janus_use_account, and the description instructs how to discover tools ('Omit tool to first list that account's available tools'). It stops short of naming the alternative sibling explicitly or stating exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 5 tool updatesv0.6.2
    • First observedjanus_list_accounts
    • First observedjanus_login
    • First observedjanus_use_account
    • First observedjanus_whoami
    • First observedjanus_with_account

TDQS

A3.9/5.0

Scored across 5 tools

Disambiguation4/5

Each tool has a distinct action: listing, logging in, switching active account, checking identity, and one-off account-scoped execution. There is minor overlap between janus_list_accounts and janus_whoami since both can reveal the active account, but their descriptions make the distinction workable.

Naming Consistency5/5

All tools share the janus_ prefix and use consistent snake_case naming. The verb-based patterns (list_accounts, login, use_account, whoami, with_account) are predictable and readable despite whoami being a conventional special case.

Tool Count5/5

Five tools is well-scoped for an account/identity management server. Each tool earns its place, covering discovery, authentication, active-account control, identity inspection, and temporary account switching without unnecessary extras.

Completeness4/5

The core account lifecycle is covered: listing, OAuth login, setting active identity, checking identity, and running a one-off call under another account. A logout/forget-account operation is a minor gap, but agents can work around it and the essential workflows are present.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    C
    maintenance
    An MCP server that enables users to query, compare, and synthesize responses from multiple local and cloud LLMs simultaneously using existing subscriptions. It provides tools for parallel model evaluation, consensus polling with an LLM-as-judge, and response synthesis across different model providers.
    8
    30 npm
    15
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    One local gateway for all your MCP servers — shared by every AI coding tool (Claude, Cursor, VS Code, Codex). Set up each server once; keys stay in the OS keychain; lazy discovery keeps agent context small. Local-first, open source.
    4
    5 npm
    221
    MIT