or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

authentication.mdclient.mdindex.mdserver-advanced.mdserver-prompts.mdserver-resources.mdserver-tools.mdtransports.mdtypes.md

authentication.mddocs/

0

# Authentication

1

2

Complete OAuth 2.0 support: authorization code flow with PKCE, client registration, token management, and revocation.

3

4

## Server-Side OAuth

5

6

### OAuth Router

7

8

```typescript { .api }

9

import { mcpAuthRouter } from '@modelcontextprotocol/sdk/server/auth/router.js';

10

11

function mcpAuthRouter(options: {

12

provider: OAuthServerProvider;

13

issuerUrl: URL;

14

baseUrl: URL;

15

serviceDocumentationUrl?: URL;

16

rateLimit?: RateLimitOptions;

17

}): express.Router;

18

```

19

20

### OAuth Server Provider Interface

21

22

```typescript { .api }

23

interface OAuthServerProvider {

24

get clientsStore(): OAuthRegisteredClientsStore;

25

authorize(client: OAuthClientInformationFull, params: AuthorizationParams, res: Response): Promise<void>;

26

challengeForAuthorizationCode(client: OAuthClientInformationFull, authorizationCode: string): Promise<string>;

27

exchangeAuthorizationCode(client: OAuthClientInformationFull, authorizationCode: string, codeVerifier?: string, redirectUri?: string, resource?: URL): Promise<OAuthTokens>;

28

exchangeRefreshToken(client: OAuthClientInformationFull, refreshToken: string, scopes?: string[], resource?: URL): Promise<OAuthTokens>;

29

verifyAccessToken(token: string): Promise<AuthInfo>;

30

revokeToken?(client: OAuthClientInformationFull, request: OAuthTokenRevocationRequest): Promise<void>;

31

skipLocalPkceValidation?: boolean;

32

}

33

34

interface AuthorizationParams {

35

state?: string;

36

scopes?: string[];

37

codeChallenge: string;

38

redirectUri: string;

39

resource?: URL;

40

}

41

42

interface OAuthTokenVerifier {

43

verifyAccessToken(token: string): Promise<AuthInfo>;

44

}

45

```

46

47

### Proxy OAuth Provider

48

49

```typescript { .api }

50

import { ProxyOAuthServerProvider } from '@modelcontextprotocol/sdk/server/auth/providers/proxyProvider.js';

51

52

class ProxyOAuthServerProvider implements OAuthServerProvider {

53

constructor(options: {

54

endpoints: {

55

authorizationUrl: string;

56

tokenUrl: string;

57

revocationUrl: string;

58

};

59

verifyAccessToken: (token: string) => Promise<TokenInfo>;

60

getClient: (clientId: string) => Promise<OAuthClient | undefined>;

61

tokens?: OAuthTokens;

62

});

63

}

64

```

65

66

### OAuth Middleware

67

68

```typescript { .api }

69

import { requireBearerAuth } from '@modelcontextprotocol/sdk/server/auth/middleware/bearerAuth.js';

70

71

function requireBearerAuth(options: {

72

verifier: OAuthTokenVerifier;

73

requiredScopes?: string[];

74

resourceMetadataUrl?: string;

75

}): express.RequestHandler;

76

```

77

78

### Complete Server Example

79

80

```typescript

81

import express from 'express';

82

import { mcpAuthRouter } from '@modelcontextprotocol/sdk/server/auth/router.js';

83

import { ProxyOAuthServerProvider } from '@modelcontextprotocol/sdk/server/auth/providers/proxyProvider.js';

84

import { requireBearerAuth } from '@modelcontextprotocol/sdk/server/auth/middleware/bearerAuth.js';

85

86

const app = express();

87

88

const provider = new ProxyOAuthServerProvider({

89

endpoints: {

90

authorizationUrl: 'https://auth.example.com/oauth2/authorize',

91

tokenUrl: 'https://auth.example.com/oauth2/token',

92

revocationUrl: 'https://auth.example.com/oauth2/revoke'

93

},

94

verifyAccessToken: async (token) => ({

95

token,

96

clientId: 'client-123',

97

scopes: ['openid', 'profile']

98

}),

99

getClient: async (clientId) => ({

100

client_id: clientId,

101

redirect_uris: ['http://localhost:3000/callback']

102

})

103

});

104

105

// Mount OAuth router

106

app.use(mcpAuthRouter({

107

provider,

108

issuerUrl: new URL('https://auth.example.com'),

109

baseUrl: new URL('https://mcp.example.com'),

110

serviceDocumentationUrl: new URL('https://docs.example.com')

111

}));

112

113

// Protect MCP endpoint

114

app.post('/mcp',

115

requireBearerAuth({

116

verifier: provider,

117

requiredScopes: ['mcp:read', 'mcp:write']

118

}),

119

async (req, res) => {

120

await transport.handleRequest(req, res, req.body);

121

}

122

);

123

124

app.listen(3000);

125

```

126

127

## Client-Side OAuth

128

129

### OAuth Client Provider Interface

130

131

```typescript { .api }

132

interface OAuthClientProvider {

133

get redirectUrl(): string | URL;

134

get clientMetadata(): OAuthClientMetadata;

135

state?(): string | Promise<string>;

136

clientInformation(): OAuthClientInformation | undefined | Promise<OAuthClientInformation | undefined>;

137

saveClientInformation?(clientInformation: OAuthClientInformationFull): void | Promise<void>;

138

tokens(): OAuthTokens | undefined | Promise<OAuthTokens | undefined>;

139

saveTokens(tokens: OAuthTokens): void | Promise<void>;

140

redirectToAuthorization(authorizationUrl: URL): void | Promise<void>;

141

saveCodeVerifier(codeVerifier: string): void | Promise<void>;

142

codeVerifier(): string | Promise<string>;

143

addClientAuthentication?(headers: Headers, params: URLSearchParams, url: string | URL, metadata?: AuthorizationServerMetadata): void | Promise<void>;

144

validateResourceURL?(serverUrl: string | URL, resource?: string): Promise<URL | undefined>;

145

invalidateCredentials?(scope: 'all' | 'client' | 'tokens' | 'verifier'): void | Promise<void>;

146

}

147

```

148

149

### OAuth Authentication Flow

150

151

```typescript { .api }

152

import { auth } from '@modelcontextprotocol/sdk/client/auth.js';

153

154

async function auth(

155

provider: OAuthClientProvider,

156

options: {

157

serverUrl: URL;

158

forceRefresh?: boolean;

159

fetch?: FetchLike;

160

}

161

): Promise<{

162

tokens: OAuthTokens;

163

metadata: OAuthMetadata | OAuthProtectedResourceMetadata;

164

}>;

165

```

166

167

### OAuth HTTP Middleware

168

169

```typescript { .api }

170

import { withOAuth } from '@modelcontextprotocol/sdk/client/middleware.js';

171

172

function withOAuth(provider: OAuthClientProvider, baseUrl?: string | URL): Middleware;

173

```

174

175

### Client Example

176

177

```typescript

178

import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';

179

180

const transport = new StreamableHTTPClientTransport(

181

new URL('http://localhost:3000/mcp'),

182

{ authProvider: myOAuthProvider }

183

);

184

185

// OAuth is automatically handled by the transport

186

await client.connect(transport);

187

```

188

189

## OAuth Types

190

191

```typescript { .api }

192

interface OAuthTokens {

193

access_token: string;

194

token_type: string;

195

expires_in?: number;

196

refresh_token?: string;

197

scope?: string;

198

}

199

200

interface OAuthClientMetadata {

201

client_name?: string;

202

redirect_uris?: string[];

203

token_endpoint_auth_method?: string;

204

grant_types?: string[];

205

response_types?: string[];

206

client_uri?: string;

207

logo_uri?: string;

208

scope?: string;

209

contacts?: string[];

210

tos_uri?: string;

211

policy_uri?: string;

212

jwks_uri?: string;

213

software_id?: string;

214

software_version?: string;

215

}

216

217

interface OAuthClientInformation {

218

client_id: string;

219

redirect_uris?: string[];

220

}

221

222

interface OAuthClientInformationFull extends OAuthClientInformation {

223

client_secret?: string;

224

client_secret_expires_at?: number;

225

registration_access_token?: string;

226

registration_client_uri?: string;

227

}

228

229

interface OAuthMetadata {

230

issuer: string;

231

authorization_endpoint: string;

232

token_endpoint: string;

233

revocation_endpoint?: string;

234

registration_endpoint?: string;

235

scopes_supported?: string[];

236

response_types_supported: string[];

237

grant_types_supported?: string[];

238

token_endpoint_auth_methods_supported?: string[];

239

code_challenge_methods_supported?: string[];

240

service_documentation?: string;

241

}

242

243

interface OAuthProtectedResourceMetadata {

244

resource: string;

245

authorization_servers?: string[];

246

bearer_methods_supported?: string[];

247

resource_documentation?: string;

248

scopes_supported?: string[];

249

}

250

251

interface TokenInfo {

252

token: string;

253

clientId: string;

254

scopes: string[];

255

userId?: string;

256

expiresAt?: number;

257

}

258

```

259

260

## OAuth Error Classes

261

262

```typescript { .api }

263

class OAuthError extends Error { }

264

class InvalidRequestError extends OAuthError { }

265

class InvalidClientError extends OAuthError { }

266

class InvalidGrantError extends OAuthError { }

267

class UnauthorizedClientError extends OAuthError { }

268

class UnsupportedGrantTypeError extends OAuthError { }

269

class InvalidScopeError extends OAuthError { }

270

class AccessDeniedError extends OAuthError { }

271

class ServerError extends OAuthError { }

272

class TemporarilyUnavailableError extends OAuthError { }

273

class UnsupportedResponseTypeError extends OAuthError { }

274

class UnsupportedTokenTypeError extends OAuthError { }

275

class InvalidTokenError extends OAuthError { }

276

class MethodNotAllowedError extends OAuthError { }

277

class TooManyRequestsError extends OAuthError { }

278

class InvalidClientMetadataError extends OAuthError { }

279

class InsufficientScopeError extends OAuthError { }

280

```

281

282

## Metadata Discovery

283

284

```typescript { .api }

285

import { extractResourceMetadataUrl } from '@modelcontextprotocol/sdk/client/auth.js';

286

import { resourceUrlFromServerUrl } from '@modelcontextprotocol/sdk/shared/auth-utils.js';

287

288

function extractResourceMetadataUrl(response: Response): URL | undefined;

289

function resourceUrlFromServerUrl(url: URL | string): URL;

290

```

291