Connecting servers

Ad-hoc MCP Servers

Ad-hoc MCP Servers

mcporter is gaining support for "just try it" workflows where you point the CLI at a raw MCP endpoint without first editing a config file. This doc tracks the behavior and heuristics we use to make that experience smooth while keeping the runtime predictable.

#Entry Points

Two new flag sets let you describe a server on the command line:

  • mcporter list --http-url https://mcp.linear.app/mcp [--name linear]
  • mcporter call --stdio "bun run ./server.ts" --name local-tools

You can also pass a bare URL as the selector (mcporter list https://mcp.linear.app/mcp) or embed the URL in a call expression (mcporter call 'https://mcp.example.com/tools.generate({ topic: "release" })').

  • Add --json to mcporter list … when you need a machine-readable summary of status counts and per-server failures, use --output json/--output raw with mcporter call to receive structured { server, tool, issue } envelopes whenever a transport error occurs, and run mcporter auth … --json to capture the same envelope if OAuth or transport setup fails.

#Example: HTTP ad-hoc workflow

# Inspect the server directly via URL (no config entry needed)
mcporter list 'https://mcp.sentry.dev/mcp?agent=1'

# Call a tool by repeating the same URL + tool suffix
mcporter call 'https://mcp.sentry.dev/mcp?agent=1.use_sentry(request: "yo whats up")'

Notice that the second command repeats the URL. Ad-hoc definitions are ephemeral unless you pass --persist, so there is no stored server named mcp-sentry-dev-mcp yet. Reusing the printed slug only works after you persist the definition (see "Naming & Identity" below) or add the server to your config; otherwise keep passing the URL/stdio selector each time.

#Transport Detection

  • HTTP(S): Providing a URL defaults to the streamable HTTP transport. https:// works out of the box; http:// requires --allow-http (or the hidden alias --insecure) to acknowledge cleartext traffic. The --sse flag is a hidden alias for --http-url to match older examples. Use repeatable --header KEY=value flags for private servers that require headers such as Authorization, X-API-Key, or tenant selectors.
  • STDIO: Supplying --stdio (with a command string) or --stdio-bin (binary + args) selects the stdio transport. Your current shell environment is inherited automatically; use --env KEY=value only when you need to inject/override specific variables (and --cwd to change directories).
  • Conflict guard: Passing both URL and stdio flags errors out so we don’t guess.

#Naming & Identity

  • --name wins when provided.
  • Otherwise we derive a slug:
  • HTTP: <host> plus a sanitized path fragment (e.g. mcp-linear-app-mcp).
  • STDIO: executable basename + script (node-singlestep).
  • Until you persist the definition (via --persist, mcporter config add, etc.), the slug is only used as the cache key for OAuth tokens/log prefs—you still need to supply the ad-hoc descriptor (--http-url, --stdio, or bare URL) every time you invoke mcporter list|call|auth.
  • Once persisted, the slug becomes a normal server name so mcporter call <slug>.tool and mcporter auth <slug> work just like any other configured entry.
  • If you don’t persist the definition, run mcporter auth https://mcp.linear.app/mcp (or supply --name linear so mcporter auth linear also works) to finish OAuth with the same settings.

This name becomes the cache key for OAuth tokens and log preferences, so repeated ad-hoc calls still benefit from credential reuse.

#OAuth Auto-Detection

Many hosted MCP servers (Supabase, Vercel, etc.) advertise OAuth capabilities but expect clients to discover this dynamically. When an ad-hoc HTTP server responds with 401/403 during the initial handshake, mcporter now:

  1. Promotes the definition to OAuth and spins up the default browser flow—no need to edit config or supply auth: "oauth" manually. On headless hosts, pass --no-browser (or --browser none) to print the authorization URL instead of launching the platform browser.
  2. Persists the change whenever you pass --persist, so future runs remember that the endpoint requires OAuth without repeating the detection step.

The CLI still avoids surprise prompts during mcporter list; the upgrade happens the first time you run mcporter auth <url> or any other command that allows OAuth (i.e., not in --autoAuthorize=false mode).

#Auth & Persistence

  • OAuth flows are allowed; successful tokens store under the inferred name just like regular definitions.
  • mcporter auth accepts the same --http-url/--stdio flags (and even bare URLs), so you can immediately re-run mcporter auth https://… after a 401 without touching a config file.
  • Use mcporter auth <url> --no-browser for human-in-the-loop headless OAuth. Text mode writes only the authorization URL to stdout; --json --no-browser writes authorizationUrl plus redirectUrl as JSON. Keep that URL out of durable CI logs and support bundles. The mcporter auth process must keep running until the browser redirects to redirectUrl; process managers that capture stdout and then tear down the command can kill the local callback listener before tokens are saved. Use a persistent terminal, tmux, or a supervised background process such as nohup when completing OAuth outside an interactive shell.
  • When opening the URL on a different machine, remember that loopback redirect URLs point at the browser machine unless an SSH tunnel forwards the callback port back to the mcporter process. Use oauthRedirectUrl when you need a predictable callback port.
  • Nothing is written to disk unless you pass --persist /path/to/config.json. When set, we merge the generated definition into that file (creating it if necessary) so future runs can rely on the standard config pipeline. Ad-hoc HTTP headers are persisted with the entry, so placeholders such as --header 'Authorization=$env:MY_TOKEN' keep working through the normal config header resolver.

#Safety Nets

  • Non-HTTPS endpoints require --allow-http.
  • For stdio commands we print a confirmation snippet the first time we see a new command unless --yes is present.
  • Missing transports or malformed combinations throw descriptive errors, pointing to docs/adhoc.md for guidance.

#Follow-ups

  • Extend mcporter config add to leverage the same helper, making it the one-stop path from exploration to permanence.
  • Consider caching inference results so repeated URL calls automatically rehydrate the previous settings (env/cwd).