Skip to content

MCP Protocol

How AI assistants communicate with tools.

What is MCP?

MCP (Model Context Protocol) is an open standard that enables AI assistants to interact with external tools and data sources. It provides a structured way for AI models to:

  • Discover available tools
  • Call tools with parameters
  • Receive structured results

How MCP Works

sequenceDiagram
    participant User
    participant AI as AI Assistant
    participant Server as MCP Server
    participant DataHub

    User->>AI: "Search for customer datasets"
    AI->>Server: ListTools()
    Server-->>AI: [datahub_search, datahub_get_entity, ...]
    AI->>Server: CallTool(datahub_search, {query: "customer"})
    Server->>DataHub: GraphQL Query
    DataHub-->>Server: Results
    Server-->>AI: Tool Result
    AI->>User: "I found 5 customer datasets..."

MCP Components

Server

The MCP server provides tools to AI assistants. mcp-datahub is an MCP server.

flowchart TB
    subgraph MCP Server
        tools[Tools Registry]
        handler[Request Handler]
        transport[Transport Layer]
    end

    client[AI Assistant] <--> transport
    transport <--> handler
    handler <--> tools

Tools

Tools are functions that AI assistants can call. Each tool has:

Property Description
Name Unique identifier
Description What the tool does
Input Schema Parameters the tool accepts
Handler Function that executes the tool

Example tool definition:

{
  "name": "datahub_search",
  "description": "Search for datasets, dashboards, and other assets in DataHub",
  "inputSchema": {
    "type": "object",
    "properties": {
      "query": {
        "type": "string",
        "description": "Search query"
      },
      "entity_type": {
        "type": "string",
        "description": "Filter by entity type"
      },
      "limit": {
        "type": "integer",
        "description": "Maximum results"
      }
    },
    "required": ["query"]
  }
}

Transport

MCP supports multiple transport mechanisms:

Transport Use Case
stdio Local process communication
HTTP/SSE Remote server communication
WebSocket Bidirectional streaming

mcp-datahub uses stdio transport by default for Claude Desktop integration.

MCP Message Flow

Tool Discovery

sequenceDiagram
    participant Client as AI Client
    participant Server as MCP Server

    Client->>Server: initialize
    Server-->>Client: {serverInfo, capabilities}
    Client->>Server: tools/list
    Server-->>Client: {tools: [...]}

Tool Execution

sequenceDiagram
    participant Client as AI Client
    participant Server as MCP Server

    Client->>Server: tools/call {name, arguments}
    Server->>Server: Execute handler
    Server-->>Client: {content: [...], isError: false}

Why MCP for DataHub?

Standardized Interface

MCP provides a standard way for any AI assistant to access DataHub:

  • Claude (Anthropic)
  • ChatGPT (OpenAI)
  • Other AI assistants

Type-Safe Parameters

The input schema ensures AI assistants pass correct parameters:

{
  "query": "customer",
  "entity_type": "DATASET",
  "limit": 10
}

Structured Responses

Tools return structured data that AI can process:

{
  "content": [
    {
      "type": "text",
      "text": "{\"entities\": [...], \"total\": 42}"
    }
  ]
}

Composability

Multiple MCP servers can be combined:

flowchart TB
    ai[AI Assistant]

    subgraph MCP Servers
        datahub[mcp-datahub]
        trino[mcp-trino]
        s3[mcp-s3]
    end

    ai --> datahub
    ai --> trino
    ai --> s3

MCP in mcp-datahub

Server Creation

server := mcp.NewServer(&mcp.Implementation{
    Name:    "mcp-datahub",
    Version: "0.2.0",
}, nil)

Tool Registration

toolkit := tools.NewToolkit(datahubClient)
toolkit.RegisterAll(server)

Running the Server

transport := &mcp.StdioTransport{}
server.Run(context.Background(), transport)

MCP Clients

Claude Desktop

Claude Desktop natively supports MCP servers. Configure in claude_desktop_config.json:

{
  "mcpServers": {
    "datahub": {
      "command": "mcp-datahub",
      "env": {
        "DATAHUB_URL": "https://datahub.example.com",
        "DATAHUB_TOKEN": "token"
      }
    }
  }
}

Claude Code

Configure with the CLI:

claude mcp add datahub \
  -e DATAHUB_URL=https://datahub.example.com \
  -e DATAHUB_TOKEN=token \
  -- mcp-datahub

Cursor

Cursor supports MCP through its settings.

Custom Clients

Build your own MCP client using the SDK:

client := mcp.NewClient(&mcp.Implementation{
    Name:    "my-client",
    Version: "1.0.0",
})

transport := &mcp.StdioTransport{
    Cmd: exec.Command("mcp-datahub"),
}

client.Connect(ctx, transport)

// List tools
tools, _ := client.ListTools(ctx)

// Call a tool
result, _ := client.CallTool(ctx, &mcp.CallToolRequest{
    Name: "datahub_search",
    Arguments: map[string]any{
        "query": "customer",
    },
})

Security Considerations

Tool Permissions

MCP servers control what tools are available:

// Only register specific tools
toolkit.Register(server,
    tools.ToolSearch,
    tools.ToolGetEntity,
)
// Dangerous tools not registered

Input Validation

Tool handlers validate input:

func searchHandler(ctx context.Context, req *mcp.CallToolRequest) (*mcp.CallToolResult, error) {
    query, ok := req.Arguments["query"].(string)
    if !ok || query == "" {
        return tools.ErrorResult("query is required"), nil
    }
    // ...
}

Authentication

Add authentication via middleware:

toolkit := tools.NewToolkit(client,
    tools.WithMiddleware(authMiddleware),
)