@aipermission/mcp 0.2.25 → 0.2.27

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.
package/README.md CHANGED
@@ -31,7 +31,7 @@ npx -y @aipermission/mcp init \
31
31
  --name aipermission
32
32
  ```
33
33
 
34
- The init command prompts for your AIPermission API token and writes the MCP client configuration for the selected provider.
34
+ The init command prompts for your AIPermission API token and writes the MCP client configuration for the selected provider. Generated runtime configs pin the exact package version that wrote them; re-run init when you intentionally upgrade a client.
35
35
 
36
36
  The generated MCP config contains a bearer token. Keep it private. For project-local configs such as `.mcp.json`, `.cursor/mcp.json`, and `.vscode/mcp.json`, the init command refuses to write into files already tracked by Git unless `--force` is passed. For untracked project-local configs, it adds the file to `.git/info/exclude` when it detects a Git repository. Use `--print` if you prefer to copy the config manually. If a token config is committed or shared, revoke that token in the AIPermission UI.
37
37
 
@@ -42,7 +42,7 @@ The generated MCP config contains a bearer token. Keep it private. For project-l
42
42
  "mcpServers": {
43
43
  "aipermission": {
44
44
  "command": "npx",
45
- "args": ["-y", "@aipermission/mcp"],
45
+ "args": ["-y", "@aipermission/mcp@0.2.27"],
46
46
  "env": {
47
47
  "NODE_ENV": "production",
48
48
  "AIPERMISSION_API_URL": "http://localhost:3210",
package/dist/init.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import fs from "node:fs/promises";
2
+ import { createRequire } from "node:module";
2
3
  import os from "node:os";
3
4
  import path from "node:path";
4
5
  import readline from "node:readline/promises";
@@ -6,7 +7,12 @@ import { pathToFileURL } from "node:url";
6
7
  import { stdin as input, stdout as output } from "node:process";
7
8
  import { DEFAULT_API_URL, normalizeLocalAPIURL } from "./local-url.js";
8
9
 
9
- const PACKAGE_NAME = "@aipermission/mcp";
10
+ const require = createRequire(import.meta.url);
11
+ const packageMetadata = require("../package.json");
12
+
13
+ export const PACKAGE_NAME = packageMetadata.name;
14
+ export const PACKAGE_VERSION = packageMetadata.version;
15
+ export const PACKAGE_SPECIFIER = `${PACKAGE_NAME}@${PACKAGE_VERSION}`;
10
16
  const useColor = output.isTTY && !process.env.NO_COLOR;
11
17
  const color = {
12
18
  reset: useColor ? "\x1b[0m" : "",
@@ -287,7 +293,7 @@ async function readStdin() {
287
293
  export function buildMCPServerConfig({ apiUrl, token }) {
288
294
  return {
289
295
  command: "npx",
290
- args: ["-y", PACKAGE_NAME],
296
+ args: ["-y", PACKAGE_SPECIFIER],
291
297
  env: {
292
298
  NODE_ENV: "production",
293
299
  AIPERMISSION_API_URL: apiUrl,
@@ -25,7 +25,7 @@ Before acting:
25
25
  2. Pick the relevant `target_ref`.
26
26
  3. Call `get_connector_help(target_ref)` the first time you use that connector.
27
27
  4. Call `get_connector_actions(target_ref)` and choose the narrowest action.
28
- 5. Call `call_connector_action(target_ref, action_name, input, reason)`.
28
+ 5. Call `call_connector_action(target_ref, action_name, input, reason, idempotency_key)`.
29
29
 
30
30
  If no target is visible, say that the current token has no accessible connector
31
31
  targets. A target can be absent because its project is disabled for the token or
@@ -41,6 +41,11 @@ profile. Treat action errors as the current reachability/authorization signal.
41
41
  ## Reasons
42
42
 
43
43
  Every `call_connector_action` should include a short `reason`.
44
+ Use one stable, unique `idempotency_key` for each logical action. Preserve that
45
+ key while retrying an uncertain call. Never reuse it for a different target,
46
+ action, input, or reason; the gateway rejects mismatched reuse.
47
+ Blocked and missing-permission outcomes are also replayed. After the operator
48
+ changes permission, use a new key for the new logical attempt.
44
49
 
45
50
  Good reasons:
46
51
 
package/dist/server.js CHANGED
@@ -69,13 +69,15 @@ server.tool(
69
69
  action_name: z.string().min(1).describe("Action name from get_connector_actions."),
70
70
  input: z.record(z.unknown()).optional().describe("Connector-specific action input."),
71
71
  reason: z.string().optional().describe("Why this connector action is needed."),
72
+ idempotency_key: z.string().min(1).max(128).optional().describe("Caller-stable key that makes retries return the original request without running twice."),
72
73
  },
73
- async ({ target_ref, action_name, input, reason }) => {
74
+ async ({ target_ref, action_name, input, reason, idempotency_key }) => {
74
75
  return jsonToolResult(() => apiPost("/api/mcp/connector-actions/call", {
75
76
  target_ref,
76
77
  action_name,
77
78
  input: input || {},
78
79
  reason: reason || "",
80
+ idempotency_key,
79
81
  }));
80
82
  }
81
83
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aipermission/mcp",
3
- "version": "0.2.25",
3
+ "version": "0.2.27",
4
4
  "mcpName": "io.github.aipermission/aipermission-mcp",
5
5
  "description": "Local-first MCP bridge for the aipermission gateway.",
6
6
  "license": "AGPL-3.0-only",
package/server.json CHANGED
@@ -3,12 +3,12 @@
3
3
  "name": "io.github.aipermission/aipermission-mcp",
4
4
  "title": "AIPermission",
5
5
  "description": "Local-first MCP bridge for the AIPermission gateway.",
6
- "version": "0.2.25",
6
+ "version": "0.2.27",
7
7
  "packages": [
8
8
  {
9
9
  "registryType": "npm",
10
10
  "identifier": "@aipermission/mcp",
11
- "version": "0.2.25",
11
+ "version": "0.2.27",
12
12
  "transport": {
13
13
  "type": "stdio"
14
14
  }