RoxyAPI

Menu

AI Agents Calling Real APIs: How Tool Calling and MCP Work in Practice

14 min read
By Sarah Chen
AI AgentsTool CallingMCPFunction CallingAPI Integration

See how AI agents actually call APIs in production. Real examples of OpenAI function calling, Claude tool use, Gemini ADK, and MCP with request/response flows and code you can run today.

AI Agents Calling Real APIs: How Tool Calling and MCP Work in Practice

"Get me a birth chart for someone born June 15, 1990 at 2:30 PM in New York."

A year ago, an AI assistant would respond with a general explanation of what a birth chart is. Today, that same prompt triggers the assistant to call an astrology API, pass the birth data as structured parameters, receive precise planetary positions, and present a personalized chart interpretation, all within a single conversation turn.

This is not a demo. It is how AI agents work in production right now. OpenAI, Anthropic, Google, and open-source frameworks all support tool calling, the mechanism that lets language models interact with external APIs during a conversation. And the Model Context Protocol (MCP) is making it even simpler by letting agents discover available tools automatically.

This article shows you exactly how it works, with real request/response flows, code examples across four platforms, and the architecture that connects user prompts to API calls.

How Tool Calling Works (The Basics)

When a user asks an AI agent something that requires external data, the model does not magically connect to the internet. Instead, it follows a structured protocol:

  1. User sends a message: "What are my planetary positions for June 15, 1990 at 2:30 PM in New York?"
  2. Model analyzes intent: The model determines it needs to call an external tool to answer this question
  3. Model generates a tool call: Instead of generating text, the model outputs a structured JSON object specifying which function to call and with what parameters
  4. Application executes the call: Your code (not the model) makes the actual HTTP request to the API
  5. Result returns to the model: The API response is injected back into the conversation
  6. Model generates a response: The model interprets the API data and crafts a natural language answer

The critical insight: the model never calls the API directly. It generates a description of the call it wants to make. Your application code is the bridge between the model intent and the actual API execution. This is what makes tool calling safe and auditable.

Example 1: OpenAI Function Calling

OpenAI supports function calling (now called "tools" in the API) across GPT-4, GPT-4o, and newer models. Here is a complete flow:

Step 1: Define Available Tools

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_planetary_positions",
            "description": "Calculate planetary positions for a specific date, time, and location. Returns Sun, Moon, and planet positions in zodiac signs.",
            "parameters": {
                "type": "object",
                "properties": {
                    "date": {
                        "type": "string",
                        "description": "Date in YYYY-MM-DD format"
                    },
                    "time": {
                        "type": "string",
                        "description": "Time in HH:MM 24-hour format"
                    },
                    "latitude": {
                        "type": "number",
                        "description": "Geographic latitude in decimal degrees"
                    },
                    "longitude": {
                        "type": "number",
                        "description": "Geographic longitude in decimal degrees"
                    }
                },
                "required": ["date", "time", "latitude", "longitude"]
            }
        }
    }
]

Step 2: Send the User Message

response = client.chat.completions.create(
    model="gpt-4o",
    messages=[
        {"role": "user", "content": "What are my planetary positions if I was born June 15, 1990 at 2:30 PM in New York?"}
    ],
    tools=tools
)

Step 3: Model Returns a Tool Call (Not Text)

{
  "choices": [{
    "message": {
      "tool_calls": [{
        "id": "call_abc123",
        "function": {
          "name": "get_planetary_positions",
          "arguments": "{\"date\": \"1990-06-15\", \"time\": \"14:30\", \"latitude\": 40.7128, \"longitude\": -74.006}"
        }
      }]
    }
  }]
}

Notice what the model did: it extracted "June 15, 1990" into ISO format, converted "2:30 PM" to 24-hour time, and looked up New York coordinates. All from natural language.

Step 4: Your Code Calls the API

import requests

api_response = requests.post(
    "https://roxyapi.com/api/v2/astrology/planets",
    headers={"X-API-Key": "YOUR_KEY", "Content-Type": "application/json"},
    json={"date": "1990-06-15", "time": "14:30", "latitude": 40.7128, "longitude": -74.006}
)

Step 5: Feed the Result Back

final_response = client.chat.completions.create(
    model="gpt-4o",
    messages=[
        {"role": "user", "content": "What are my planetary positions..."},
        {"role": "assistant", "tool_calls": [tool_call]},
        {"role": "tool", "tool_call_id": "call_abc123", "content": api_response.text}
    ],
    tools=tools
)

Step 6: Model Generates the Final Answer

The model now has the actual planetary data and generates a personalized response:

"Based on your birth data (June 15, 1990, 2:30 PM, New York), here are your planetary positions: Your Sun is in Gemini at 24 degrees, giving you a curious and communicative nature. Your Moon is in Scorpio at 8 degrees, suggesting deep emotional intensity beneath your social exterior..."

The entire flow happens in one conversation. The user sees only the final answer.

Example 2: Claude Tool Use (Anthropic)

Anthropic Claude uses a similar pattern called "tool use." The key difference is the message format:

response = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=1024,
    tools=[
        {
            "name": "get_birth_chart",
            "description": "Calculate a complete natal birth chart with planetary positions, house placements, and aspects.",
            "input_schema": {
                "type": "object",
                "properties": {
                    "date": {"type": "string", "description": "Birth date (YYYY-MM-DD)"},
                    "time": {"type": "string", "description": "Birth time (HH:MM, 24h)"},
                    "latitude": {"type": "number"},
                    "longitude": {"type": "number"}
                },
                "required": ["date", "time", "latitude", "longitude"]
            }
        }
    ],
    messages=[
        {"role": "user", "content": "Generate a birth chart for someone born March 3, 1985 at 9 AM in London"}
    ]
)

Claude responds with a tool_use content block:

{
  "content": [
    {
      "type": "tool_use",
      "id": "toolu_01abc",
      "name": "get_birth_chart",
      "input": {
        "date": "1985-03-03",
        "time": "09:00",
        "latitude": 51.5074,
        "longitude": -0.1278
      }
    }
  ]
}

You execute the API call, then send the result back as a tool_result message. Claude synthesizes the data into a natural language chart interpretation.

Example 3: MCP (No Manual Tool Definitions)

The examples above require you to manually define every tool (function schema) in your code. If an API has 85+ endpoints, that is 85+ tool definitions you must write, maintain, and update when the API changes.

MCP eliminates this entirely. Instead of hardcoding tool definitions, the AI agent connects to an MCP server that advertises its available tools dynamically.

How MCP Discovery Works

The agent sends a JSON-RPC request to discover available tools:

// Agent asks: what can you do?
{"jsonrpc": "2.0", "method": "tools/list", "id": 1}

The MCP server responds with all available tools and their schemas:

{
  "tools": [
    {
      "name": "get_planetary_positions",
      "description": "Calculate planetary positions (Sun, Moon, Mercury through Pluto) for a specific date, time, and location.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "date": {"type": "string", "description": "Date in YYYY-MM-DD format"},
          "time": {"type": "string", "description": "Time in HH:MM format (24-hour)"},
          "latitude": {"type": "number"},
          "longitude": {"type": "number"}
        },
        "required": ["date", "time", "latitude", "longitude"]
      }
    },
    {
      "name": "get_birth_chart",
      "description": "Generate a complete natal chart with planets, houses, and aspects..."
    },
    {
      "name": "get_compatibility",
      "description": "Calculate synastry compatibility between two birth charts..."
    }
  ]
}

The agent now knows every available tool without any manual configuration. When a user asks a question, the agent selects the right tool, calls it, and processes the result.

MCP in Claude Desktop

{
  "mcpServers": {
    "roxyapi-astrology": {
      "url": "https://roxyapi.com/mcp/astrology-api",
      "headers": {
        "X-API-Key": "your_api_key_here"
      }
    }
  }
}

Save this to your Claude Desktop config, restart, and Claude can now call any astrology endpoint without you writing a single tool definition.

MCP in Google Gemini ADK

from google.adk.agents import LlmAgent
from google.adk.tools.mcp_tool import McpToolset
from google.adk.tools.mcp_tool.mcp_session_manager import SseConnectionParams

agent = LlmAgent(
    model='gemini-2.0-flash',
    name='astrology_assistant',
    instruction='Use RoxyAPI tools to provide astrological insights',
    tools=[
        McpToolset(
            connection_params=SseConnectionParams(
                url="https://roxyapi.com/mcp/astrology-api",
                headers={"X-API-Key": "your_api_key_here"}
            )
        )
    ]
)

The Gemini agent auto-discovers all available astrology tools from the MCP server and can call them in response to user queries.

Example 4: Multi-Tool Agent Workflow

Real production agents often call multiple APIs in sequence to answer a single question. Here is a realistic multi-step workflow:

User: "I am a Gemini born June 15, 1990. My partner is a Scorpio born November 8, 1988. Are we compatible? Also pull a tarot card for our relationship."

Agent reasoning:

  1. I need planetary positions for Person A (June 15, 1990)
  2. I need planetary positions for Person B (November 8, 1988)
  3. I need a synastry compatibility analysis between both charts
  4. I need a tarot reading focused on relationships

Tool calls (the agent makes these in sequence or parallel):

Call 1: get_birth_chart(date="1990-06-15", time="12:00", latitude=40.71, longitude=-74.01)
Call 2: get_birth_chart(date="1988-11-08", time="12:00", latitude=40.71, longitude=-74.01)
Call 3: get_compatibility(person1_date="1990-06-15", person2_date="1988-11-08", ...)
Call 4: get_tarot_reading(spread="relationship", seed=20260222)

Agent response: A synthesized answer combining natal chart insights, compatibility analysis, and tarot guidance into one coherent response. Four API calls, zero human intervention, one natural language answer.

This multi-tool orchestration is where MCP shines. With function calling, you would need to predefine tools for both astrology and tarot domains. With MCP, the agent connects to multiple MCP servers (astrology + tarot) and discovers all tools from both domains automatically.

The Architecture Behind Agent-API Integration

Here is the typical production architecture for AI agents that call external APIs:

User
  |
  v
AI Platform (OpenAI / Claude / Gemini)
  |
  v
Orchestration Layer (your application code)
  |
  +---> MCP Server A (Astrology API)
  |
  +---> MCP Server B (Tarot API)
  |
  +---> MCP Server C (Numerology API)
  |
  v
Response synthesis back to user

The orchestration layer is your code. It manages the conversation state, routes tool calls to the correct APIs, handles authentication, and feeds results back to the model. In MCP-based architectures, the orchestration is largely handled by the AI platform itself (Claude Desktop, ChatGPT, Gemini), which connects to MCP servers directly.

Key architectural decisions:

  • Authentication: API keys are stored in your orchestration layer or MCP server config, never exposed to the model
  • Error handling: Your code catches API errors and returns structured error messages that the model can interpret
  • Rate limiting: Your orchestration layer tracks API usage and prevents the model from exceeding quotas
  • Caching: Identical API calls (same birth data) can be cached to reduce costs and latency

What Developers Need to Know

If you are building AI-powered features that call external APIs, here are the practical considerations:

Start with MCP if Available

If the API provides an MCP server, use it. You skip the entire tool definition step and get automatic updates when new endpoints are added. RoxyAPI provides MCP servers for all six domains (astrology, Vedic astrology, tarot, numerology, dreams, I-Ching).

Fall Back to Function Calling for Custom Logic

If you need to combine API calls with custom business logic (applying user preferences, filtering results, formatting for your UI), function calling gives you more control over the orchestration.

Use Per-Product OpenAPI Specs for Tool Generation

If an API serves OpenAPI specifications, you can auto-generate tool definitions from the spec instead of writing them manually. Many AI frameworks support this pattern.

Test with Real Data

AI agents behave differently with real API data vs. mock responses. Test your tool definitions with actual API calls to verify that the model interprets responses correctly and generates accurate summaries.

Getting Started: Your First Agent-API Integration

The fastest path from zero to a working AI agent that calls a real API:

  1. Get an API key: roxyapi.com/pricing
  2. Choose your platform: Claude Desktop, ChatGPT, Gemini ADK, or custom code
  3. Connect via MCP (fastest): Add the MCP server URL to your platform config
  4. Or define tools manually: Use the OpenAPI spec to generate tool definitions
  5. Test with a prompt: "What are the planetary positions for someone born [date] in [city]?"
# Verify the API works before connecting to an agent
curl -X POST "https://roxyapi.com/api/v2/astrology/planets" \
  -H "X-API-Key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"date": "1990-06-15", "time": "14:30", "latitude": 40.7128, "longitude": -74.006}'

Once the raw API call works, connecting it to an AI agent via MCP or function calling is straightforward. Browse the full API documentation to see all available endpoints across astrology, tarot, numerology, dreams, and I-Ching.

Conclusion

AI agents calling real APIs is no longer experimental. OpenAI, Anthropic, Google, and open-source frameworks all support structured tool calling that lets models interact with external services during conversations. MCP takes this further by eliminating manual tool definitions entirely, letting agents discover API capabilities at runtime.

The pattern is consistent across all platforms: the model generates a structured intent, your code executes the API call, and the result feeds back into the conversation. Whether you use function calling or MCP, the architecture separates model reasoning from API execution, keeping things safe, auditable, and debuggable.

Key takeaways:

  • Tool calling lets AI models generate structured API call intents without executing calls directly
  • The model extracts parameters from natural language (dates, locations, names) and formats them correctly
  • OpenAI, Claude, and Gemini all support tool calling with slightly different API formats
  • MCP eliminates manual tool definitions by letting agents discover tools from a server at runtime
  • Multi-tool workflows let agents call several APIs in sequence to answer complex questions
  • Authentication stays in your orchestration layer, never exposed to the model
  • MCP servers per domain let agents connect to exactly the capabilities they need

Ready to connect your AI agent to a real API? RoxyAPI provides MCP servers for astrology, tarot, numerology, dreams, and I-Ching, plus full OpenAPI specs for function calling. View pricing to get your API key and start building.

Frequently Asked Questions

Q: What is tool calling in AI agents? A: Tool calling (also called function calling) is the mechanism that lets AI language models interact with external APIs during a conversation. Instead of generating text, the model outputs a structured JSON object specifying which function to call and with what parameters. Your application code then executes the actual API call and feeds the result back to the model for interpretation.

Q: What is the difference between function calling and MCP? A: Function calling requires you to manually define every tool (function schema) in your code before the model can use it. MCP (Model Context Protocol) lets the AI agent discover available tools dynamically by connecting to a server that advertises its capabilities. MCP eliminates the need to write and maintain tool definitions, especially valuable for APIs with many endpoints.

Q: Which AI platforms support tool calling? A: All major platforms support it: OpenAI (GPT-4, GPT-4o) calls it "function calling" or "tools." Anthropic (Claude) calls it "tool use." Google (Gemini) calls it "function declarations." Meta (Llama 3+) supports structured function calling. Open-source frameworks like LangChain and CrewAI also support tool calling across multiple model providers.

Q: Can an AI agent call multiple APIs in one conversation? A: Yes. Agents routinely call multiple APIs in sequence or parallel to answer complex questions. For example, an astrology chatbot might call a birth chart API, a compatibility API, and a tarot API in a single conversation turn. With MCP, the agent can connect to multiple MCP servers and discover tools across all connected domains.

Q: Is it safe to let AI agents call APIs? A: The architecture is designed for safety. The model never calls APIs directly. It generates a structured intent (which function to call, with what parameters), and your application code decides whether to execute it. API keys stay in your orchestration layer. You control which tools are available, what parameters are allowed, and whether to execute or reject any tool call.

Q: How does MCP authentication work? A: API keys are passed in the MCP server configuration (headers), not in the conversation. When you configure an MCP server in Claude Desktop or Gemini ADK, you include the API key in the connection config. The AI platform uses this key when making tool calls but never exposes it in the conversation or to the model.

Q: Do I need to write code to use MCP with an API? A: For platforms like Claude Desktop, no code is needed. You add the MCP server URL and API key to a JSON config file, restart the application, and the AI can call all available tools immediately. For custom applications or platforms like Gemini ADK, you write a few lines of setup code to connect to the MCP server, but the tool discovery and calling is handled automatically.

Q: What happens if an API call fails during an agent conversation? A: Your orchestration layer should catch API errors (timeouts, rate limits, invalid parameters) and return a structured error message to the model. The model then communicates the issue to the user in natural language, such as "I could not retrieve your birth chart because the date format was invalid. Could you provide your birth date in YYYY-MM-DD format?" Well-designed error responses let the model attempt self-correction.