> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dedaluslabs.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# MCP Servers

> Connect to any model to any MCP server

The Dedalus SDK is a full MCP client. Connect your agents to any server that implements the [Model Context Protocol](https://modelcontextprotocol.io), hosted by you, us, or anyone else.

With `DedalusRunner`, you can mix and chain tool calls across local and remote MCP servers in one agent loop. Local tools handle your custom logic, while MCP servers add hosted capabilities (search, databases, SaaS APIs, etc.).

## Connect MCP server in one line

<CodeGroup>
  ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
  import asyncio
  from dedalus_labs import AsyncDedalus, DedalusRunner
  from dotenv import load_dotenv

  load_dotenv()

  async def main():
      client = AsyncDedalus()
      runner = DedalusRunner(client)

      result = await runner.run(
          input="What's the weather forecast for San Francisco this week?",
          model="anthropic/claude-opus-4-5",
          mcp_servers=["windsornguyen/open-meteo-mcp"],  # Weather forecasts via Open-Meteo
      )

      print(result.final_output)

  if __name__ == "__main__":
      asyncio.run(main())
  ```

  ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
  import Dedalus from "dedalus-labs";
  import { DedalusRunner } from "dedalus-labs";

  const client = new Dedalus();
  const runner = new DedalusRunner(client);

  async function main() {
  	const result = await runner.run({
  		input: "What's the weather forecast for San Francisco this week?",
  		model: "anthropic/claude-opus-4-5",
  		mcpServers: ["windsornguyen/open-meteo-mcp"], // Weather forecasts via Open-Meteo
  	});

  	console.log(result.finalOutput);
  }

  main();
  ```
</CodeGroup>

The agent discovers the server's tools and uses them when relevant.

## Combine with local tools

MCP servers and local tools work together. Pass both to `runner.run()`.

<CodeGroup>
  ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
  import asyncio
  from dedalus_labs import AsyncDedalus, DedalusRunner
  from dotenv import load_dotenv

  load_dotenv()

  def as_bullets(items: list[str]) -> str:
      """Format items as a bulleted list."""
      return "\n".join(f"• {item}" for item in items)

  async def main():
      client = AsyncDedalus()
      runner = DedalusRunner(client)

      result = await runner.run(
          input=(
              "Get the 7-day weather forecast for San Francisco "
              "and format the daily conditions as bullets using as_bullets."
          ),
          model="anthropic/claude-opus-4-5",
          mcp_servers=["windsornguyen/open-meteo-mcp"],
          tools=[as_bullets],
      )

      print(result.final_output)

  if __name__ == "__main__":
      asyncio.run(main())
  ```

  ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
  import Dedalus from "dedalus-labs";
  import { DedalusRunner } from "dedalus-labs";

  const client = new Dedalus();
  const runner = new DedalusRunner(client);

  function asBullets(items: string[]): string {
  	return items.map((item) => `• ${item}`).join("\n");
  }

  async function main() {
  	const result = await runner.run({
  		input:
  			"Get the 7-day weather forecast for San Francisco and format the daily conditions as bullets using asBullets.",
  		model: "anthropic/claude-opus-4-5",
  		mcpServers: ["windsornguyen/open-meteo-mcp"],
  		tools: [asBullets],
  	});

  	console.log((result as any).finalOutput);
  }

  main();
  ```
</CodeGroup>

## External MCP URL

You can connect directly to any external MCP server URL (Streamable HTTP). This is useful when:

* You’re testing a server without registering it
* You’re connecting to a self-hosted MCP deployment
* You’re using an MCP server that isn’t in the marketplace

<CodeGroup>
  ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
  import asyncio
  from dedalus_labs import AsyncDedalus, DedalusRunner
  from dotenv import load_dotenv

  load_dotenv()

  async def main():
      client = AsyncDedalus()
      runner = DedalusRunner(client)

      result = await runner.run(
          input="Use your tools to summarize the Dedalus Python SDK repo in 5 bullet points.",
          model="openai/gpt-5.2",
          # External MCP URL!
          mcp_servers=["https://mcp.deepwiki.com/mcp"],
      )

      print(result.final_output)

  if __name__ == "__main__":
      asyncio.run(main())
  ```

  ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
  import Dedalus from "dedalus-labs";
  import { DedalusRunner } from "dedalus-labs";

  const client = new Dedalus();
  const runner = new DedalusRunner(client);

  async function main() {
  	const result = await runner.run({
  		input: "Use your tools to summarize the Dedalus Python SDK repo in 5 bullet points.",
  		model: "openai/gpt-5.2",
  		// External MCP URL!
  		mcpServers: ["https://mcp.deepwiki.com/mcp"],
  	});

  	console.log((result as any).finalOutput);
  }

  main();
  ```
</CodeGroup>

## Next steps

<CardGroup cols={2}>
  <Card title="Structured Outputs" href="/sdk/agents/structured-outputs">
    Validate and parse JSON into schemas
  </Card>

  <Card title="Streaming" href="/sdk/agents/streaming">
    Watch tool use + output in real time
  </Card>

  <Card title="Use Cases" href="/sdk/agents/use-cases/web-search-agent">
    End-to-end MCP agent patterns
  </Card>
</CardGroup>
