docs: rebuild the v2 documentation around a task-based page tree (#2397)
This commit is contained in:
parent
708d5455d9
commit
b153505428
1 changed files with 11884 additions and 4971 deletions
106
docs/clients/connect.md
Normal file
106
docs/clients/connect.md
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
---
|
||||
shape: how-to
|
||||
---
|
||||
# Connect to a server
|
||||
|
||||
A **client** holds one connection to one server: construct a `Client`, pick a **transport**, and `connect()`.
|
||||
|
||||
## Create a client and connect over HTTP
|
||||
|
||||
`Client` takes a name and a version; `StreamableHTTPClientTransport` takes the server's MCP endpoint URL.
|
||||
|
||||
```ts source="../../examples/guides/clients/connect.examples.ts#connect_streamableHttp"
|
||||
import { Client, StreamableHTTPClientTransport } from '@modelcontextprotocol/client';
|
||||
|
||||
const client = new Client({ name: 'my-client', version: '1.0.0' });
|
||||
|
||||
const transport = new StreamableHTTPClientTransport(new URL('http://localhost:3000/mcp'));
|
||||
|
||||
await client.connect(transport);
|
||||
```
|
||||
|
||||
`connect()` runs the `initialize` handshake and resolves once it completes. The client now holds the negotiated protocol version, the server's capabilities, and its instructions.
|
||||
|
||||
::: info Coming from v1?
|
||||
`Client` and the transport classes keep their names — only the import paths moved, to `@modelcontextprotocol/client` and its `/stdio` subpath. Run the codemod, then see the [upgrade guide](../migration/upgrade-to-v2.md).
|
||||
:::
|
||||
|
||||
## Connect to a local process over stdio
|
||||
|
||||
For a server you run as a child process, change only the transport: `StdioClientTransport`, imported from `@modelcontextprotocol/client/stdio`, spawns the command and speaks JSON-RPC over its stdin and stdout.
|
||||
|
||||
```ts source="../../examples/guides/clients/connect.examples.ts#connect_stdio"
|
||||
const client = new Client({ name: 'my-client', version: '1.0.0' });
|
||||
|
||||
const transport = new StdioClientTransport({ command: 'node', args: ['server.js'] });
|
||||
|
||||
await client.connect(transport);
|
||||
```
|
||||
|
||||
`server.js` runs as a child of your process. `close()` shuts it down in order: close stdin, then `SIGTERM`, then `SIGKILL`.
|
||||
|
||||
::: tip
|
||||
`InMemoryTransport.createLinkedPair()` is the third transport: it links a `Client` and an `McpServer` inside one process, no network and no child process. [Test a server](../testing.md) builds on it.
|
||||
:::
|
||||
|
||||
## Fall back to SSE for servers that predate Streamable HTTP
|
||||
|
||||
An SSE-only server speaks the older HTTP+SSE transport instead of Streamable HTTP. Try `StreamableHTTPClientTransport` first; when it fails, retry with `SSEClientTransport` on a fresh `Client`.
|
||||
|
||||
```ts source="../../examples/guides/clients/connect.examples.ts#connect_sseFallback"
|
||||
try {
|
||||
const client = new Client({ name: 'my-client', version: '1.0.0' });
|
||||
await client.connect(new StreamableHTTPClientTransport(new URL(url)));
|
||||
return client;
|
||||
} catch {
|
||||
const client = new Client({ name: 'my-client', version: '1.0.0' });
|
||||
await client.connect(new SSEClientTransport(new URL(url)));
|
||||
return client;
|
||||
}
|
||||
```
|
||||
|
||||
Whichever branch returns, the `Client` behaves the same from here on — nothing downstream depends on the transport.
|
||||
|
||||
::: info
|
||||
`versionNegotiation` in `ClientOptions` controls which protocol revision `connect()` negotiates — see [Protocol versions](../protocol-versions.md).
|
||||
:::
|
||||
|
||||
## Read what the server told you at connect time
|
||||
|
||||
Three accessors return what the server declared during the handshake; all of them return `undefined` until `connect()` resolves.
|
||||
|
||||
```ts source="../../examples/guides/clients/connect.examples.ts#connect_introspect"
|
||||
console.log(client.getServerVersion());
|
||||
console.log(client.getServerCapabilities());
|
||||
console.log(client.getInstructions());
|
||||
```
|
||||
|
||||
Connected to a server named `travel` that registered one tool and set `instructions`, that prints:
|
||||
|
||||
```
|
||||
{ name: 'travel', version: '2.1.0' }
|
||||
{ tools: { listChanged: true } }
|
||||
Call list-trips before book-trip. Dates are ISO 8601.
|
||||
```
|
||||
|
||||
The capability object gates every verb on [the next page](./calling.md): only ask for what the server advertised. `getInstructions()` is the server's usage guide for the model — put it in the system prompt.
|
||||
|
||||
## Disconnect cleanly
|
||||
|
||||
Over Streamable HTTP, terminate the server-side session, then close the client.
|
||||
|
||||
```ts source="../../examples/guides/clients/connect.examples.ts#connect_close"
|
||||
await transport.terminateSession();
|
||||
await client.close();
|
||||
```
|
||||
|
||||
`close()` tears down the transport and rejects every request still in flight with a `CONNECTION_CLOSED` error. `terminateSession()` returns without sending anything when the server never issued a session ID. On the other transports, `close()` alone is the whole teardown.
|
||||
|
||||
## Recap
|
||||
|
||||
- `new Client({ name, version })`, a transport, and `connect()` are the whole setup; `connect()` runs the `initialize` handshake.
|
||||
- `StreamableHTTPClientTransport` connects to remote servers; `StdioClientTransport`, from `@modelcontextprotocol/client/stdio`, spawns local ones; `SSEClientTransport` is the fallback for SSE-only servers.
|
||||
- `InMemoryTransport.createLinkedPair()` links a client and a server in one process.
|
||||
- After `connect()`, `getServerVersion()`, `getServerCapabilities()`, and `getInstructions()` return what the server declared.
|
||||
- `close()` tears down the transport and rejects in-flight requests.
|
||||
- Protocol-revision differences live on the protocol versions page, not here.
|
||||
Loading…
Reference in a new issue