Skip to content

Commit 0d6d069

Browse files
maximthomasCopilot
andauthored
OpenAM MCP server (#935)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent 727b718 commit 0d6d069

40 files changed

Lines changed: 3103 additions & 0 deletions

openam-mcp-server/README.md

Lines changed: 345 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,345 @@
1+
# OpenAM MCP Server
2+
3+
OpenAM MCP Server is a lightweight management service for OpenAM user accounts. It allows administrators to create, update, delete, and reset passwords for users, as well as retrieve authentication modules and chains configurations.
4+
5+
## Prerequisites
6+
* JDK 17+
7+
* [OpenAM](http://github.com/OpenIdentityPlatform/OpenAM) installed
8+
9+
## Quick Start
10+
Set the `OPENAM_URL` environment variable, i.e., http://openam.example.org:8080/openam
11+
Set the `OPENAM_ADMIN_USERNAME` (i.e., `amadmin`) and the `OPENAM_ADMIN_PASSWORD` environment variables (i.e., `passw0rd`).
12+
13+
```bash
14+
export OPENAM_URL=http://openam.example.org:8080/openam
15+
export OPENAM_ADMIN_USERNAME=amadmin
16+
export OPENAM_ADMIN_PASSWORD=passw0rd
17+
```
18+
19+
Clone and run from source:
20+
21+
```bash
22+
mvn spring-boot:run
23+
```
24+
Or build and run the JAR:
25+
26+
```bash
27+
cd openam-mcp-server
28+
mvn package -DskipTests=true && java -jar ./target/openam-mcp-server-*.jar
29+
```
30+
31+
## Advanced Authentication
32+
33+
> [!IMPORTANT]
34+
> Using administrative credentials directly in the MCP server can be insecure. This server therefore supports OpenAM's OAuth 2.0 protocol.
35+
36+
This approach requires additional OpenAM configuration.
37+
38+
### OpenAM OAuth2.0 Service Configuration
39+
40+
1. In the OpenAM admin console, select the root realm.
41+
1. Select **Configure OAuth Provider****Configure OAuth2.0**.
42+
1. Leave the settings unchanged and click **Create**.
43+
44+
Configure the OAuth 2.0 Provider with the following settings:
45+
46+
| Setting | Value |
47+
|------------------------------------------------------------------|---------|
48+
| Use Stateless Access & Refresh Tokens | enabled |
49+
| User Profile Attribute(s) the Resource Owner is Authenticated On | uid |
50+
| Supported Scopes | profile |
51+
| OAuth2 Token Signing Algorithm | RS256 |
52+
| Allow Open Dynamic Client Registration | enabled |
53+
54+
For more details, see the OpenAM OAuth 2.0 documentation: https://doc.openidentityplatform.org/openam/admin-guide/chap-oauth2
55+
56+
### Authentication Chain Configuration
57+
58+
Create an OpenAM OAuth 2.0 authentication chain so the MCP server can exchange an access token for an SSO token to manage identities.
59+
60+
1. In the admin console, select the root realm.
61+
1. In the left menu go to **Authentication****Modules** and create a new module with named `oidc` of type `OpenID Connect id_token bearer`.
62+
63+
Configure the `oidc` module as follows:
64+
65+
| Setting | Value |
66+
|----------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------|
67+
| OpenID Connect validation configuration value | OpenAM's .well-known/openid-configuration endpoint, i.e., http://openam.example.org:8080/openam/oauth2/.well-known/openid-configuration |
68+
| Name of OpenID Connect ID Token Issuer | http://openam.example.org:8080/openam/oauth2 |
69+
| Mapping of jwt attributes to local LDAP attributes | sub=uid |
70+
| Audience name | Your MCP client's client ID, for example openam-mcp-server |
71+
72+
Create an authentication chain:
73+
74+
1. In the admin console, select the root realm.
75+
1. In the left menu select **Authentication****Chains**
76+
1. Create a new chain named `oidc` with the following configuration:
77+
78+
| Module | Criteria |
79+
|--------|------------|
80+
| oidc | REQUISITE |
81+
82+
Finally, enable OAuth 2.0 in the MCP server:
83+
84+
```bash
85+
export OPENAM_USE_OAUTH=true
86+
```
87+
88+
## Available MCP Server Tools
89+
90+
### Authentication Service Tools
91+
92+
```java
93+
@Tool(name = "get_auth_modules", description = "Returns OpenAM authentication modules list")
94+
public List<AuthModule> getAuthModules(@ToolParam(required = false, description = "If not set, uses root realm") String realm)
95+
96+
@Tool(name = "get_auth_chains", description = "Returns OpenAM authentication chains with modules")
97+
public List<AuthChain> getOpenAMAuthChains(@ToolParam(required = false, description = "If not set, uses root realm") String realm)
98+
99+
@Tool(name = "get_available_modules", description = "Returns all available authentication modules")
100+
public List<CoreAuthModule> getAvailableModuleList()
101+
102+
103+
```
104+
105+
### Realm Tools
106+
107+
```java
108+
@Tool(name = "get_realms", description = "Returns OpenAM realm list")
109+
public List<Realm> getRealms()
110+
```
111+
112+
### User Tools
113+
114+
```java
115+
@Tool(name = "get_users", description = "Returns OpenAM user list from the default (root) realm")
116+
public List<User> getUsers(@ToolParam(required = false, description = "If not set, uses root realm") String realm,
117+
@ToolParam(required = false, description = "Username filter") String filter)
118+
119+
@Tool(name = "set_user_attribute", description = "Sets the attribute value for a user")
120+
public User setUserAttribute(@ToolParam(required = false, description = "If not set, uses root realm") String realm,
121+
@ToolParam(description = "username") String username,
122+
@ToolParam(description = "user attribute name") String attribute,
123+
@ToolParam(description = "user attribute value") String value)
124+
125+
@Tool(name = "set_user_password", description = "Sets the password for a user")
126+
public User setUserPassword(@ToolParam(required = false, description = "If not set, uses root realm") String realm,
127+
@ToolParam(description = "username") String username,
128+
@ToolParam(description = "user password") String password)
129+
130+
@Tool(name = "create_user", description = "Creates a new user")
131+
public User createUser(@ToolParam(required = false, description = "If not set, uses root realm") String realm,
132+
@ToolParam(description = "Username (login)") String userName,
133+
@ToolParam(description = "Password (min length 8)") String password,
134+
@ToolParam(required = false, description = "User family name") String familyName,
135+
@ToolParam(required = false, description = "User given name") String givenName,
136+
@ToolParam(required = false, description = "Name") String name,
137+
@ToolParam(required = false, description = "Email") String mail,
138+
@ToolParam(required = false, description = "Phone number") String phone)
139+
140+
@Tool(name = "delete_user", description = "Deletes a user")
141+
public Map<String, String> deleteUser(@ToolParam(required = false, description = "If not set, uses root realm") String realm,
142+
@ToolParam(description = "Username (login)") String username)
143+
144+
```
145+
146+
In JSON-RPC format:
147+
```json
148+
{
149+
"tools": [
150+
{
151+
"name": "set_user_password",
152+
"description": "Sets the password for a user",
153+
"inputSchema": {
154+
"type": "object",
155+
"properties": {
156+
"arg0": {
157+
"type": "string",
158+
"description": "If not set, uses root realm"
159+
},
160+
"arg1": {
161+
"type": "string",
162+
"description": "username"
163+
},
164+
"arg2": {
165+
"type": "string",
166+
"description": "user password"
167+
}
168+
},
169+
"required": [
170+
"arg1",
171+
"arg2"
172+
],
173+
"additionalProperties": false
174+
}
175+
},
176+
{
177+
"name": "set_user_attribute",
178+
"description": "Sets the attribute value for a user",
179+
"inputSchema": {
180+
"type": "object",
181+
"properties": {
182+
"arg0": {
183+
"type": "string",
184+
"description": "If not set, uses root realm"
185+
},
186+
"arg1": {
187+
"type": "string",
188+
"description": "username"
189+
},
190+
"arg2": {
191+
"type": "string",
192+
"description": "user attribute name"
193+
},
194+
"arg3": {
195+
"type": "string",
196+
"description": "user attribute value"
197+
}
198+
},
199+
"required": [
200+
"arg1",
201+
"arg2",
202+
"arg3"
203+
],
204+
"additionalProperties": false
205+
}
206+
},
207+
{
208+
"name": "get_realms",
209+
"description": "Returns OpenAM realm list",
210+
"inputSchema": {
211+
"type": "object",
212+
"properties": {},
213+
"required": [],
214+
"additionalProperties": false
215+
}
216+
},
217+
{
218+
"name": "get_users",
219+
"description": "Returns OpenAM user list from the default (root) realm",
220+
"inputSchema": {
221+
"type": "object",
222+
"properties": {
223+
"arg0": {
224+
"type": "string",
225+
"description": "If not set, uses root realm"
226+
},
227+
"arg1": {
228+
"type": "string",
229+
"description": "Username filter"
230+
}
231+
},
232+
"required": [],
233+
"additionalProperties": false
234+
}
235+
},
236+
{
237+
"name": "get_auth_modules",
238+
"description": "Returns OpenAM authentication modules list",
239+
"inputSchema": {
240+
"type": "object",
241+
"properties": {
242+
"arg0": {
243+
"type": "string",
244+
"description": "If not set, uses root realm"
245+
}
246+
},
247+
"required": [],
248+
"additionalProperties": false
249+
}
250+
},
251+
{
252+
"name": "create_user",
253+
"description": "Creates a new user",
254+
"inputSchema": {
255+
"type": "object",
256+
"properties": {
257+
"arg0": {
258+
"type": "string",
259+
"description": "If not set, uses root realm"
260+
},
261+
"arg1": {
262+
"type": "string",
263+
"description": "Username (login)"
264+
},
265+
"arg2": {
266+
"type": "string",
267+
"description": "Password (min length 8)"
268+
},
269+
"arg3": {
270+
"type": "string",
271+
"description": "User family name"
272+
},
273+
"arg4": {
274+
"type": "string",
275+
"description": "User given name"
276+
},
277+
"arg5": {
278+
"type": "string",
279+
"description": "Name"
280+
},
281+
"arg6": {
282+
"type": "string",
283+
"description": "Email"
284+
},
285+
"arg7": {
286+
"type": "string",
287+
"description": "Phone number"
288+
}
289+
},
290+
"required": [
291+
"arg1",
292+
"arg2"
293+
],
294+
"additionalProperties": false
295+
}
296+
},
297+
{
298+
"name": "delete_user",
299+
"description": "Deletes a user",
300+
"inputSchema": {
301+
"type": "object",
302+
"properties": {
303+
"arg0": {
304+
"type": "string",
305+
"description": "If not set, uses root realm"
306+
},
307+
"arg1": {
308+
"type": "string",
309+
"description": "Username (login)"
310+
}
311+
},
312+
"required": [
313+
"arg1"
314+
],
315+
"additionalProperties": false
316+
}
317+
},
318+
{
319+
"name": "get_available_modules",
320+
"description": "Returns all available authentication modules",
321+
"inputSchema": {
322+
"type": "object",
323+
"properties": {},
324+
"required": [],
325+
"additionalProperties": false
326+
}
327+
},
328+
{
329+
"name": "get_auth_chains",
330+
"description": "Returns OpenAM authentication chains with modules",
331+
"inputSchema": {
332+
"type": "object",
333+
"properties": {
334+
"arg0": {
335+
"type": "string",
336+
"description": "If not set, uses root realm"
337+
}
338+
},
339+
"required": [],
340+
"additionalProperties": false
341+
}
342+
}
343+
]
344+
}
345+
```

0 commit comments

Comments
 (0)