.do

Integration Guide

Integrate MCP.do with Claude, AI models, and applications

Comprehensive guide to integrating MCP.do with AI models, applications, and development tools.

Claude Desktop Integration

Integration Architecture

graph LR subgraph "AI Clients" CLAUDE[Claude Desktop] CODE[Claude Code] CHAT[ChatGPT] CUSTOM[Custom Apps] end subgraph "MCP Transport" SSE[SSE Transport<br/>Long-lived] HTTP[HTTP JSON-RPC<br/>Request/Response] end subgraph "MCP.do Server" AUTH[Authentication] TOOLS[do + elicit Tools] EXEC[Execution Engine] end subgraph "Platform" SDK[SDK Primitives] PAYLOAD[Payload CMS] WORKERS[90+ Workers] end CLAUDE --> SSE CODE --> SSE CHAT --> HTTP CUSTOM --> HTTP SSE --> AUTH HTTP --> AUTH AUTH --> TOOLS TOOLS --> EXEC EXEC --> SDK SDK --> PAYLOAD SDK --> WORKERS

Configuration

Add to Claude Desktop config (~/Library/Application Support/Claude/claude_desktop_config.json):

{
  "mcpServers": {
    "do": {
      "url": "https://mcp.do",
      "type": "sse",
      "headers": {
        "Authorization": "Bearer sk_live_xxxxx"
      }
    }
  }
}
{
  "mcpServers": {
    "do": {
      "url": "https://mcp.do",
      "type": "sse",
      "oauth": {
        "authorizationServer": "https://oauth.do",
        "clientId": "your_client_id",
        "scopes": ["mcp:tools", "mcp:resources"]
      }
    }
  }
}

Usage in Claude

User: List all businesses in the platform

Claude: I'll use the do tool to query businesses.
[Uses do tool with script: await db.list('Business')]

Found 15 businesses:
1. Acme Corp
2. Widget Inc
...

Claude Code Integration

Direct SDK Integration

import { MCPClient } from '@modelcontextprotocol/sdk/client/index.js'
import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js'

// Create transport
const transport = new SSEClientTransport(new URL('https://mcp.do'), {
  headers: {
    Authorization: 'Bearer sk_live_xxxxx',
  },
})

// Create client
const client = new MCPClient({ name: 'my-app', version: '1.0.0' }, {})

// Connect
await client.connect(transport)

// List available tools
const { tools } = await client.listTools()
console.log('Tools:', tools)

// Execute operations
const result = await client.callTool('do', {
  script: 'await db.list("Business")',
})

console.log('Result:', result.content[0].text)

Helper Class

class DoClient {
  private client: MCPClient

  private constructor(apiKey: string) {
    const transport = new SSEClientTransport(new URL('https://mcp.do'), { headers: { Authorization: `Bearer ${apiKey}` } })
    this.client = new MCPClient({ name: 'do-client', version: '1.0.0' }, {})
  }

  static async create(apiKey: string): Promise<DoClient> {
    const client = new DoClient(apiKey)
    await client.client.connect(client.client['transport'])
    return client
  }

  async execute(script: string) {
    const result = await this.client.callTool('do', { script })
    return JSON.parse(result.content[0].text)
  }

  async elicit(message: string, schema: object) {
    const result = await this.client.callTool('elicit', {
      message,
      schema,
    })
    return JSON.parse(result.content[0].text)
  }

  async close() {
    await this.client.close()
  }
}

// Usage
const client = await DoClient.create(process.env.DO_API_KEY!)
const businesses = await client.execute('await db.list("Business")')
console.log(businesses)
await client.close()

Node.js Application

Basic Integration

import { MCPClient } from '@modelcontextprotocol/sdk'

// Initialize client
const client = new MCPClient({
  serverUrl: 'https://mcp.do',
  apiKey: process.env.DO_API_KEY,
  transport: 'sse',
})

// Execute operations
async function createOrder(customerEmail: string, items: any[]) {
  try {
    const result = await client.useTool('do', {
      script: `
        const customers = await db.list('Customer', { email: \`${customerEmail}\` })
        if (customers.length === 0) {
          throw new Error('Customer not found')
        }
        const customer = customers[0]
        const order = await db.create('Order', {
          customer: customer,
          items: ${JSON.stringify(items)},
          status: 'pending'
        })
        await send($.Email.send, {
          to: customer.email,
          subject: 'Order Confirmation',
          body: \`Order #\${order.id} created\`
        })
        return order
      `,
    })
    if (result.isError) {
      throw new Error(result.content[0].text)
    }
    return result
  } catch (error) {
    console.error('Failed to create order:', error)
    throw error
  }
}

// Use with async/await
const order = await createOrder('[email protected]', [{ product: 'widget', quantity: 2 }])

Express.js Middleware

import express from 'express'
import { MCPClient } from '@modelcontextprotocol/sdk'

const app = express()
const mcpClient = new MCPClient({
  serverUrl: 'https://mcp.do',
  apiKey: process.env.DO_API_KEY,
})

// Middleware to attach MCP client
app.use((req, res, next) => {
  req.mcp = mcpClient
  next()
})

// Route using MCP
app.post('/api/orders', async (req, res) => {
  try {
    const order = await req.mcp.useTool('do', {
      script: `
        await db.create('Order', ${JSON.stringify(req.body)})
      `,
    })
    res.json(order)
  } catch (error) {
    res.status(500).json({ error: error.message })
  }
})

app.listen(3000)

Python Integration

Using MCP SDK

from mcp import Client
import asyncio
import os

async def main():
    # Create client
    client = Client(
        server_url="https://mcp.do",
        api_key=os.environ['DO_API_KEY'],
        transport='sse'
    )

    # Connect
    await client.connect()

    # List tools
    tools = await client.list_tools()
    print(f"Available tools: {tools}")

    # Execute operation
    result = await client.call_tool('do', {
        'script': 'await db.list("Business")'
    })
    print(f"Result: {result}")

    # Close connection
    await client.close()

# Run
asyncio.run(main())

FastAPI Integration

from fastapi import FastAPI, Depends
from mcp import Client
import os

app = FastAPI()

# MCP client dependency
async def get_mcp_client():
    client = Client(
        server_url="https://mcp.do",
        api_key=os.environ['DO_API_KEY']
    )
    await client.connect()
    try:
        yield client
    finally:
        await client.close()

@app.post("/api/orders")
async def create_order(
    order_data: dict,
    mcp: Client = Depends(get_mcp_client)
):
    result = await mcp.call_tool('do', {
        'script': f'await db.create("Order", {order_data})'
    })
    return result

LangChain Integration

Custom Tool

import { Tool } from 'langchain/tools'
import { MCPClient } from '@modelcontextprotocol/sdk'

class DoTool extends Tool {
  name = 'do'
  description = 'Execute TypeScript against the .do platform SDK'

  private client: MCPClient

  constructor() {
    super()
    this.client = new MCPClient({
      serverUrl: 'https://mcp.do',
      apiKey: process.env.DO_API_KEY,
    })
  }

  async _call(script: string): Promise<string> {
    const result = await this.client.useTool('do', { script })
    return result.content[0].text
  }
}

// Use with LangChain agent
import { initializeAgentExecutorWithOptions } from 'langchain/agents'
import { ChatOpenAI } from 'langchain/chat_models/openai'

const tools = [new DoTool()]
const model = new ChatOpenAI({ temperature: 0 })

const executor = await initializeAgentExecutorWithOptions(tools, model, { agentType: 'chat-conversational-react-description' })

const result = await executor.call({
  input: 'List all businesses and create a summary report',
})

React Application

Custom Hook

import { useState, useEffect } from 'react'
import { MCPClient } from '@modelcontextprotocol/sdk'

export function useMCP(apiKey: string) {
  const [client, setClient] = useState<MCPClient | null>(null)
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<Error | null>(null)

  useEffect(() => {
    let mounted = true
    let mcpClient: MCPClient | null = null

    const initClient = async () => {
      try {
        mcpClient = new MCPClient({
          serverUrl: 'https://mcp.do',
          apiKey
        })
        await mcpClient.connect()
        if (mounted) {
          setClient(mcpClient)
          setLoading(false)
        }
      } catch (err) {
        if (mounted) {
          setError(err instanceof Error ? err : new Error('Failed to connect'))
          setLoading(false)
        }
      }
    }
    initClient()

    return () => {
      mounted = false
      mcpClient?.close()
    }
  }, [apiKey])

  const execute = async (script: string) => {
    if (!client) throw new Error('Client not initialized')
    return await client.useTool('do', { script })
  }

  const elicit = async (message: string, schema: object) => {
    if (!client) throw new Error('Client not initialized')
    return await client.useTool('elicit', { message, schema })
  }

  return { client, loading, error, execute, elicit }
}

// Usage in component
function BusinessList() {
  const { execute, loading } = useMCP(process.env.REACT_APP_DO_API_KEY!)
  const [businesses, setBusinesses] = useState([])

  useEffect(() => {
    if (!loading) {
      execute('await db.list("Business")').then(result => {
        setBusinesses(JSON.parse(result.content[0].text))
      })
    }
  }, [loading])

  return (
    <ul>
      {businesses.map(b => <li key={b.id}>{b.name}</li>)}
    </ul>
  )
}

REST API Wrapper

Create HTTP Gateway

import express from 'express'
import { MCPClient } from '@modelcontextprotocol/sdk'

const app = express()
app.use(express.json())

// MCP client
const mcp = new MCPClient({
  serverUrl: 'https://mcp.do',
  apiKey: process.env.DO_API_KEY,
})

// Execute endpoint
app.post('/api/execute', async (req, res) => {
  try {
    const { script } = req.body
    const result = await mcp.useTool('do', { script })
    res.json(result)
  } catch (error) {
    res.status(500).json({ error: error.message })
  }
})

// Elicit endpoint
app.post('/api/elicit', async (req, res) => {
  try {
    const { message, schema, uiType } = req.body
    const result = await mcp.useTool('elicit', {
      message,
      schema,
      uiType,
    })
    res.json(result)
  } catch (error) {
    res.status(500).json({ error: error.message })
  }
})

app.listen(3000)

CI/CD Integration

GitHub Actions

name: Deploy with MCP

on: [push]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Deploy via MCP
        run: |
          npx tsx deploy.ts
        env:
          DO_API_KEY: ${{ secrets.DO_API_KEY }}

deploy.ts:

import { MCPClient } from '@modelcontextprotocol/sdk'

const client = new MCPClient({
  serverUrl: 'https://mcp.do',
  apiKey: process.env.DO_API_KEY!,
})

await client.connect()

// Deploy worker
await client.useTool('do', {
  script: `
    const code = await api.fetch('https://raw.githubusercontent.com/...')
    await send($.Worker.deploy, { name: 'api', code })
  `,
})

console.log('Deployment complete')
await client.close()

Best Practices

1. Connection Management

// ✅ Reuse connection
const client = new MCPClient({ ... })
await client.connect()

// Multiple operations
await client.useTool('do', { ... })
await client.useTool('do', { ... })

await client.close()

// ❌ Don't create new connection per request
async function execute(script) {
  const client = new MCPClient({ ... })
  await client.connect()
  const result = await client.useTool('do', { script })
  await client.close()
  return result
}

2. Error Handling

try {
  const result = await client.useTool('do', { script })
  if (result.isError) {
    console.error('Execution error:', result.content[0].text)
  }
} catch (error) {
  if (error.status === 429) {
    // Rate limit - retry with backoff
  } else if (error.status === 401) {
    // Auth failed - refresh token
  } else {
    throw error
  }
}

3. Type Safety

// Define types for results
interface Business {
  id: string
  name: string
  email: string
}

async function getBusinesses(): Promise<Business[]> {
  const result = await client.useTool('do', {
    script: 'await db.list("Business")',
  })
  return JSON.parse(result.content[0].text) as Business[]
}

4. Security

// ❌ Don't expose API key
const client = new MCPClient({
  apiKey: 'sk_live_xxxxx', // Hardcoded!
})

// ✅ Use environment variables
const client = new MCPClient({
  apiKey: process.env.DO_API_KEY,
})

// ✅ Use OAuth for user-facing apps
const client = new MCPClient({
  serverUrl: 'https://mcp.do',
  oauth: {
    authorizationServer: 'https://oauth.do',
    clientId: process.env.OAUTH_CLIENT_ID,
  },
})

Next Steps