{
  "access": "public",
  "type": "reference",
  "format": "markdown",
  "title": "Conduit SDK",
  "chunked": true,
  "url": "https://library.datagrout.ai/conduit-sdk",
  "summary": "**Drop-in MCP client for Python, TypeScript, and Rust**",
  "content_markdown": "# Conduit SDK\n\n**Drop-in MCP client for Python, TypeScript, and Rust**\n\nConduit replaces your existing MCP client with a single import swap. Your agent code works unchanged. The SDK transparently routes every call through the DataGrout intelligence layer, giving you discovery, planning, policy enforcement, and cost tracking without rewriting anything.\n\n---\n\n## Installation\n\n**Python**\n\n```bash\npip install datagrout-conduit\n```\n\n**TypeScript / Node.js**\n\n```bash\nnpm install datagrout-conduit\n```\n\n**Rust**\n\n```bash\ncargo add datagrout-conduit\n```\n\n---\n\n## Connect to Your Server\n\nYou need your server URL (from the dashboard) and an authentication credential.\n\n**Python**\n\n```python\nfrom datagrout.conduit import Client\n\nclient = Client(\n    \"https://gateway.datagrout.ai/servers/YOUR_SERVER_ID/mcp\",\n    auth={\"bearer\": \"dg_your_token_here\"},\n)\nawait client.connect()\n```\n\n**TypeScript**\n\n```typescript\nimport { Client } from '@datagrout/conduit';\n\nconst client = new Client({\n    url: 'https://gateway.datagrout.ai/servers/YOUR_SERVER_ID/mcp',\n    auth: { bearer: 'dg_your_token_here' },\n});\nawait client.connect();\n```\n\n**Rust**\n\n```rust\nuse datagrout_conduit::{ClientBuilder, Transport};\n\nlet client = ClientBuilder::new()\n    .url(\"https://gateway.datagrout.ai/servers/YOUR_SERVER_ID/mcp\")\n    .auth_bearer(\"dg_your_token_here\")\n    .build()?;\n\nclient.connect().await?;\n```\n\n---\n\n## Standard MCP Operations\n\nConduit supports the full MCP protocol surface. These calls behave identically to any MCP client.\n\n### List Tools\n\n```python\ntools = client.list_tools()\n\nfor tool in tools:\n    print(tool.name, tool.description)\n```\n\n### Call a Tool\n\n```python\nresult = client.call_tool(\n    \"salesforce@1/get_leads@1\",\n    {\"limit\": 10}\n)\n```\n\n---\n\n## DataGrout Extensions\n\nBeyond standard MCP, Conduit exposes three methods that access the intelligence layer directly.\n\n### discover()\n\nFind tools by meaning, not by name. Returns ranked matches based on semantic similarity to your query.\n\n```python\nresults = client.discover(\n    query=\"create an invoice\",\n    limit=5,\n    min_score=0.5\n)\n\nfor match in results:\n    print(match.tool.name, match.score)\n```\n\nUse `goal` instead of `query` when you want multi-step planning:\n\n```python\nplan = client.discover(\n    goal=\"sync qualified leads to invoices\"\n)\n```\n\nFilter to a specific integration:\n\n```python\nresults = client.discover(\n    query=\"list customers\",\n    integration=\"quickbooks\"\n)\n```\n\n### guide()\n\nStart an interactive decision tree to build a workflow step-by-step.\n\n```python\nsession = client.guide(goal=\"export invoices to PDF\")\n\n# System returns options at each step\nprint(session.message)\nfor option in session.options:\n    print(option.id, option.label)\n\n# Select a choice by ID\nsession = client.guide(choice=\"1.2\")\n```\n\nSee [Guide Mode](guide-mode) for the full walkthrough.\n\n### perform()\n\nExecute a tool directly through the intelligence layer. Equivalent to `call_tool` but routes through policy enforcement, cost tracking, and optional output transformations.\n\n```python\nresult = client.perform(\n    \"quickbooks@1/create_invoice@1\",\n    {\"customer_id\": \"123\", \"amount\": 1500.00}\n)\n```\n\n---\n\n## Cost Tracking\n\nEvery tool call returns a receipt with credit costs. Use `extract_meta()` to access it.\n\n**Python**\n\n```python\nfrom datagrout.conduit import extract_meta\n\nresult = await client.call_tool(\"salesforce@1/get_leads@1\", {\"limit\": 10})\nmeta = extract_meta(result)\n\nif meta:\n    print(meta.receipt.net_credits)\n    print(meta.receipt.savings)\n```\n\n**TypeScript**\n\n```typescript\nimport { extractMeta } from '@datagrout/conduit';\n\nconst result = await client.callTool('salesforce@1/get_leads@1', { limit: 10 });\nconst meta = extractMeta(result);\n\nif (meta) {\n    console.log(meta.receipt.netCredits);\n    console.log(meta.receipt.savings);\n}\n```\n\n**Rust**\n\n```rust\nlet result = client.call_tool(\"salesforce@1/get_leads@1\", json!({\"limit\": 10})).await?;\nlet meta = client.extract_meta(&result)?;\nprintln!(\"Cost: {} credits\", meta.receipt.actual_credits);\n```\n\nSee [Credits and Receipts](credits-receipts) for receipt fields and BYOK discounts.\n\n---\n\n## Transport Options\n\nConduit supports two transport protocols. Both provide identical access to the intelligence layer.\n\n| Transport | Protocol | Streaming | Use When |\n|-----------|----------|-----------|----------|\n| `Transport.Mcp` | JSON-RPC 2.0 over SSE | Yes | Your agent framework supports MCP |\n| `Transport.JsonRpc` | JSON-RPC 2.0 over HTTP POST | No | Legacy systems, simple HTTP clients |\n\n```python\n# MCP transport (streaming, persistent connection)\nclient = ClientBuilder().transport(Transport.Mcp).build()\n\n# JSON-RPC transport (stateless HTTP POST)\nclient = ClientBuilder().transport(Transport.JsonRpc).build()\n```\n\n---\n\n## Authentication\n\nConduit supports three authentication methods: bearer tokens, OAuth 2.1, and mutual TLS.\n\n### Bearer Token\n\nThe simplest option. Create a token in your server settings.\n\n**Python**\n\n```python\nclient = Client(\n    \"https://gateway.datagrout.ai/servers/YOUR_UUID/mcp\",\n    auth={\"bearer\": \"your-token\"},\n)\n```\n\n**Rust**\n\n```rust\nlet client = ClientBuilder::new()\n    .url(\"https://gateway.datagrout.ai/servers/YOUR_UUID/mcp\")\n    .auth_bearer(\"your-token\")\n    .build()?;\n```\n\n### OAuth 2.1 (client_credentials)\n\nFor machine-to-machine authentication. The SDK handles token exchange and refresh automatically.\n\n**Python**\n\n```python\nclient = Client(\n    \"https://gateway.datagrout.ai/servers/YOUR_UUID/mcp\",\n    client_id=\"your-client-id\",\n    client_secret=\"your-client-secret\",\n)\n```\n\n**Rust**\n\n```rust\nlet client = ClientBuilder::new()\n    .url(\"https://gateway.datagrout.ai/servers/YOUR_UUID/mcp\")\n    .auth_client_credentials(\"your-client-id\", \"your-client-secret\")\n    .build()?;\n```\n\n### Mutual TLS (mTLS)\n\nCertificate-based authentication for production agents. After bootstrapping, no tokens or secrets are needed — the client certificate is the credential.\n\n**Bootstrap once, connect forever:**\n\n```python\n# First run: register identity with the DataGrout CA\nclient = await Client.bootstrap_identity(\n    url=\"https://gateway.datagrout.ai/servers/YOUR_UUID/mcp\",\n    auth_token=\"your-access-token\",\n    name=\"my-agent\",\n)\n\n# All subsequent runs: mTLS auto-discovered from ~/.conduit/\nclient = Client(\"https://gateway.datagrout.ai/servers/YOUR_UUID/mcp\")\n```\n\n**Auto-discovery searches:**\n\n1. `CONDUIT_MTLS_CERT` / `CONDUIT_MTLS_KEY` env vars (inline PEM)\n2. `CONDUIT_IDENTITY_DIR` env var (directory path)\n3. `~/.conduit/`\n4. `.conduit/` relative to cwd\n\n**Multiple agents on one machine:**\n\n```python\nclient = Client(\n    \"https://gateway.datagrout.ai/servers/YOUR_UUID/mcp\",\n    identity_dir=\"/opt/agents/agent-a/.conduit\",\n    identity_auto=True,\n)\n```\n\nSee [Authentication](authentication) for the full reference.\n\n---\n\n## Full Example\n\nConnect, discover a tool, execute it, and check the cost.\n\n```python\nfrom datagrout.conduit import Client, extract_meta\n\nasync with Client(\n    \"https://gateway.datagrout.ai/servers/YOUR_SERVER_ID/mcp\",\n    auth={\"bearer\": \"dg_your_token_here\"},\n) as client:\n    # Find the right tool by intent\n    matches = await client.discover(query=\"list recent invoices\", limit=3)\n    tool = matches[0].tool\n\n    # Execute it\n    result = await client.call_tool(tool.name, {\"limit\": 25})\n\n    # Check cost\n    meta = extract_meta(result)\n    if meta:\n        print(f\"Credits: {meta.receipt.net_credits}, savings: {meta.receipt.savings}\")\n```\n\n---\n\n## Related\n\n- [Quick Start](quick-start) -- Set up your first server\n- [Core Concepts](core-concepts) -- Servers, integrations, tools, policies\n- [Credits and Receipts](credits-receipts) -- Cost model and receipt fields\n- [Authentication](authentication) -- Full auth reference\n"
}