StackMCP
Blog
·7 min read

How to Set Up MCP Servers in Windsurf: Complete Guide

Step-by-step guide to configuring MCP servers in Windsurf. Learn where the config file lives, the JSON format differences, and how to troubleshoot setup issues.

mcpwindsurfsetupguide

Windsurf by Codeium is an AI-powered code editor with built-in support for MCP (Model Context Protocol) servers. This means you can connect your AI assistant -- Windsurf calls it Cascade -- to external tools like databases, browsers, GitHub, and documentation services. The setup is straightforward, but Windsurf has a few quirks in its config format that catch people off guard if they are coming from Cursor or Claude Desktop.

This guide covers everything: where the config file lives, the exact JSON format Windsurf expects, how to configure both local and remote servers, and how to fix the issues that most commonly go wrong.

Where Windsurf Stores Its MCP Config

Windsurf reads MCP server definitions from a JSON file at a specific location depending on your operating system:

macOS:

~/.codeium/windsurf/mcp_config.json

Linux:

~/.codeium/windsurf/mcp_config.json

Windows:

%USERPROFILE%\.codeium\windsurf\mcp_config.json

Note the path: it is .codeium/windsurf/, not .windsurf/. This catches people who guess the path based on the editor name. The file is called mcp_config.json, not mcp.json.

If the directory does not exist yet, create it:

mkdir -p ~/.codeium/windsurf
touch ~/.codeium/windsurf/mcp_config.json

Windsurf currently only supports a global config. There is no project-level MCP configuration like Cursor offers. All servers defined in mcp_config.json are available across every project you open.

The Config Format

Windsurf uses a JSON format that is similar to Cursor and Claude Desktop, but not identical. Here is a minimal example:

{
  "mcpServers": {
    "context7": {
      "command": "npx",
      "args": ["-y", "@upstash/context7-mcp@latest"]
    }
  }
}

This looks familiar if you have configured MCP servers in other clients. The structure is an mcpServers object where each key is the server name and each value defines how to start it.

Standard Fields

command: The executable that starts the server. Usually npx for npm packages, uvx or python for Python servers, or docker for containerized servers.

args: An array of command-line arguments. For npm packages, this typically includes -y (auto-confirm) and the package name.

env: An object of environment variables passed to the server process. API keys and access tokens go here.

The "serverUrl" Difference for HTTP Servers

Here is where Windsurf diverges from other clients. When configuring a remote MCP server that communicates over HTTP or SSE, Windsurf uses serverUrl instead of the url field that Cursor and other clients use:

Cursor (uses url):

{
  "mcpServers": {
    "remote-server": {
      "url": "https://mcp.example.com/sse"
    }
  }
}

Windsurf (uses serverUrl):

{
  "mcpServers": {
    "remote-server": {
      "serverUrl": "https://mcp.example.com/sse"
    }
  }
}

If you copy a remote server configuration from Cursor docs or another client's documentation and use url, Windsurf will silently ignore it. The server will not connect and you will get no error message explaining why. Switch url to serverUrl and it works.

This is the single most common configuration mistake in Windsurf MCP setup.

Example Server Configurations

GitHub MCP

{
  "mcpServers": {
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_your_token_here"
      }
    }
  }
}

Requires a GitHub personal access token with repo scope. Generate one at github.com/settings/tokens.

Supabase MCP

{
  "mcpServers": {
    "supabase": {
      "command": "npx",
      "args": ["-y", "@supabase/mcp-server-supabase@latest"],
      "env": {
        "SUPABASE_ACCESS_TOKEN": "sbp_your_token_here"
      }
    }
  }
}

Context7 MCP

{
  "mcpServers": {
    "context7": {
      "command": "npx",
      "args": ["-y", "@upstash/context7-mcp@latest"]
    }
  }
}

No API key required.

Playwright MCP

{
  "mcpServers": {
    "playwright": {
      "command": "npx",
      "args": ["-y", "@playwright/mcp"]
    }
  }
}

No API key required. Launches a browser locally.

Multiple Servers Together

{
  "mcpServers": {
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_your_token_here"
      }
    },
    "supabase": {
      "command": "npx",
      "args": ["-y", "@supabase/mcp-server-supabase@latest"],
      "env": {
        "SUPABASE_ACCESS_TOKEN": "sbp_your_token_here"
      }
    },
    "context7": {
      "command": "npx",
      "args": ["-y", "@upstash/context7-mcp@latest"]
    },
    "playwright": {
      "command": "npx",
      "args": ["-y", "@playwright/mcp"]
    }
  }
}

Step-by-Step Setup

1. Create the config directory and file

mkdir -p ~/.codeium/windsurf

Then create mcp_config.json:

touch ~/.codeium/windsurf/mcp_config.json

2. Add your server configuration

Open the file in any editor and paste your config. Start with a single server to verify the setup works:

{
  "mcpServers": {
    "context7": {
      "command": "npx",
      "args": ["-y", "@upstash/context7-mcp@latest"]
    }
  }
}

3. Reload Windsurf

After saving the file, you need to reload Windsurf for it to pick up the new configuration. You can do this through:

  • The command palette (Cmd+Shift+P on macOS, Ctrl+Shift+P on Windows/Linux), then search for "Reload Window"
  • Or simply close and reopen Windsurf

4. Verify the connection

Open Windsurf's Cascade panel and check for MCP server status indicators. You should see your server listed as connected. Test it by asking Cascade to use one of the server's tools. For Context7, try: "Look up the Next.js documentation for server components." If Cascade calls the Context7 tool and returns results, the setup is working.

5. Check the MCP tools panel

Windsurf provides a dedicated view of available MCP tools. You can access this through the settings or the Cascade interface. This panel shows which servers are connected, how many tools each one provides, and lets you verify that everything loaded correctly.

Troubleshooting Common Issues

Server does not appear after config change

The most common cause: Windsurf did not reload. MCP configuration is read at startup and on reload, not dynamically. Always reload after editing mcp_config.json.

Second most common cause: JSON syntax errors. Unlike YAML, JSON does not tolerate trailing commas. Validate your file:

python3 -c "import json; json.load(open('$HOME/.codeium/windsurf/mcp_config.json'))"

If this command outputs nothing, your JSON is valid. If it throws an error, fix the syntax issue it points to.

"Server failed to start"

This means the command could not be executed. Check:

  • Node.js is installed: run node --version in your terminal. If it is not found, install Node.js first.
  • Package name is correct: a typo in the package name in args will cause npx to fail.
  • Network access: npx downloads packages on first run. If you are behind a proxy, configure npm's proxy settings.

Test by running the command directly:

npx -y @upstash/context7-mcp@latest

Remote server not connecting

If you are configuring a remote HTTP/SSE server and it is not connecting:

  1. Verify you are using serverUrl, not url.
  2. Check that the URL is correct and the remote server is actually running.
  3. If the server requires authentication, ensure headers or tokens are configured correctly.

Environment variable issues

  • Variable names are case-sensitive. GITHUB_PERSONAL_ACCESS_TOKEN is not the same as github_personal_access_token.
  • Copy tokens fresh from the source dashboard. Trailing spaces or newlines in a pasted token will cause authentication failures.
  • Some servers require multiple environment variables. Check the server's documentation for the complete list.

Tools load but Cascade does not use them

Windsurf's Cascade needs to be in the right mode to use MCP tools. Make sure you are using a model and mode that supports tool calling. In standard chat mode, Cascade may not invoke MCP tools even if they are available.

Also keep in mind that running too many servers increases the token overhead. Each server's tool definitions consume context window space. If you are running five or more servers, the tool definitions alone might take up a significant portion of the available context, leaving less room for your code and conversation.

Migrating configs from Cursor

If you are switching from Cursor to Windsurf (or using both), the config migration is straightforward:

  1. Copy the mcpServers object from your Cursor .cursor/mcp.json file.
  2. Paste it into Windsurf's ~/.codeium/windsurf/mcp_config.json.
  3. Replace any "url" fields with "serverUrl" for remote servers.
  4. Local stdio servers (using command and args) work identically in both clients with no changes needed.

Best Servers to Start With in Windsurf

If you are setting up MCP servers in Windsurf for the first time, start with these three:

Context7 MCP -- pulls live documentation into your conversations. No API key, two tools, minimal overhead. The immediate benefit is that Cascade stops giving you outdated API suggestions.

GitHub MCP -- if you work with GitHub repositories (and most developers do), this server lets Cascade manage PRs, search issues, and review code without browser switching.

Supabase MCP (or your database server of choice) -- direct database access from your editor eliminates the most common context switch in fullstack development: checking the dashboard to remember table structures.

Add more servers as you identify gaps. The key is to keep your active server count manageable so each one is actually earning its token cost.

Managing Secrets

Since mcp_config.json contains API tokens:

  • Do not add ~/.codeium/windsurf/ to any version-controlled directory.
  • If you share your configuration with teammates, strip out real tokens and replace them with placeholder values.
  • Rotate tokens periodically, especially for services like GitHub where the token grants broad access.

Generate Configs for Windsurf

Getting the config format right -- remembering serverUrl instead of url, the correct file path, which environment variables each server needs -- takes trial and error. stackmcp.dev generates ready-to-use MCP configurations specifically formatted for Windsurf. Pick a stack (frontend developer, fullstack web, indie hacker, etc.), select Windsurf as your client, and get a config you can paste directly into mcp_config.json.

It handles the Windsurf-specific format differences automatically, so you do not have to remember which fields are named differently or where the config file should go. Copy, paste, fill in your API tokens, reload Windsurf, and you are running.

Related Stacks

Related Servers