Integrating External Services

TeamDay agents connect to external services through MCP servers β€” lightweight processes that expose tools from APIs, databases, and other systems. This guide covers practical patterns for giving your agents access to the services they need.

For MCP fundamentals, see What Are MCP Servers?. For installation, see Installing MCP Servers.


How Integrations Work

When you want an agent to interact with an external service (database, analytics platform, messaging system), you:

  1. Install an MCP server that provides tools for that service
  2. Store credentials as Space secrets
  3. Reference secrets in MCP configuration via ${VAR_NAME} syntax

The agent then accesses the service through MCP tools β€” no custom code needed.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Agent                                              β”‚
β”‚   "Query last week's page views"                   β”‚
β”‚                                                    β”‚
β”‚   β†’ calls mcp__google-analytics__run_report        β”‚
β”‚   β†’ MCP server handles auth, API call              β”‚
β”‚   β†’ returns structured data to agent               β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Common Integrations

Google Analytics (GA4)

# Install via CLI
teamday mcps create \
  --name "google-analytics" \
  --type stdio \
  --command "pipx" \
  --args '["run", "google-analytics-mcp"]'

# Store credentials
teamday spaces set-secret <space-id> \
  GA_PROPERTY_ID=123456789

Or via .mcp.json in the Space:

{
  "mcpServers": {
    "google-analytics": {
      "command": "pipx",
      "args": ["run", "google-analytics-mcp"],
      "env": {
        "GA_PROPERTY_ID": "${GA_PROPERTY_ID}"
      }
    }
  }
}

Google Search Console β€” Available as an OAuth integration. Connect via Space settings in the web app.

Databases

PostgreSQL

{
  "mcpServers": {
    "postgres": {
      "command": "npx",
      "args": ["-y", "@anthropic-ai/mcp-postgres", "${DATABASE_URL}"]
    }
  }
}
teamday spaces set-secret <space-id> \
  DATABASE_URL="postgres://user:pass@host:5432/dbname"

The agent gets tools like mcp__postgres__query to run SQL queries directly.

Version Control

GitHub

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

Provides tools for issues, PRs, repo management, and code search.

Brave Search

{
  "mcpServers": {
    "brave-search": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-brave-search"],
      "env": {
        "BRAVE_API_KEY": "${BRAVE_API_KEY}"
      }
    }
  }
}

Communication

Slack

{
  "mcpServers": {
    "slack": {
      "command": "npx",
      "args": ["-y", "@anthropic-ai/mcp-slack"],
      "env": {
        "SLACK_BOT_TOKEN": "${SLACK_BOT_TOKEN}"
      }
    }
  }
}

Credential Management

Space Secrets

Store sensitive values as encrypted Space secrets. Never hardcode credentials in .mcp.json.

Via CLI:

teamday spaces set-secret <space-id> \
  API_KEY=sk-abc123 \
  DATABASE_URL=postgres://user:pass@host/db

Via API:

curl -X POST "https://us.teamday.ai/api/v1/spaces/<space-id>/secrets" \
  -H "Authorization: Bearer $TEAMDAY_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"secrets": {"API_KEY": "sk-abc123"}}'

Secret names must be UPPER_SNAKE_CASE.

Variable References

In .mcp.json, reference secrets with ${VAR_NAME}:

{
  "mcpServers": {
    "my-service": {
      "command": "node",
      "args": ["server.js"],
      "env": {
        "API_KEY": "${MY_API_KEY}",
        "API_SECRET": "${MY_API_SECRET}",
        "BASE_URL": "${SERVICE_URL}"
      }
    }
  }
}

The runtime resolves these from the Space's stored secrets before starting the MCP process.

OAuth Integrations

Some services use OAuth instead of API keys. These are connected through the web app:

  1. Open Space settings
  2. Find the integration (e.g., Google Analytics)
  3. Click Connect and complete the OAuth flow
  4. Tokens are managed automatically (refresh, re-auth prompts)

Multiple Integrations

A Space can run many MCP servers simultaneously. Each runs as a separate process:

{
  "mcpServers": {
    "postgres": {
      "command": "npx",
      "args": ["-y", "@anthropic-ai/mcp-postgres", "${DATABASE_URL}"]
    },
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN}"
      }
    },
    "brave-search": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-brave-search"],
      "env": {
        "BRAVE_API_KEY": "${BRAVE_API_KEY}"
      }
    }
  }
}

All tools from all servers are available to the agent. Tool names follow the pattern mcp__{server}__{tool} (e.g., mcp__postgres__query).


Custom Integrations

If no pre-built MCP server exists for your service, you can build one:

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

const server = new McpServer({
  name: "my-service",
  version: "1.0.0",
});

server.tool(
  "get_data",
  "Fetch data from My Service",
  { query: z.string() },
  async ({ query }) => {
    const response = await fetch(`https://api.myservice.com/data?q=${query}`, {
      headers: { Authorization: `Bearer ${process.env.API_KEY}` },
    });
    const data = await response.json();
    return { content: [{ type: "text", text: JSON.stringify(data) }] };
  }
);

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

See Creating Custom MCP Servers for the full guide.


Calling TeamDay from External Systems

You can also integrate TeamDay into your existing systems by calling the TeamDay API:

Webhook Handler

app.post('/webhook/new-order', async (req, res) => {
  const { orderId, customerEmail } = req.body;

  await fetch('https://us.teamday.ai/api/v1/agents/AGENT_ID/execute', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.TEAMDAY_API_TOKEN}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      message: `New order ${orderId} from ${customerEmail}. Process and send confirmation.`,
      spaceId: 'SPACE_ID',
    }),
  });

  res.json({ status: 'ok' });
});

CI/CD Pipeline

# GitHub Actions
- name: Post-deploy analysis
  env:
    TEAMDAY_API_TOKEN: ${{ secrets.TEAMDAY_TOKEN }}
  run: |
    curl -X POST "https://us.teamday.ai/api/v1/agents/$AGENT_ID/execute" \
      -H "Authorization: Bearer $TEAMDAY_API_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{"message": "Deployment complete. Run health checks."}'

See API & Automation for more patterns.


Best Practices

  • One MCP per service β€” don't combine unrelated services in a single MCP
  • Secrets, not hardcoded values β€” always use ${VAR_NAME} references
  • Least privilege β€” give API keys only the permissions the agent needs
  • Start new conversations β€” MCP servers load at conversation start; after adding an MCP, start a new chat
  • Test MCPs locally first β€” run the MCP command manually to verify it works before deploying

Next Steps