alnair-mcp 0.1.0
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/dist/server.d.ts +2 -0
- package/dist/server.js +109 -0
- package/package.json +42 -0
package/dist/server.d.ts
ADDED
package/dist/server.js
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Alnair MCP — visible grant path for Cursor / Claude tool UIs.
|
|
4
|
+
*
|
|
5
|
+
* Returns a one-line notice the chat will show:
|
|
6
|
+
* [alnair] GitHub access granted
|
|
7
|
+
*/
|
|
8
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
9
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
10
|
+
import { z } from "zod";
|
|
11
|
+
import { AlnairClient, displayPermission } from "alnair-sdk";
|
|
12
|
+
const server = new McpServer({
|
|
13
|
+
name: "alnair",
|
|
14
|
+
version: "0.1.0",
|
|
15
|
+
});
|
|
16
|
+
function grantLine(permissions) {
|
|
17
|
+
const groups = [...new Set(permissions.map((p) => displayPermission(p).group))];
|
|
18
|
+
const who = groups.length === 1 ? groups[0] : "Access";
|
|
19
|
+
return `[alnair] ${who} access granted`;
|
|
20
|
+
}
|
|
21
|
+
server.tool("requestAccess", `REQUIRED before git commit, git push, deploy, or DB writes in this project.
|
|
22
|
+
|
|
23
|
+
Call this first, then run the privileged command. The user will see the grant
|
|
24
|
+
in this tool result — that is intentional.
|
|
25
|
+
|
|
26
|
+
Map actions → permissions:
|
|
27
|
+
- git commit → ["github.git.commit"]
|
|
28
|
+
- git push → ["github.git.push"]
|
|
29
|
+
- merge PR → ["github.pull_request.merge"]
|
|
30
|
+
- deploy → ["vercel.deploy.preview"]
|
|
31
|
+
- DB write → ["supabase.write"]
|
|
32
|
+
|
|
33
|
+
task = real commit subject / mission. Only request what you need.`, {
|
|
34
|
+
task: z.string().describe("What you are about to do, e.g. the commit subject"),
|
|
35
|
+
permissions: z
|
|
36
|
+
.array(z.string())
|
|
37
|
+
.describe('e.g. ["github.git.push"] or ["github.git.commit"]'),
|
|
38
|
+
ttl: z.string().optional().describe('Lifetime, default "15m"'),
|
|
39
|
+
agent: z.string().optional(),
|
|
40
|
+
}, async ({ task, permissions, ttl, agent }) => {
|
|
41
|
+
try {
|
|
42
|
+
const client = await AlnairClient.fromProject(agent ? { agent } : {});
|
|
43
|
+
await client.mint({
|
|
44
|
+
task,
|
|
45
|
+
permissions,
|
|
46
|
+
ttl: ttl ?? "15m",
|
|
47
|
+
agent,
|
|
48
|
+
notify: false, // tool result is the notice
|
|
49
|
+
});
|
|
50
|
+
return {
|
|
51
|
+
content: [{ type: "text", text: grantLine(permissions) }],
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
56
|
+
return {
|
|
57
|
+
content: [
|
|
58
|
+
{
|
|
59
|
+
type: "text",
|
|
60
|
+
text: `[alnair] Could not grant access — ${reason}`,
|
|
61
|
+
},
|
|
62
|
+
],
|
|
63
|
+
isError: true,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
// Alias for older instructions / Claude CLAUDE.md still naming mintCapability
|
|
68
|
+
server.tool("mintCapability", `Alias of requestAccess. Prefer requestAccess.
|
|
69
|
+
|
|
70
|
+
REQUIRED before git commit/push/deploy/DB writes. Returns a one-line grant notice.`, {
|
|
71
|
+
task: z.string(),
|
|
72
|
+
permissions: z.array(z.string()),
|
|
73
|
+
ttl: z.string().optional(),
|
|
74
|
+
agent: z.string().optional(),
|
|
75
|
+
}, async ({ task, permissions, ttl, agent }) => {
|
|
76
|
+
try {
|
|
77
|
+
const client = await AlnairClient.fromProject(agent ? { agent } : {});
|
|
78
|
+
await client.mint({
|
|
79
|
+
task,
|
|
80
|
+
permissions,
|
|
81
|
+
ttl: ttl ?? "15m",
|
|
82
|
+
agent,
|
|
83
|
+
notify: false,
|
|
84
|
+
});
|
|
85
|
+
return {
|
|
86
|
+
content: [{ type: "text", text: grantLine(permissions) }],
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
catch (err) {
|
|
90
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
91
|
+
return {
|
|
92
|
+
content: [
|
|
93
|
+
{
|
|
94
|
+
type: "text",
|
|
95
|
+
text: `[alnair] Could not grant access — ${reason}`,
|
|
96
|
+
},
|
|
97
|
+
],
|
|
98
|
+
isError: true,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
async function main() {
|
|
103
|
+
const transport = new StdioServerTransport();
|
|
104
|
+
await server.connect(transport);
|
|
105
|
+
}
|
|
106
|
+
main().catch((err) => {
|
|
107
|
+
console.error(err);
|
|
108
|
+
process.exit(1);
|
|
109
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "alnair-mcp",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Alnair MCP server — requestAccess for Claude Code and Cursor",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"alnair-mcp": "./dist/server.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "tsc -p tsconfig.json",
|
|
14
|
+
"prepare": "npm run build"
|
|
15
|
+
},
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "git+https://github.com/CamiloJac/seren.git",
|
|
19
|
+
"directory": "packages/mcp"
|
|
20
|
+
},
|
|
21
|
+
"keywords": [
|
|
22
|
+
"alnair",
|
|
23
|
+
"mcp",
|
|
24
|
+
"model-context-protocol",
|
|
25
|
+
"ai",
|
|
26
|
+
"agents",
|
|
27
|
+
"permissions"
|
|
28
|
+
],
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
31
|
+
"alnair-sdk": "^0.1.0",
|
|
32
|
+
"zod": "^3.23.8"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@types/node": "^22.8.6",
|
|
36
|
+
"typescript": "^5.6.3"
|
|
37
|
+
},
|
|
38
|
+
"engines": {
|
|
39
|
+
"node": ">=18"
|
|
40
|
+
},
|
|
41
|
+
"license": "MIT"
|
|
42
|
+
}
|