Connect an agent client
Every agent client spells "connect to this URL" differently: VS Code keys on
servers, Cursor has no type, Devin Desktop says serverUrl, OpenCode wants
"type": "remote", and Codex is TOML. This page has the snippet for each one.
The quickest route is your instance's own /account page. It shows the
same snippets as this page, already filled in with your instance's agent URL
(mcp.oauth.publicUrl) and server name (mcp.serverName). Below, they use
https://searchcode.example.com/v1/mcp and the default name,
searchcode-private.
Each client has two ways in:
- Signing in (OAuth) is the default and needs no key. The client registers itself, opens a browser, you approve, and it holds a token that refreshes. Your groups re-resolve on every refresh, and offboarding you in the identity provider ends it. Behind a sign-in proxy, open the UI at least once a week, or the agent's sign-in lapses (see credentials).
- A key is for a client that cannot sign in. Mint one on
/account. The key forms read it from an environment variable, so the file you might commit holds a reference and never the key. Two rows say otherwise, and each says why.
searchcode-private is a name local to your client and must be unique in that
file. Pasting over an entry that already has it replaces it silently, with no
merge and no warning. Rename it to whatever you call this instance.
The key forms read the key from an environment variable, set once:
export SEARCHCODE_PRIVATE_TOKEN=YOUR_KEY
Claude Code
Sign in (OAuth)
Terminal:
claude mcp add --transport http searchcode-private https://searchcode.example.com/v1/mcp
Add --scope user to make it available in every project.
With a key
.mcp.json:
{
"mcpServers": {
"searchcode-private": {
"type": "http",
"url": "https://searchcode.example.com/v1/mcp",
"headers": {
"Authorization": "Bearer ${SEARCHCODE_PRIVATE_TOKEN}"
}
}
}
}
Cursor
Sign in (OAuth)
~/.cursor/mcp.json or .cursor/mcp.json:
{
"mcpServers": {
"searchcode-private": {
"url": "https://searchcode.example.com/v1/mcp"
}
}
}
With a key
~/.cursor/mcp.json or .cursor/mcp.json:
{
"mcpServers": {
"searchcode-private": {
"url": "https://searchcode.example.com/v1/mcp",
"headers": {
"Authorization": "Bearer ${env:SEARCHCODE_PRIVATE_TOKEN}"
}
}
}
}
VS Code
Sign in (OAuth)
.vscode/mcp.json:
{
"servers": {
"searchcode-private": {
"type": "http",
"url": "https://searchcode.example.com/v1/mcp"
}
}
}
With a key
.vscode/mcp.json:
{
"inputs": [
{
"type": "promptString",
"id": "searchcode-private-token",
"description": "API key for searchcode-private",
"password": true
}
],
"servers": {
"searchcode-private": {
"type": "http",
"url": "https://searchcode.example.com/v1/mcp",
"headers": {
"Authorization": "Bearer ${input:searchcode-private-token}"
}
}
}
}
VS Code asks for the key the first time the server starts and stores it itself.
Codex
Sign in (OAuth)
~/.codex/config.toml:
[mcp_servers.searchcode-private]
url = "https://searchcode.example.com/v1/mcp"
Then, in a terminal:
codex mcp login searchcode-private
With a key
~/.codex/config.toml:
[mcp_servers.searchcode-private]
url = "https://searchcode.example.com/v1/mcp"
bearer_token_env_var = "SEARCHCODE_PRIVATE_TOKEN"
OpenCode
Sign in (OAuth)
opencode.json:
{
"mcp": {
"searchcode-private": {
"type": "remote",
"url": "https://searchcode.example.com/v1/mcp"
}
}
}
With a key
opencode.json:
{
"mcp": {
"searchcode-private": {
"type": "remote",
"url": "https://searchcode.example.com/v1/mcp",
"headers": {
"Authorization": "Bearer {env:SEARCHCODE_PRIVATE_TOKEN}"
}
}
}
}
Claude Desktop / claude.ai
Sign in (OAuth)
Settings → Connectors → Add custom connector:
https://searchcode.example.com/v1/mcp
On Team and Enterprise plans an admin adds it once for the whole organisation. The connector is reached from Anthropic's side, so this URL must be reachable from the internet.
With a key (written into the file, because Claude Desktop is a GUI application and inherits no shell environment, so the key has to be in its own env block)
claude_desktop_config.json (Settings → Developer → Edit Config):
{
"mcpServers": {
"searchcode-private": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://searchcode.example.com/v1/mcp",
"--header",
"Authorization:${SEARCHCODE_PRIVATE_TOKEN}"
],
"env": {
"SEARCHCODE_PRIVATE_TOKEN": "Bearer YOUR_KEY"
}
}
}
}
Needs Node.js. Quit Claude completely and reopen it afterwards.
Devin Desktop (formerly Windsurf)
Sign in (OAuth)
~/.config/devin/mcp_config.json:
{
"mcpServers": {
"searchcode-private": {
"serverUrl": "https://searchcode.example.com/v1/mcp"
}
}
}
With a key
~/.config/devin/mcp_config.json:
{
"mcpServers": {
"searchcode-private": {
"serverUrl": "https://searchcode.example.com/v1/mcp",
"headers": {
"Authorization": "Bearer ${env:SEARCHCODE_PRIVATE_TOKEN}"
}
}
}
}
Any other client
Sign in (OAuth)
The client's MCP configuration:
{
"mcpServers": {
"searchcode-private": {
"type": "http",
"url": "https://searchcode.example.com/v1/mcp"
}
}
}
The de facto shape most clients accept. Any client that speaks streamable HTTP will work.
With a key (written into the file, because an unknown client may not interpolate environment variables)
The client's MCP configuration:
{
"mcpServers": {
"searchcode-private": {
"type": "http",
"url": "https://searchcode.example.com/v1/mcp",
"headers": {
"Authorization": "Bearer YOUR_KEY"
}
}
}
}
A client not listed here
Any client that speaks MCP over streamable HTTP works with the "Any other
client" shape above. Each row was checked against that client's own
documentation on the date recorded in pkg/mcpclients. A client is added once
its format has been checked, and the table is what both this page and
/account render.