Skip to main content
Superset supports the Model Context Protocol (MCP), allowing coding agents to interact with external tools, databases, APIs, and services through a standardized interface.

What is MCP?

MCP (Model Context Protocol) is an open protocol that enables AI agents to securely connect to external data sources and tools. Think of it as a plugin system for AI agents.
MCP servers expose tools, resources, and prompts that agents can use during execution.

Benefits

Extend Agent Capabilities

Give agents access to databases, APIs, file systems, and more without modifying agent code.

Secure Access

MCP handles authentication and authorization, keeping credentials secure.

Standardized Interface

One protocol works with all compatible agents and tools.

Composable

Combine multiple MCP servers to build powerful workflows.

How Superset Uses MCP

Superset integrates MCP in two ways:
  1. Built-in MCP Server: Superset exposes its own MCP server that allows agents to create workspaces, switch between them, manage tasks, and more.
  2. MCP Client: Superset agents can connect to external MCP servers like Neon, Linear, Sentry, and custom servers.

Configuring MCP Servers

MCP servers are configured in .mcp.json at the root of your repository:
.mcp.json
{
  "mcpServers": {
    "superset": {
      "type": "http",
      "url": "https://api.superset.sh/api/agent/mcp"
    },
    "neon": {
      "type": "http",
      "url": "https://mcp.neon.tech/mcp"
    },
    "linear": {
      "type": "http",
      "url": "https://mcp.linear.app/mcp"
    },
    "desktop-automation": {
      "command": "bun",
      "args": ["run", "packages/desktop-mcp/src/bin.ts"]
    }
  }
}

Server Types

Remote MCP servers accessed via HTTP/HTTPS:
{
  "servername": {
    "type": "http",
    "url": "https://mcp.example.com/mcp"
  }
}
Remote servers handle authentication on their end, often via OAuth.

OpenCode Configuration

For agents using OpenCode, MCP servers are configured in opencode.json:
opencode.json
{
  "$schema": "https://opencode.ai/config.json",
  "permission": {
    "external_directory": "allow"
  },
  "mcp": {
    "superset": {
      "type": "remote",
      "url": "https://api.superset.sh/api/agent/mcp",
      "oauth": {}
    },
    "neon": {
      "type": "remote",
      "url": "https://mcp.neon.tech/mcp"
    },
    "maestro": {
      "type": "local",
      "command": ["maestro", "mcp"]
    },
    "desktop-automation": {
      "type": "local",
      "command": ["bun", "run", "packages/desktop-mcp/src/bin.ts"]
    }
  }
}
OpenCode uses "type": "remote" and "type": "local" instead of "type": "http" and stdio configuration.

Available MCP Servers

Superset MCP Server

Superset’s built-in MCP server provides workspace and task management. URL: https://api.superset.sh/api/agent/mcp (production) or http://localhost:3001/api/agent/mcp (local) Available Tools:
ToolDescription
create_workspaceCreate a new workspace
delete_workspaceDelete a workspace
switch_workspaceSwitch to a different workspace
list_workspacesList all workspaces
get_workspace_detailsGet detailed workspace info
update_workspaceUpdate workspace metadata
list_projectsList available projects
create_taskCreate a new task
update_taskUpdate task status
delete_taskDelete a task
list_tasksList all tasks
get_taskGet task details
Example Usage:
# Agent creates a workspace
opencode "Create a workspace called 'fix-auth-bug' for the main project"

# Agent switches workspace
opencode "Switch to the 'add-dark-mode' workspace"

Neon MCP Server

Manage Neon PostgreSQL databases and branches. URL: https://mcp.neon.tech/mcp Tools: Create branches, delete branches, run queries, manage databases

Linear MCP Server

Interact with Linear issues and projects. URL: https://mcp.linear.app/mcp Tools: Create issues, update issues, list issues, manage projects

Sentry MCP Server

Access Sentry error tracking and monitoring. URL: https://mcp.sentry.dev/mcp Tools: List errors, get error details, resolve issues

Expo MCP Server

Manage Expo projects and builds. URL: https://mcp.expo.dev/mcp Tools: Start builds, check build status, manage releases
The Expo MCP server is disabled by default in Superset. Set "enabled": true to use it.

Maestro MCP Server

Mobile UI testing automation. Command: maestro mcp Type: Local (stdio) Tools: Run tests, capture screenshots, interact with mobile apps

Desktop Automation MCP Server

Control the Superset desktop app via Chrome DevTools Protocol. Command: bun run packages/desktop-mcp/src/bin.ts Type: Local (stdio) Available Tools:
ToolDescription
navigateNavigate to a URL
clickClick an element
type_textType text into an input
send_keysSend keyboard keys
take_screenshotCapture screenshot
inspect_domInspect DOM structure
evaluate_jsExecute JavaScript
get_window_infoGet window information
get_console_logsRetrieve console logs
Example Usage:
# Agent tests the UI
opencode "Open localhost:3000, click the login button, and take a screenshot"

Building Custom MCP Servers

You can build your own MCP servers to integrate custom tools.

TypeScript Example

1

Install SDK

bun add @modelcontextprotocol/sdk
2

Create Server

server.ts
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

const server = new Server(
  {
    name: "my-mcp-server",
    version: "1.0.0",
  },
  {
    capabilities: {
      tools: {},
    },
  }
);

// Define a tool
server.setRequestHandler("tools/list", async () => ({
  tools: [
    {
      name: "get_weather",
      description: "Get weather for a location",
      inputSchema: z.object({
        location: z.string(),
      }),
    },
  ],
}));

// Handle tool calls
server.setRequestHandler("tools/call", async (request) => {
  if (request.params.name === "get_weather") {
    const { location } = request.params.arguments;
    // Fetch weather data...
    return {
      content: [
        {
          type: "text",
          text: `Weather in ${location}: Sunny, 72°F`,
        },
      ],
    };
  }
});

// Start server
const transport = new StdioServerTransport();
await server.connect(transport);
3

Register Server

Add to .mcp.json:
{
  "mcpServers": {
    "weather": {
      "command": "bun",
      "args": ["run", "server.ts"]
    }
  }
}
4

Use in Agent

opencode "What's the weather in San Francisco?"

Python Example

server.py
import asyncio
from mcp.server import Server
from mcp.server.stdio import stdio_server

app = Server("my-mcp-server")

@app.list_tools()
async def list_tools():
    return [
        {
            "name": "greet",
            "description": "Greet a user",
            "inputSchema": {
                "type": "object",
                "properties": {
                    "name": {"type": "string"}
                },
                "required": ["name"]
            }
        }
    ]

@app.call_tool()
async def call_tool(name, arguments):
    if name == "greet":
        username = arguments.get("name")
        return {
            "content": [
                {
                    "type": "text",
                    "text": f"Hello, {username}!"
                }
            ]
        }

async def main():
    async with stdio_server() as streams:
        await app.run(
            streams[0],
            streams[1],
            app.create_initialization_options()
        )

if __name__ == "__main__":
    asyncio.run(main())
Register in .mcp.json:
{
  "mcpServers": {
    "greeter": {
      "command": "python",
      "args": ["server.py"]
    }
  }
}

Local vs Remote Servers

Local (Stdio) Servers

Pros:
  • Full control over implementation
  • No network latency
  • Can access local file system and processes
  • Easy to debug
Cons:
  • Must be installed on every machine
  • No centralized updates
  • Process management required
Best for: File system access, local tools, development

Remote (HTTP) Servers

Pros:
  • Centrally hosted and updated
  • No client installation needed
  • Can scale independently
  • Easier to manage authentication
Cons:
  • Network latency
  • Requires internet connection
  • Harder to debug
Best for: APIs, databases, cloud services, shared tools

Authentication

OAuth for Remote Servers

Remote MCP servers often use OAuth for authentication. In OpenCode:
opencode.json
{
  "mcp": {
    "superset": {
      "type": "remote",
      "url": "https://api.superset.sh/api/agent/mcp",
      "oauth": {}
    }
  }
}
When an agent connects, Superset will prompt you to authenticate via browser.

Environment Variables for Local Servers

Local servers can read credentials from environment variables:
.env
GITHUB_TOKEN=ghp_xxxxxxxxxxxx
LINEAR_API_KEY=lin_api_xxxxxxxxxxxx
Access in your server:
const token = process.env.GITHUB_TOKEN;

Troubleshooting

If a local MCP server fails to start:
  1. Check that the command is correct in .mcp.json
  2. Verify the executable exists: which bun
  3. Test the command manually in terminal
  4. Check for error messages in agent output
  5. Make sure dependencies are installed
If agents don’t recognize MCP tools:
  1. Verify the server is configured in .mcp.json or opencode.json
  2. Restart the agent
  3. Check that tools/list handler is implemented
  4. Test with a simple tool first
If OAuth or auth fails:
  1. Check that credentials are set in environment variables
  2. Verify OAuth configuration in opencode.json
  3. Try re-authenticating: delete cached tokens
  4. Check server logs for auth errors
If remote MCP servers time out:
  1. Check internet connection
  2. Verify the URL is correct
  3. Check if the server is down (try in browser)
  4. Look for rate limiting or API quota issues

Best Practices

Start with Remote Servers

Use hosted MCP servers (Neon, Linear, Sentry) before building your own. They’re maintained and production-ready.

Keep Servers Simple

Each MCP server should do one thing well. Don’t build monolithic servers with dozens of tools.

Use Environment Variables

Never hardcode credentials. Use environment variables and .env files.

Document Your Tools

Provide clear descriptions for tools. Agents rely on descriptions to know when to use them.

Handle Errors Gracefully

Return helpful error messages. Agents need context to understand what went wrong.

Version Your Servers

Use semantic versioning for custom MCP servers. Breaking changes should increment major version.

Example: Full MCP Server

Here’s a complete example of a GitHub MCP server:
github-mcp.ts
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
import { Octokit } from "@octokit/rest";

const octokit = new Octokit({ auth: process.env.GITHUB_TOKEN });

const server = new Server(
  { name: "github-mcp", version: "1.0.0" },
  { capabilities: { tools: {} } }
);

server.setRequestHandler("tools/list", async () => ({
  tools: [
    {
      name: "list_issues",
      description: "List issues in a repository",
      inputSchema: z.object({
        owner: z.string(),
        repo: z.string(),
      }),
    },
    {
      name: "create_issue",
      description: "Create a new issue",
      inputSchema: z.object({
        owner: z.string(),
        repo: z.string(),
        title: z.string(),
        body: z.string().optional(),
      }),
    },
  ],
}));

server.setRequestHandler("tools/call", async (request) => {
  const { name, arguments: args } = request.params;

  try {
    if (name === "list_issues") {
      const { owner, repo } = args;
      const { data } = await octokit.issues.listForRepo({ owner, repo });
      return {
        content: [
          {
            type: "text",
            text: JSON.stringify(data, null, 2),
          },
        ],
      };
    }

    if (name === "create_issue") {
      const { owner, repo, title, body } = args;
      const { data } = await octokit.issues.create({
        owner,
        repo,
        title,
        body,
      });
      return {
        content: [
          {
            type: "text",
            text: `Created issue #${data.number}: ${data.html_url}`,
          },
        ],
      };
    }
  } catch (error) {
    return {
      content: [
        {
          type: "text",
          text: `Error: ${error.message}`,
        },
      ],
      isError: true,
    };
  }
});

const transport = new StdioServerTransport();
await server.connect(transport);
Register and use:
.mcp.json
{
  "mcpServers": {
    "github": {
      "command": "bun",
      "args": ["run", "github-mcp.ts"]
    }
  }
}
# Agent uses the GitHub MCP server
opencode "List all open issues in superset-sh/superset and create a new issue for the bug I just found"

Running Agents

Learn how agents use MCP tools

Setup Scripts

Configure MCP servers in setup scripts

Integrations

Connect Superset with external tools

MCP Specification

Read the full MCP specification

Build docs developers (and LLMs) love