-
Notifications
You must be signed in to change notification settings - Fork 133
Expand file tree
/
Copy pathMcpElements.php
More file actions
132 lines (123 loc) · 4.35 KB
/
McpElements.php
File metadata and controls
132 lines (123 loc) · 4.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
<?php
/*
* This file is part of the official PHP MCP SDK.
*
* A collaboration between Symfony and the PHP Foundation.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Mcp\Example\Server\OAuthKeycloak;
use Mcp\Capability\Attribute\McpPrompt;
use Mcp\Capability\Attribute\McpResource;
use Mcp\Capability\Attribute\McpTool;
use Mcp\Server\RequestContext;
/**
* MCP elements for the OAuth Keycloak example.
*
* These tools demonstrate a protected MCP server.
* All requests must include a valid OAuth bearer token.
*/
final class McpElements
{
/**
* Confirms the user is authenticated.
*
* The fact that this tool executes means the request passed OAuth validation.
*
* @return array<string, mixed>
*/
#[McpTool(
name: 'get_auth_status',
description: 'Confirm authentication status - only accessible with valid OAuth token'
)]
public function getAuthStatus(RequestContext $context): array
{
$meta = $context->getRequest()->getMeta() ?? [];
$oauth = isset($meta['oauth']) && \is_array($meta['oauth']) ? $meta['oauth'] : [];
$claims = isset($oauth['oauth.claims']) && \is_array($oauth['oauth.claims']) ? $oauth['oauth.claims'] : [];
$scopes = isset($oauth['oauth.scopes']) && \is_array($oauth['oauth.scopes']) ? $oauth['oauth.scopes'] : [];
return [
'authenticated' => true,
'provider' => 'Keycloak',
'message' => 'You have successfully authenticated with OAuth!',
'timestamp' => date('c'),
'user' => [
'subject' => $oauth['oauth.subject'] ?? ($claims['sub'] ?? null),
'username' => $claims['preferred_username'] ?? null,
'name' => $claims['name'] ?? null,
'email' => $claims['email'] ?? null,
'issuer' => $claims['iss'] ?? null,
'audience' => $claims['aud'] ?? null,
'scopes' => $scopes,
'expires_at' => isset($claims['exp']) && is_numeric($claims['exp'])
? date('c', (int) $claims['exp'])
: null,
],
'note' => 'This endpoint is protected by JWT validation. If you see this, your token was valid.',
];
}
/**
* Simulates calling a protected external API.
*
* @return array<string, mixed>
*/
#[McpTool(
name: 'call_protected_api',
description: 'Simulate calling a protected external API endpoint'
)]
public function callProtectedApi(
string $endpoint,
string $method = 'GET',
): array {
// In a real implementation, you would:
// 1. Use token exchange to get a token for the downstream API
// 2. Or use client credentials with the user's context
// 3. Make the actual HTTP call to the protected API
return [
'status' => 'success',
'message' => \sprintf('Simulated %s request to %s', $method, $endpoint),
'simulated_response' => [
'data' => 'This is simulated data from the protected API',
'timestamp' => date('c'),
],
];
}
/**
* Returns the current server time and status.
*
* @return array<string, mixed>
*/
#[McpResource(
uri: 'server://status',
name: 'server_status',
description: 'Current server status (protected resource)',
mimeType: 'application/json'
)]
public function getServerStatus(): array
{
return [
'status' => 'healthy',
'timestamp' => date('c'),
'php_version' => \PHP_VERSION,
'memory_usage_mb' => round(memory_get_usage(true) / 1024 / 1024, 2),
'protected' => true,
];
}
/**
* A greeting prompt.
*/
#[McpPrompt(
name: 'greeting',
description: 'Generate a greeting message'
)]
public function greeting(string $style = 'formal'): string
{
return match ($style) {
'casual' => 'Hey there! Welcome to the protected MCP server!',
'formal' => 'Good day. Welcome to the OAuth-protected MCP server.',
'friendly' => 'Hello! Great to have you here!',
default => 'Welcome to the MCP server!',
};
}
}