The Authdog MCP Dart SDK (authdog_mcp) verifies a bearer token presented to your MCP server. AuthdogVerifier.verifyToken calls GET {baseUrl}/v1/userinfo with the token and returns an AuthInfo. It requires Dart SDK ^3.0.0 and depends on package:http. It is a token verifier only, not an OAuth client or an MCP server framework.
Availability
The Dart SDK is source-available in `dart/` of authdog/mcp-sdk. The README shows authdog_mcp: ^0.1.0, but publication to pub.dev is unverified and the package may not resolve from the registry yet. Install from source until it does.
Install
Check out authdog/mcp-sdk and use a path dependency in pubspec.yaml:
dependencies:
authdog_mcp:
path: ../mcp-sdk/dartdart pub getConfigure
import 'package:authdog_mcp/authdog_mcp.dart';
final verifier = AuthdogVerifier(
baseUrl: 'https://api.authdog.com',
timeout: const Duration(seconds: 10),
);| Parameter | Type | Default | Notes |
|---|---|---|---|
baseUrl |
String |
required | Authdog API base URL. One trailing / is stripped. |
timeout |
Duration |
10 seconds | Per-request timeout. |
client |
http.Client? |
null |
Injected client, mainly for tests. When omitted, the verifier creates its own. |
Every request sends User-Agent: authdog-mcp-dart-sdk/0.1.0. Call verifier.close() when you are done to release the HTTP client. Per the SDK docs this applies when the verifier owns the client, that is, when you did not inject one.
Verify a token
try {
final info = await verifier.verifyToken('incoming-access-token');
print(info.subject);
print(info.email);
} on AuthenticationException catch (e) {
// HTTP 401
} on ApiException catch (e) {
// any other failure
} finally {
verifier.close();
}It sends Authorization: Bearer <token> and, on a 2xx response, returns:
| Field | Type | Source |
|---|---|---|
token |
String |
the verified access token |
subject |
String |
user.id (empty string if absent) |
username |
String |
user.userName (empty string if absent) |
email |
String? |
first non-empty user.emails[].value, else null |
scopes |
List<String> |
always empty (userinfo returns no scopes) |
expiresAt |
DateTime? |
UTC, now + session.remainingSeconds; null if the response has no numeric value |
user |
Map<String, dynamic> |
raw user object from the response |
Unlike the Kotlin and Swift SDKs, the Dart verifier does not use a typed user model, and a 2xx response missing user fields yields empty values rather than an error. Check that subject is non-empty if you depend on it. Do not use scopes for authorization yet. The verifier does not cache results; each call is one HTTP request.
Wire into an MCP server
verifyToken returns the identity you attach to your transport's request context. Adapt it to your token-verification hook and treat any AuthdogException as unauthenticated:
Future<AuthInfo?> authenticate(String token) async {
try {
return await verifier.verifyToken(token);
} on AuthdogException {
return null; // invalid token or upstream failure
}
}Collapsing every failure to null also hides outages. Catch AuthenticationException and ApiException separately if you need to tell a rejected token from an upstream error.
Errors
All errors extend AuthdogException, which exposes a message string.
| Exception | When |
|---|---|
AuthenticationException |
HTTP 401. Message: Unauthorized - invalid or expired token. |
ApiException |
Any other non-2xx status (message includes the status and body), a transport failure or timeout, or a body that is not a valid JSON object. |
AuthdogException |
Base type of both. |
Related
- MCP SDKs: all language token verifiers
- MCP authentication: how Authdog authenticates MCP clients