Building Custom AI Agents with Antigravity and MCP — External API Integration
Learn how to build custom AI agents using Antigravity's MCP (Model Context Protocol) to integrate external REST APIs and Webhooks. This guide covers design, implementation, debugging, and production-ready patterns.
Antigravity provides powerful code generation and editing capabilities, but when you need to integrate external data sources or let AI operate your own APIs, the built-in features alone won't cut it.
That's where MCP (Model Context Protocol) comes in. With MCP, you can wrap external REST APIs and Webhooks as tools that AI can directly operate, effectively turning Antigravity into your own custom AI agent platform.
Understanding MCP Architecture
What Is MCP?
MCP (Model Context Protocol) is a standard protocol that enables AI models to interact with external tools and data sources. Antigravity natively supports MCP, so adding an MCP server instantly extends the AI's capabilities.
The MCP architecture consists of three layers:
Host (Antigravity): Runs the AI model and manages user interactions
MCP Client: Operates within the host and mediates communication with MCP servers
MCP Server: An independent process that exposes external tools and resources
Three Capabilities of MCP Servers
MCP servers can expose three types of capabilities:
Tools: Functions that AI can invoke — API calls, database queries, file operations, and more
Resources: Data sources that AI can read — config files, documentation, live data feeds
Prompts: Predefined prompt templates that simplify complex operations into shortcuts
✦
Thank you for reading this far.
Continue Reading
What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.
WHAT YOU'LL LEARN
✦Master the complete development flow from MCP server design and implementation to Antigravity integration
✦Build systems where AI autonomously calls external REST APIs wrapped as MCP tools
✦Learn production-ready patterns for error handling, rate limiting, and auth token management
Secure payment via Stripe · Cancel anytime
✦
Unlock This Article
Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.
After registration, simply type "What's the weather in Tokyo?" in Antigravity, and the AI will automatically invoke the get_weather tool to fetch the weather information.
Building a Practical Multi-API Agent
Designing a Project Management Agent
Real-world agents typically combine multiple APIs. Here's an example that integrates GitHub Issues and Slack into a project management agent:
// src/project-agent.tsimport { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";import { z } from "zod";const server = new McpServer({ name: "project-manager", version: "1.0.0",});// Fetch open issues from GitHubserver.tool( "list_open_issues", "List open issues from a GitHub repository", { repo: z.string().describe("Repository name (owner/repo format)"), labels: z .string() .optional() .describe("Filter labels (comma-separated)"), }, async ({ repo, labels }) => { const headers: Record<string, string> = { Accept: "application/vnd.github.v3+json", }; const token = process.env.GITHUB_TOKEN; if (token) { headers["Authorization"] = `Bearer ${token}`; } let url = `https://api.github.com/repos/${repo}/issues?state=open&per_page=20`; if (labels) { url += `&labels=${encodeURIComponent(labels)}`; } const response = await fetch(url, { headers }); if (!response.ok) { return { content: [ { type: "text", text: `GitHub API Error: ${response.status}` }, ], }; } const issues = await response.json(); const summary = issues .map( (issue: any) => `#${issue.number}: ${issue.title} [${issue.labels.map((l: any) => l.name).join(", ")}]` ) .join("\n"); return { content: [ { type: "text", text: `Open issues (${issues.length}):\n${summary}`, }, ], }; });// Send a message to Slackserver.tool( "send_slack_message", "Send a message to a Slack channel", { channel: z.string().describe("Channel ID"), message: z.string().describe("Message to send"), }, async ({ channel, message }) => { const token = process.env.SLACK_BOT_TOKEN; if (!token) { return { content: [ { type: "text", text: "Error: SLACK_BOT_TOKEN is not set" }, ], }; } const response = await fetch("https://slack.com/api/chat.postMessage", { method: "POST", headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json", }, body: JSON.stringify({ channel, text: message }), }); const data = await response.json(); if (!data.ok) { return { content: [ { type: "text", text: `Slack Error: ${data.error}` }, ], }; } return { content: [{ type: "text", text: "Message sent successfully" }], }; });const transport = new StdioServerTransport();await server.connect(transport);
With this setup, you can tell Antigravity "Check this week's open issues and send a summary to the team's Slack channel," and the AI will autonomously fetch issues from GitHub, compose a summary, and post it to Slack.
Production Best Practices
Implementing Rate Limiting
External APIs always have rate limits. Managing them within your MCP server prevents hitting API quotas unexpectedly.
// src/rate-limiter.tsclass RateLimiter { private timestamps: number[] = []; private maxRequests: number; private windowMs: number; constructor(maxRequests: number, windowMs: number) { this.maxRequests = maxRequests; this.windowMs = windowMs; } async waitIfNeeded(): Promise<void> { const now = Date.now(); // Remove timestamps outside the window this.timestamps = this.timestamps.filter( (t) => now - t < this.windowMs ); if (this.timestamps.length >= this.maxRequests) { const oldestInWindow = this.timestamps[0]; const waitTime = this.windowMs - (now - oldestInWindow) + 100; await new Promise((resolve) => setTimeout(resolve, waitTime)); } this.timestamps.push(Date.now()); }}// Example: Maximum 60 requests per minuteexport const githubLimiter = new RateLimiter(60, 60_000);// Usage in tools: await githubLimiter.waitIfNeeded();
Secure Authentication Token Management
MCP servers receive API keys and tokens through environment variables. For production environments, follow these patterns:
// src/auth.tsfunction getRequiredEnv(key: string): string { const value = process.env[key]; if (!value) { throw new Error( `Required environment variable ${key} is not set. ` + `Add it to the env block in your Antigravity MCP configuration.` ); } return value;}// Token refresh supportclass TokenManager { private token: string; private refreshToken: string; private expiresAt: number = 0; constructor() { this.token = getRequiredEnv("API_ACCESS_TOKEN"); this.refreshToken = getRequiredEnv("API_REFRESH_TOKEN"); } async getValidToken(): Promise<string> { if (Date.now() < this.expiresAt - 60_000) { return this.token; } // Refresh the token const response = await fetch("https://api.example.com/oauth/token", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ grant_type: "refresh_token", refresh_token: this.refreshToken, }), }); const data = await response.json(); this.token = data.access_token; this.expiresAt = Date.now() + data.expires_in * 1000; return this.token; }}
Error Handling Patterns
In MCP tools, it's crucial to return AI-readable error messages rather than crashing the process.
MCP provides an official debugging tool called MCP Inspector:
# Install MCP Inspectornpx @modelcontextprotocol/inspector# Launch with your servernpx @modelcontextprotocol/inspector npx tsx src/index.ts
The Inspector lets you monitor tool inputs and outputs in real time, making it easy to inspect API responses and quickly identify the source of errors.
Common Issues and Solutions
Tools not appearing: Verify the path in settings.json is correct. Test that command and args are executable independently
Timeout errors: If external APIs are slow, set timeouts on fetch using AbortController
Environment variables not reading: Confirm they're added to the env block in MCP settings. Shell environment variables aren't automatically passed to MCP servers
Summary
The combination of Antigravity and MCP dramatically expands what's possible with AI agents. Using the standard MCP SDK, you can transform any external API into an AI-operable tool and build autonomous workflows that span multiple services.
Antigravity Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.