# initialize (/docs/reference/mcp/initialize)

`POST https://api.corespeed.io/mcp` — JSON-RPC method `initialize`

Most MCP clients send this automatically as their first call. It negotiates the
protocol version and reports which capabilities the server exposes. The result
can also carry `instructions`: guidance the agent reads at session start, on
memory recall and, where Smart Approvals is available, on approvals.

A client on protocol revision `2026-07-28` does not send `initialize`. It sends
a per-request `_meta` envelope instead, and reads the same capabilities and
instructions from `server/discover`.

#### Authorizations

* `Authorization` (string, header, required) — `Bearer <token>` — an MCP OAuth token, an `sk-cs-…` API key or `sk-csa-…` agent key, or a user session JWT. `x-api-key: <sk-cs-…>` is accepted in its place.
* `Accept` (string, header, required) — `application/json, text/event-stream` — the Streamable HTTP transport requires both media types. This 2025-era request is answered as one `text/event-stream` event; its `data:` line is the JSON-RPC response.
* `Content-Type` (string, header, required) — `application/json`. The transport rejects anything else with `415`.

#### Request

* `protocolVersion` (string, required) — The version your client speaks. Supported: `2025-11-25` (latest), `2025-06-18`, `2025-03-26`, `2024-11-05`, `2024-10-07`. An unsupported value is answered with the latest version instead of an error, so read the version in the response rather than assuming yours was accepted.
* `capabilities` (object, required) — Client capabilities. Send `{}` when your client has none to advertise.
* `clientInfo` (object, required) — `{ "name": string, "version": string }`. Part of the MCP handshake; the gateway does not copy it onto activity events, which are emitted per `tools/call`.

**curl**

```bash
curl https://api.corespeed.io/mcp \
  -H "Authorization: Bearer $CORESPEED_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "initialize",
    "params": {
      "protocolVersion": "2025-06-18",
      "capabilities": {},
      "clientInfo": { "name": "my-agent", "version": "1.0.0" }
    }
  }'
```

**TypeScript**

```ts
const res = await fetch("https://api.corespeed.io/mcp", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CORESPEED_API_KEY}`,
    "Content-Type": "application/json",
    Accept: "application/json, text/event-stream",
  },
  body: JSON.stringify({
    jsonrpc: "2.0",
    id: 1,
    method: "initialize",
    params: {
      protocolVersion: "2025-06-18",
      capabilities: {},
      clientInfo: { name: "my-agent", version: "1.0.0" },
    },
  }),
});

// One SSE event: the JSON-RPC response is its data line.
const data = (await res.text()).split("\n").filter((line) => line.startsWith("data: ")).at(-1)!;
const { result } = JSON.parse(data.slice("data: ".length));
console.log(result.protocolVersion, result.serverInfo);
```

**Python**

```python
import json
import os
import httpx

res = httpx.post(
    "https://api.corespeed.io/mcp",
    headers={
        "Authorization": f"Bearer {os.environ['CORESPEED_API_KEY']}",
        "Content-Type": "application/json",
        "Accept": "application/json, text/event-stream",
    },
    json={
        "jsonrpc": "2.0",
        "id": 1,
        "method": "initialize",
        "params": {
            "protocolVersion": "2025-06-18",
            "capabilities": {},
            "clientInfo": {"name": "my-agent", "version": "1.0.0"},
        },
    },
)

# One SSE event: the JSON-RPC response is its data line.
data = [line for line in res.text.splitlines() if line.startswith("data: ")][-1]
result = json.loads(data[len("data: "):])["result"]
print(result["protocolVersion"], result["serverInfo"])
```

**Go**

```go
package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"os"
	"strings"
)

func main() {
	body, _ := json.Marshal(map[string]any{
		"jsonrpc": "2.0",
		"id":      1,
		"method":  "initialize",
		"params": map[string]any{
			"protocolVersion": "2025-06-18",
			"capabilities":    map[string]any{},
			"clientInfo":      map[string]any{"name": "my-agent", "version": "1.0.0"},
		},
	})

	req, _ := http.NewRequest("POST", "https://api.corespeed.io/mcp", bytes.NewReader(body))
	req.Header.Set("Authorization", "Bearer "+os.Getenv("CORESPEED_API_KEY"))
	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("Accept", "application/json, text/event-stream")

	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()

	// One SSE event: the JSON-RPC response is its data line.
	raw, _ := io.ReadAll(res.Body)
	var data string
	for _, line := range strings.Split(string(raw), "\n") {
		if strings.HasPrefix(line, "data: ") {
			data = strings.TrimPrefix(line, "data: ")
		}
	}

	var out struct {
		Result struct {
			ProtocolVersion string         `json:"protocolVersion"`
			ServerInfo      map[string]any `json:"serverInfo"`
		} `json:"result"`
	}
	json.Unmarshal([]byte(data), &out)
	fmt.Println(out.Result.ProtocolVersion, out.Result.ServerInfo)
}
```

**200 OK** — Session negotiated

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "protocolVersion": "2025-06-18",
    "capabilities": {
      "tools": { "listChanged": true }
    },
    "serverInfo": {
      "name": "mcp-gateway",
      "version": "1.0.0"
    },
    "instructions": "Persistent cross-session memory is connected (the memory__* tools). …"
  }
}
```

**401 Unauthorized** — No credential

The `WWW-Authenticate` header carries the RFC 9728 pointer an OAuth-capable
client follows to discover the authorization server.

```http
WWW-Authenticate: Bearer error="invalid_token",
  error_description="Authorization needed",
  resource_metadata="https://api.corespeed.io/.well-known/oauth-protected-resource/mcp"
```

```json
{
  "error": {
    "type": "authentication_error",
    "code": "missing_authorization",
    "message": "Authorization header or x-api-key is required"
  }
}
```