Skip to main content
Glama
yingcaihuang

Authentik OAuth MCP Server

by yingcaihuang
README.md
# Authentik OAuth MCP Server (Node.js)

Stdio 模式 MCP Server。第一次调用工具时自动弹浏览器完成 Authentik OAuth 登录,拿到 token 后调用 Authentik API。

> 这是 Python 版 (`fastmcp-code/server.py`) 的 Node.js 移植,功能对等。

## 认证流程

```
MCP 客户端                                  Authentik (IDP)
    │                                           │
    ├─ 加入 MCP → 立即握手成功                    │
    │                                           │
    ├─ 首次调用工具,本地无 token                  │
    │  (起临时端口 19280, 打开浏览器)              │
    │                                           │
    │                              用户登录 ◄────┤
    │◄── 回调临时端口 (authorization code) ──────┤
    │                                           │
    ├─── code + PKCE verifier → token ────────►│
    │◄── access_token + refresh_token ─────────┤
    │                                           │
    ├─ 保存 token.json,完成工具调用              │
```

浏览器和回调服务器都在**运行此进程的机器**上,因此仅适用于**本地 stdio** 场景。

## 环境要求

- Node.js >= 18 (自带 `fetch`)

## 快速开始

```bash
npm install
```

## 配置 (环境变量)

支持两种方式,二选一 (两者都给时优先用自动发现)。

### 方式 1: 自动发现 (推荐)

| 变量 | 必填 | 说明 |
|------|------|------|
| `AUTHENTIK_CLIENT_ID` | 是 | OAuth2 Public Client 的 client_id |
| `AUTHENTIK_OIDC_CONFIG_URL` | 是 | `.well-known/openid-configuration` 地址 |

### 方式 2: 常规 OIDC 手动端点

| 变量 | 必填 | 说明 |
|------|------|------|
| `AUTHENTIK_CLIENT_ID` | 是 | client_id |
| `AUTHENTIK_AUTHORIZATION_ENDPOINT` | 是 | 授权端点 |
| `AUTHENTIK_TOKEN_ENDPOINT` | 是 | token 端点 |
| `AUTHENTIK_USERINFO_ENDPOINT` | 否 | userinfo 端点 (call_userinfo 需要) |

### 可选项

| 变量 | 默认 | 说明 |
|------|------|------|
| `AUTHENTIK_API_BASE` | 从上面 URL 推导 `域名/api/v3` | Authentik REST API 基地址 |
| `AUTHENTIK_SCOPES` | `openid profile email offline_access goauthentik.io/api` | 请求的 scope |
| `AUTHENTIK_CALLBACK_PORT` | `19280` | 本地回调端口 |
| `AUTHENTIK_LOGIN_TIMEOUT` | `120` | 等待浏览器回调的超时秒数 |

> `goauthentik.io/api` (界面名 "authentik API access") 是 Authentik 内置特殊 scope,
> 查用户信息 / 应用列表都需要它,无需在 provider 里额外配置 Scope Mapping。

## MCP 客户端配置

在 MCP 客户端 (如 Quick Desktop) 的配置中加入。把 `args` 路径换成你机器上 `server.js` 的实际路径 (Windows 用双反斜杠)。

**方式 1 (自动发现):**

```json
{
  "mcpServers": {
    "authentik-test": {
      "command": "node",
      "args": ["/path/to/node-mcp-oauth/server.js"],
      "env": {
        "AUTHENTIK_CLIENT_ID": "your-client-id",
        "AUTHENTIK_OIDC_CONFIG_URL": "https://your-authentik/application/o/<slug>/.well-known/openid-configuration"
      }
    }
  }
}
```

**方式 2 (手动端点):**

```json
{
  "mcpServers": {
    "authentik-test": {
      "command": "node",
      "args": ["/path/to/node-mcp-oauth/server.js"],
      "env": {
        "AUTHENTIK_CLIENT_ID": "your-client-id",
        "AUTHENTIK_AUTHORIZATION_ENDPOINT": "https://your-authentik/application/o/authorize/",
        "AUTHENTIK_TOKEN_ENDPOINT": "https://your-authentik/application/o/token/",
        "AUTHENTIK_USERINFO_ENDPOINT": "https://your-authentik/application/o/userinfo/"
      }
    }
  }
}
```

## 工具清单

| 工具 | 类型 | 作用 |
|------|------|------|
| `whoami` | 身份 | 解码 access_token 看当前用户 (username/email/name) |
| `token_status` | 状态 | 看 token 是否有效、过期时间 (不触发登录) |
| `call_userinfo` | GET | 调 OIDC `userinfo_endpoint` (标准 OIDC 声明) |
| `login` | 认证 | 清除 token 并重新弹浏览器登录 |
| `refresh_token` | 认证 | 用 refresh_token 刷新 access_token (不弹浏览器) |
| `get_user_info` | GET | 调 `/core/users/me/` 查用户详情 (需 API scope) |
| `list_applications` | GET | 调 `/core/applications/` 查可访问应用 (需 API scope) |

## 文件结构

```
node-authentik-mcp/
├── server.js        # MCP 工具定义 + stdio 启动
├── auth.js          # OAuth 登录 + token 管理 + API 调用
├── config.js        # 环境变量配置 + 校验
├── package.json
├── .gitignore       # 忽略 token.json / node_modules
└── README.md
```

## Authentik 侧配置

- **Provider 类型**: OAuth2/OpenID Provider
- **Client Type**: Public (桌面/CLI 无法安全保存 secret,用 Public + PKCE)
- **Redirect URIs**: `http://localhost:19280/callback` (端口按 `AUTHENTIK_CALLBACK_PORT`)
- **PKCE**: S256 (代码强制携带)

## 安全提示

- `token.json` 存有 access_token 和 refresh_token,已在 `.gitignore` 中,切勿提交。
- 代码默认跳过 TLS 校验 (`NODE_TLS_REJECT_UNAUTHORIZED=0`) 以兼容自签证书,仅限本地测试;生产环境请移除 `config.js` 末尾那行。