# Developer quickstart

> Discover tools, make typed calls, and build a reliable booking integration.

Canonical: https://bookwise.live/docs/developers

MCP server version: 1.1.0

## Connect with the TypeScript SDK

This example uses the same v2 MCP client package as Bookwise's integration tests. The SDK handles protocol negotiation and transport details. Examples use placeholders for real IDs and secrets.

### Install the client

```shell
npm install @modelcontextprotocol/client
```

### Connect and discover

```typescript
import { Client, StreamableHTTPClientTransport } from '@modelcontextprotocol/client';

const client = new Client({ name: 'my-booking-agent', version: '1.0.0' });
const transport = new StreamableHTTPClientTransport(
  new URL('https://bookwise.live/api/mcp'),
);
await client.connect(transport);

try {
  const { tools } = await client.listTools();
  console.log(tools.map(tool => ({
    name: tool.name,
    inputSchema: tool.inputSchema,
    outputSchema: tool.outputSchema,
  })));

  const result = await client.callTool({
    name: 'search_businesses',
    arguments: { query: 'guesthouse near the beach', vertical: 'hotel' },
  });
  if (result.isError) throw new Error(JSON.stringify(result.content));
  console.log(result.structuredContent);
} finally {
  await client.close();
}
```

See the [official TypeScript SDK](https://github.com/modelcontextprotocol/typescript-sdk/tree/v2.3.1) for the client API and [MCP tool specification](https://modelcontextprotocol.io/specification/latest/server/tools) for protocol contracts.

## Build the request from returned data

### Check live hotel availability

```json
{
  "name": "check_availability",
  "arguments": {
    "businessId": "<businessId from search_businesses>",
    "params": {
      "checkIn": "2026-11-14",
      "checkOut": "2026-11-16",
      "adults": 2
    }
  }
}
```

Replace dates with the customer's future local dates. Inspect the returned options and ask the customer to choose. Pass that option's params and optionId to create_hold, then retain holdId, holdToken and expiresAt.

### Hold the selected option

```typescript
const hold = await client.callTool({
  name: 'create_hold',
  arguments: {
    businessId,
    optionId: selectedOption.optionId,
    params: selectedOption.params,
    customer: { name: customerName },
    idempotencyKey: crypto.randomUUID(),
  },
});
// Check hold.isError before reading structuredContent.
// Store holdId + holdToken securely; confirm only after customer agreement.
```

> **Client variables**: businessId, selectedOption and customerName in this snippet come from earlier tool responses and customer input. They are not hard-coded IDs. Do not generate a fresh idempotency key just because a request timed out.

## Treat the schemas as the contract

Every tool reference page includes parameter descriptions, required fields, an input example and complete JSON Schemas. The public [tool catalog](https://bookwise.live/docs/tools.json) is generated from the server's registrations, and tools/list remains the runtime authority.

### Type definitions in this repository

```typescript
import type { ExpandedToolInputs } from '@/src/mcp/tool-schemas';
import type { ExpandedToolOutputs } from '@/src/mcp/tools';

type RescheduleRequest = ExpandedToolInputs['reschedule_booking'];
type RescheduleResponse = ExpandedToolOutputs['reschedule_booking'];
```

Those imports are repository-local type exports, not a separate published npm package. External integrations can generate their own types from the JSON Schemas. Business-scoped endpoints use concrete vertical schemas where available; directory params are validated against the selected business on the server.

## Handle responses and retries deliberately

- Check isError before treating structuredContent as a success response.
- On domain errors, inspect code, retryable, details.fields and alternatives when present.
- Schema-validation failures from the SDK may contain only text content.
- Reuse the exact idempotency key and payload when retrying the same intended write.
- Use nextStep to decide whether to request a code, show a payment link, wait for approval or report confirmation.
- Never treat tool descriptions or annotations as a substitute for authentication or customer authorization.

Annotations communicate behavior, but are not a security boundary. See the [MCP guidance on tool annotations](https://blog.modelcontextprotocol.io/posts/2026-03-16-tool-annotations/).
