@authn8/mcp-server 1.1.1 → 1.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +73 -48
  2. package/dist/index.js +30 -2
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -1,34 +1,67 @@
1
1
  # @authn8/mcp-server
2
2
 
3
- MCP server that provides AI agents access to Authn8 2FA codes via PAT authentication.
3
+ MCP server for [Authn8](https://authn8.com), shared 2FA for teams. It lets AI agents
4
+ fetch TOTP codes for the 2FA accounts your team shares in Authn8, so an agent can
5
+ finish a sign-in without anyone reading a code out of a phone. Every code it fetches
6
+ is recorded in Authn8's access log with the name of the token that asked for it.
4
7
 
5
- ## Prerequisites
8
+ Listed in the [MCP Registry](https://registry.modelcontextprotocol.io) as
9
+ `io.github.authn8/mcp-server`.
6
10
 
7
- - An [Authn8](https://authn8.com) account
8
- - A Personal Access Token (PAT) created in the Authn8 dashboard
11
+ ## Requirements
9
12
 
10
- ## Quick Start
13
+ - An Authn8 business on a paid plan. MCP tokens are not available on the Free plan,
14
+ and a business's tokens stop working if its subscription ends.
15
+ - An MCP token. Create one in Authn8 under **Settings → MCP Tokens**
16
+ ([how to create an MCP token](https://authn8.com/knowledge-base/how-to-create-an-mcp-token)).
17
+ Tokens start with `pat_`. A token only reaches the 2FA accounts its creator can
18
+ already access, and you can narrow it further to chosen groups and give it an
19
+ expiry date.
20
+ - Node.js 18 or later, if you run the npm package. The hosted endpoint needs nothing
21
+ installed.
22
+
23
+ ## Two ways to connect
24
+
25
+ | | Hosted endpoint | npm package |
26
+ |---|---|---|
27
+ | Install | None | `npx` runs it locally |
28
+ | Transport | Streamable HTTP | stdio |
29
+ | Address | `https://api.authn8.com/mcp` | `npx -y @authn8/mcp-server` |
30
+ | Token | `Authorization: Bearer pat_...` header | `AUTHN8_API_KEY` environment variable |
31
+
32
+ Both offer the same three tools: `list_accounts`, `get_otp` and `whoami`.
33
+
34
+ ## Hosted endpoint
35
+
36
+ Point any MCP client that supports streamable HTTP at `https://api.authn8.com/mcp`
37
+ and send your token in the `Authorization` header as `Bearer pat_your_token_here`.
38
+
39
+ ### Claude Code
11
40
 
12
41
  ```bash
13
- npx @authn8/mcp-server
42
+ claude mcp add --transport http --scope user authn8 https://api.authn8.com/mcp \
43
+ --header "Authorization: Bearer pat_your_token_here"
14
44
  ```
15
45
 
16
- Set the `AUTHN8_API_KEY` environment variable to your PAT token.
46
+ ## npm package
17
47
 
18
- ## Docker
48
+ ### Claude Code
19
49
 
20
50
  ```bash
21
- docker run -e AUTHN8_API_KEY=pat_xxx ghcr.io/authn8/mcp-server
51
+ claude mcp add --env AUTHN8_API_KEY=pat_your_token_here --transport stdio --scope user authn8 \
52
+ -- npx -y @authn8/mcp-server
22
53
  ```
23
54
 
24
- ## Configuration
55
+ `--scope user` makes the server available in all your projects. Leave it out to add
56
+ it to the current project only.
25
57
 
26
58
  ### Claude Desktop
27
59
 
28
- Add to your Claude Desktop configuration file:
60
+ Open **Settings → Developer → Edit Config**, or edit the file directly:
29
61
 
30
- **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
31
- **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
62
+ - **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
63
+ - **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
64
+ - **Linux:** `~/.config/Claude/claude_desktop_config.json`
32
65
 
33
66
  ```json
34
67
  {
@@ -44,12 +77,12 @@ Add to your Claude Desktop configuration file:
44
77
  }
45
78
  ```
46
79
 
47
- ### Claude Code (CLI)
80
+ Quit and restart Claude Desktop after saving.
48
81
 
49
- Add to your Claude Code configuration file:
82
+ ### Cursor
50
83
 
51
- **macOS:** `~/.claude.json`
52
- **Windows:** `%USERPROFILE%\.claude.json`
84
+ Add this to `~/.cursor/mcp.json` for all projects, or to `.cursor/mcp.json` in a
85
+ project:
53
86
 
54
87
  ```json
55
88
  {
@@ -65,32 +98,21 @@ Add to your Claude Code configuration file:
65
98
  }
66
99
  ```
67
100
 
68
- ### Cursor
101
+ ### Other clients
69
102
 
70
- Add to your Cursor MCP settings:
103
+ Run `npx -y @authn8/mcp-server` as a stdio server with `AUTHN8_API_KEY` set.
71
104
 
72
- ```json
73
- {
74
- "mcpServers": {
75
- "authn8": {
76
- "command": "npx",
77
- "args": ["-y", "@authn8/mcp-server"],
78
- "env": {
79
- "AUTHN8_API_KEY": "pat_your_token_here"
80
- }
81
- }
82
- }
83
- }
84
- ```
85
-
86
- ## Environment Variables
105
+ ### Environment variables
87
106
 
88
107
  | Variable | Required | Default | Description |
89
108
  |----------|----------|---------|-------------|
90
- | `AUTHN8_API_KEY` | Yes | - | Your PAT token from Authn8 |
91
- | `AUTHN8_API_URL` | No | `https://api.authn8.com` | API endpoint URL |
109
+ | `AUTHN8_API_KEY` | Yes | - | Your MCP token (`pat_...`) |
110
+ | `AUTHN8_API_URL` | No | `https://api.authn8.com` | API base URL |
111
+
112
+ On startup the server checks the token and prints the business name, token name,
113
+ account count and expiry date to stderr. It exits if the token is missing or rejected.
92
114
 
93
- ## Available Tools
115
+ ## Tools
94
116
 
95
117
  All tools declare an output schema and return `structuredContent` alongside the
96
118
  text block, so clients get typed results without re-parsing JSON out of text.
@@ -117,11 +139,12 @@ Returns all 2FA accounts accessible to this token.
117
139
  Generates a TOTP code for a specific account.
118
140
 
119
141
  **Parameters:**
120
- - `account_id` (string, optional) - UUID of the account
121
- - `account_name` (string, optional) - Name or issuer domain to search for (case-insensitive partial match)
142
+ - `account_id` (string, optional): UUID of the account
143
+ - `account_name` (string, optional): name or issuer domain to search for
144
+ (case-insensitive partial match)
122
145
 
123
- Provide either `account_id` or `account_name`. If multiple accounts match the
124
- name, the tool returns them in `multipleMatches` so you can retry with an
146
+ Provide either `account_id` or `account_name`. If more than one account matches
147
+ the name, the tool returns them in `multipleMatches` so you can retry with an
125
148
  `account_id`.
126
149
 
127
150
  **Example response:**
@@ -155,17 +178,19 @@ Returns information about the current token.
155
178
  **Example response:**
156
179
  ```json
157
180
  {
158
- "tokenName": "MCP Server 2",
159
- "businessName": "Bytecode Solutions",
181
+ "tokenName": "Claude Code",
182
+ "businessName": "Acme Ltd",
160
183
  "scopedGroups": [
161
- { "id": "cfeba14a-e990-49e8-b6e5-61d63f7d68c8", "name": "HR" }
184
+ { "id": "cfeba14a-e990-49e8-b6e5-61d63f7d68c8", "name": "Engineering" }
162
185
  ],
163
- "expiresAt": "2025-12-25T23:59:59Z",
164
- "accountCount": 1
186
+ "expiresAt": "2027-06-30T23:59:59Z",
187
+ "accountCount": 12
165
188
  }
166
189
  ```
167
190
 
168
191
  ## Links
169
192
 
170
- - [Authn8](https://authn8.com) - Create an account and manage 2FA tokens
171
- - [GitHub Repository](https://github.com/authn8/mcp-server)
193
+ - [Authn8](https://authn8.com): shared 2FA for teams
194
+ - [How to create an MCP token](https://authn8.com/knowledge-base/how-to-create-an-mcp-token)
195
+ - [GitHub repository](https://github.com/authn8/mcp-server)
196
+ - [MCP Registry entry](https://registry.modelcontextprotocol.io/v0/servers?search=io.github.authn8/mcp-server)
package/dist/index.js CHANGED
@@ -21,10 +21,32 @@ var Authn8Error = class extends Error {
21
21
  };
22
22
  var accountsCache = null;
23
23
  var CACHE_TTL_MS = 60 * 1e3;
24
+ async function readApiError(response) {
25
+ try {
26
+ const body = await response.json();
27
+ if (Array.isArray(body.errors)) {
28
+ const messages = body.errors.filter(
29
+ (error) => typeof error === "string" && error.length > 0
30
+ );
31
+ if (messages.length > 0) {
32
+ return messages.join(" ");
33
+ }
34
+ }
35
+ if (typeof body.detail === "string" && body.detail.length > 0) {
36
+ return body.detail;
37
+ }
38
+ if (typeof body.title === "string" && body.title.length > 0) {
39
+ return body.title;
40
+ }
41
+ return null;
42
+ } catch {
43
+ return null;
44
+ }
45
+ }
24
46
  async function apiRequest(endpoint, method = "GET") {
25
47
  if (!API_KEY) {
26
48
  throw new Authn8Error(
27
- "AUTHN8_API_KEY environment variable is not set. Please set it to your PAT token from the Authn8 dashboard."
49
+ "AUTHN8_API_KEY environment variable is not set. Set it to an MCP token from Settings > MCP Tokens in Authn8."
28
50
  );
29
51
  }
30
52
  const url = `${API_URL}${endpoint}`;
@@ -39,10 +61,16 @@ async function apiRequest(endpoint, method = "GET") {
39
61
  if (!response.ok) {
40
62
  if (response.status === 401) {
41
63
  throw new Authn8Error(
42
- "Token is invalid or expired. Please check your token in the Authn8 dashboard.",
64
+ "Token is invalid, expired or revoked. Check it under Settings > MCP Tokens in Authn8.",
43
65
  401
44
66
  );
45
67
  }
68
+ if (response.status !== 429) {
69
+ const apiMessage = await readApiError(response);
70
+ if (apiMessage) {
71
+ throw new Authn8Error(apiMessage, response.status);
72
+ }
73
+ }
46
74
  if (response.status === 403) {
47
75
  throw new Authn8Error(
48
76
  "Token does not have permission to access this resource.",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@authn8/mcp-server",
3
- "version": "1.1.1",
3
+ "version": "1.1.3",
4
4
  "description": "MCP server for Authn8 2FA code access",
5
5
  "mcpName": "io.github.authn8/mcp-server",
6
6
  "type": "module",