> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.getdial.ai/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.getdial.ai/_mcp/server.

# Connect a Context MCP server

POST https://api.getdial.ai/api/v1/context-mcps
Content-Type: application/json

Registers an MCP server and wires its tools into the account's voice agent. Dial probes the server's URL to determine how it authenticates:

- **Unauthenticated or static** — the connection is wired immediately
  and returned with `status: "connected"`.

- **OAuth 2.1–protected** — the response includes an `authorizationUrl`
  and `status: "pending_auth"`. Open that URL in a browser to grant
  consent; Dial completes the connection on the OAuth callback and then
  manages token refresh for you. The server's authorization server must
  support Dynamic Client Registration (RFC 7591).


If the server is unreachable, or responds to the probe with a server error (HTTP 5xx), the request is rejected with `400` and a message naming the status Dial observed — the fault is on your server, so fix it and try again.

Reference: https://docs.getdial.ai/api-reference/rest-api/context-mcp/create-context-mcp

## Authentication

- `Authorization` header (bearer token, required) — Your Dial API key, sent as `Authorization: Bearer sk_live_...`

## Request

### Body (application/json)

- `name` (string, required) — Display name for the connection.
- `url` (string, required) — HTTPS MCP server URL (http allowed only for localhost in development).
- `headers` (map from string to string, optional) — Extra static headers to send on every connection. For an OAuth-protected server, any `Authorization` header you set is ignored — Dial manages it.
- `queryParams` (map from string to string, optional) — Query parameters to append to the connection URL.
- `timeoutMs` (integer, optional) — Connection timeout in ms. Defaults to 120000.

## Response

### 201

The created connection. For OAuth servers, `authorizationUrl` is present and the connection stays `pending_auth` until consent completes.

- `contextMcp` (object, required)
  - `id` (string, optional)
  - `name` (string, optional)
  - `url` (string, optional) — The MCP server URL.
  - `authMode` (enum, optional) — How the server authenticates, detected on connect. `none`: unauthenticated. `static`: fixed headers you supplied. `oauth`: OAuth 2.1, with tokens managed by Dial.
    - Allowed values: `none`, `static`, `oauth`
  - `status` (enum, optional) — `pending_auth`: awaiting OAuth consent. `connected`: tools are wired to the agent. `error`: connection or token refresh failed (see `lastError`).
    - Allowed values: `pending_auth`, `connected`, `error`
  - `toolCount` (integer, optional) — Number of MCP tools wired into the agent.
  - `timeoutMs` (integer, optional, nullable) — Connection timeout in ms; null uses the default (120000).
  - `headersMasked` (map from string to string, optional) — Extra static request headers, with values masked. The OAuth-managed `Authorization` header is never returned.
  - `queryParams` (map from string to string, optional) — Query parameters appended to the connection URL, with values masked.
  - `lastError` (string, optional, nullable)
  - `createdAt` (datetime, optional)
- `authorizationUrl` (string, optional, nullable) — Present only for OAuth-protected servers. Open in a browser to grant consent and finish connecting.

## Examples

**Request**

```json
{
  "name": "Acme MCP Server",
  "url": "https://mcp.acme-corp.com/api"
}
```

**Response**

```json
{
  "contextMcp": {
    "id": "a1b2c3d4-e5f6-7890-ab12-cd34ef567890",
    "name": "Acme MCP Server",
    "url": "https://mcp.acme-corp.com/api",
    "authMode": "oauth",
    "status": "pending_auth",
    "toolCount": 3,
    "timeoutMs": 120000,
    "headersMasked": {},
    "queryParams": {},
    "lastError": "Waiting for user consent",
    "createdAt": "2024-01-15T09:30:00Z"
  },
  "authorizationUrl": "https://auth.acme-corp.com/oauth2/authorize?client_id=abc123&response_type=code&scope=openid%20profile&redirect_uri=https%3A%2F%2Fapi.getdial.ai%2Foauth%2Fcallback"
}
```

**SDK Code**

```python
import requests

url = "https://api.getdial.ai/api/v1/context-mcps"

payload = {
    "name": "Acme MCP Server",
    "url": "https://mcp.acme-corp.com/api"
}
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript
const url = 'https://api.getdial.ai/api/v1/context-mcps';
const options = {
  method: 'POST',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"name":"Acme MCP Server","url":"https://mcp.acme-corp.com/api"}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.getdial.ai/api/v1/context-mcps"

	payload := strings.NewReader("{\n  \"name\": \"Acme MCP Server\",\n  \"url\": \"https://mcp.acme-corp.com/api\"\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby
require 'uri'
require 'net/http'

url = URI("https://api.getdial.ai/api/v1/context-mcps")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"name\": \"Acme MCP Server\",\n  \"url\": \"https://mcp.acme-corp.com/api\"\n}"

response = http.request(request)
puts response.read_body
```

```java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.getdial.ai/api/v1/context-mcps")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"name\": \"Acme MCP Server\",\n  \"url\": \"https://mcp.acme-corp.com/api\"\n}")
  .asString();
```

```php
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.getdial.ai/api/v1/context-mcps', [
  'body' => '{
  "name": "Acme MCP Server",
  "url": "https://mcp.acme-corp.com/api"
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp
using RestSharp;

var client = new RestClient("https://api.getdial.ai/api/v1/context-mcps");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"name\": \"Acme MCP Server\",\n  \"url\": \"https://mcp.acme-corp.com/api\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = [
  "name": "Acme MCP Server",
  "url": "https://mcp.acme-corp.com/api"
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.getdial.ai/api/v1/context-mcps")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```