@thantos66/claude-context-mcp 0.1.1 → 0.3.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/README.md +12 -1
- package/dist/index.js +12 -1
- package/dist/index.js.map +1 -1
- package/dist/proxy.d.ts +5 -0
- package/dist/proxy.js +208 -0
- package/dist/proxy.js.map +1 -0
- package/dist/services/agents.d.ts +7 -1
- package/dist/services/agents.js +6 -4
- package/dist/services/agents.js.map +1 -1
- package/dist/services/hooks.d.ts +29 -0
- package/dist/services/hooks.js +68 -0
- package/dist/services/hooks.js.map +1 -0
- package/dist/services/mcp-config.d.ts +6 -0
- package/dist/services/mcp-config.js +10 -9
- package/dist/services/mcp-config.js.map +1 -1
- package/dist/services/paths.d.ts +12 -4
- package/dist/services/paths.js +8 -8
- package/dist/services/paths.js.map +1 -1
- package/dist/services/permissions.d.ts +9 -1
- package/dist/services/permissions.js +9 -9
- package/dist/services/permissions.js.map +1 -1
- package/dist/services/skills.d.ts +8 -1
- package/dist/services/skills.js +7 -4
- package/dist/services/skills.js.map +1 -1
- package/dist/tools/agents.js +53 -1
- package/dist/tools/agents.js.map +1 -1
- package/dist/tools/export.d.ts +2 -0
- package/dist/tools/export.js +64 -0
- package/dist/tools/export.js.map +1 -0
- package/dist/tools/hooks.d.ts +2 -0
- package/dist/tools/hooks.js +51 -0
- package/dist/tools/hooks.js.map +1 -0
- package/dist/tools/mcp.js +168 -2
- package/dist/tools/mcp.js.map +1 -1
- package/dist/tools/meta.js +416 -2
- package/dist/tools/meta.js.map +1 -1
- package/dist/tools/permissions.js +8 -1
- package/dist/tools/permissions.js.map +1 -1
- package/dist/tools/skills.js +51 -1
- package/dist/tools/skills.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -141,6 +141,16 @@ For a manual end-to-end walk through every tool, use the official inspector:
|
|
|
141
141
|
npx @modelcontextprotocol/inspector node dist/index.js
|
|
142
142
|
```
|
|
143
143
|
|
|
144
|
+
## Config File Patterns
|
|
145
|
+
|
|
146
|
+
**Important:** Only `.mcp.json` is recognized as an MCP config file. Files like `.mcp.json.template` should NOT be placed where Claude Code scans for config, as they may be loaded as actual configuration and cause schema errors.
|
|
147
|
+
|
|
148
|
+
**Recommended pattern for secrets management:**
|
|
149
|
+
1. Commit `.mcp.json.template` with `${VAR_NAME}` placeholders
|
|
150
|
+
2. Create `.env` with actual secrets (gitignored, chmod 600)
|
|
151
|
+
3. Use `meta_apply_template` tool to generate `.mcp.json` from template + secrets
|
|
152
|
+
4. Gitignore `.mcp.json` (generated, contains secrets)
|
|
153
|
+
|
|
144
154
|
## Layout
|
|
145
155
|
|
|
146
156
|
```
|
|
@@ -166,6 +176,7 @@ src/
|
|
|
166
176
|
├── permissions.ts
|
|
167
177
|
├── agents.ts
|
|
168
178
|
├── skills.ts
|
|
169
|
-
|
|
179
|
+
├── meta.ts
|
|
180
|
+
└── export.ts
|
|
170
181
|
tests/ # vitest; each test runs in a spoofed $HOME
|
|
171
182
|
```
|
package/dist/index.js
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* - Tool permissions (allow / deny / ask + defaultMode)
|
|
8
8
|
* - Subagents (.claude/agents/*.md, user + project)
|
|
9
9
|
* - Skills (.claude/skills/<name>/SKILL.md, user + project)
|
|
10
|
+
* - Hooks (settings.json hooks entries)
|
|
10
11
|
*
|
|
11
12
|
* Transport: stdio. Follows mcp-builder skill conventions:
|
|
12
13
|
* - registerTool() modern API
|
|
@@ -21,16 +22,26 @@ import { registerPermissionsTools } from "./tools/permissions.js";
|
|
|
21
22
|
import { registerAgentTools } from "./tools/agents.js";
|
|
22
23
|
import { registerSkillTools } from "./tools/skills.js";
|
|
23
24
|
import { registerMetaTools } from "./tools/meta.js";
|
|
25
|
+
import { registerHookTools } from "./tools/hooks.js";
|
|
26
|
+
import { registerExportTools } from "./tools/export.js";
|
|
27
|
+
import { runProxy } from "./proxy.js";
|
|
24
28
|
async function main() {
|
|
29
|
+
// Subcommand: proxy mode — sanitize tool schemas from an external MCP server
|
|
30
|
+
if (process.argv[2] === "proxy") {
|
|
31
|
+
runProxy(process.argv.slice(3));
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
25
34
|
const server = new McpServer({
|
|
26
35
|
name: "claude-context-mcp",
|
|
27
|
-
version: "0.
|
|
36
|
+
version: "0.3.0",
|
|
28
37
|
});
|
|
29
38
|
registerMcpTools(server);
|
|
30
39
|
registerPermissionsTools(server);
|
|
31
40
|
registerAgentTools(server);
|
|
32
41
|
registerSkillTools(server);
|
|
33
42
|
registerMetaTools(server);
|
|
43
|
+
registerHookTools(server);
|
|
44
|
+
registerExportTools(server);
|
|
34
45
|
const transport = new StdioServerTransport();
|
|
35
46
|
await server.connect(transport);
|
|
36
47
|
// NOTE: we intentionally don't log anything to stdout — it's reserved for
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,KAAK,UAAU,IAAI;IACjB,6EAA6E;IAC7E,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,OAAO,EAAE,CAAC;QAChC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAChC,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,oBAAoB;QAC1B,OAAO,EAAE,OAAO;KACjB,CAAC,CAAC;IAEH,gBAAgB,CAAC,MAAM,CAAC,CAAC;IACzB,wBAAwB,CAAC,MAAM,CAAC,CAAC;IACjC,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAC3B,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAC3B,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAC1B,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAC1B,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAE5B,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAEhC,0EAA0E;IAC1E,sDAAsD;IACtD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC;AAChE,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,+BAAgC,GAAa,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC,CAAC;IACrF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
package/dist/proxy.d.ts
ADDED
package/dist/proxy.js
ADDED
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schema-sanitizing MCP stdio proxy.
|
|
3
|
+
*
|
|
4
|
+
* Sits between Claude Code and any MCP server. Transparently passes all
|
|
5
|
+
* JSON-RPC messages, but intercepts `tools/list` responses and flattens
|
|
6
|
+
* `oneOf`, `anyOf`, and `allOf` in tool input schemas — which the Claude
|
|
7
|
+
* API rejects.
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* node dist/index.js proxy <command> [args...]
|
|
11
|
+
* npx @thantos66/claude-context-mcp proxy npx -y @stripe/mcp
|
|
12
|
+
*
|
|
13
|
+
* Security: The proxy never touches secrets or data payloads — only schema
|
|
14
|
+
* metadata in tools/list responses. The child process inherits env as-is.
|
|
15
|
+
*/
|
|
16
|
+
import { spawn } from "node:child_process";
|
|
17
|
+
import { createInterface } from "node:readline";
|
|
18
|
+
// ── Schema sanitization ─────────────────────────────────────────────
|
|
19
|
+
/**
|
|
20
|
+
* Recursively walk a JSON Schema node and flatten any oneOf/anyOf/allOf
|
|
21
|
+
* by merging all branch properties into a single object schema.
|
|
22
|
+
*/
|
|
23
|
+
function sanitizeSchema(schema) {
|
|
24
|
+
if (schema === null || typeof schema !== "object" || Array.isArray(schema)) {
|
|
25
|
+
return schema;
|
|
26
|
+
}
|
|
27
|
+
const result = { ...schema };
|
|
28
|
+
// Handle top-level or nested oneOf/anyOf/allOf
|
|
29
|
+
for (const keyword of ["oneOf", "anyOf", "allOf"]) {
|
|
30
|
+
if (Array.isArray(result[keyword])) {
|
|
31
|
+
const branches = result[keyword];
|
|
32
|
+
const merged = mergeBranches(branches);
|
|
33
|
+
// Remove the keyword and merge the result
|
|
34
|
+
delete result[keyword];
|
|
35
|
+
Object.assign(result, merged);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
// Ensure we have type: "object" if we have properties
|
|
39
|
+
if (result.properties && !result.type) {
|
|
40
|
+
result.type = "object";
|
|
41
|
+
}
|
|
42
|
+
// Recurse into properties
|
|
43
|
+
if (result.properties && typeof result.properties === "object") {
|
|
44
|
+
const props = result.properties;
|
|
45
|
+
const sanitized = {};
|
|
46
|
+
for (const [key, value] of Object.entries(props)) {
|
|
47
|
+
sanitized[key] =
|
|
48
|
+
value && typeof value === "object" && !Array.isArray(value)
|
|
49
|
+
? sanitizeSchema(value)
|
|
50
|
+
: value;
|
|
51
|
+
}
|
|
52
|
+
result.properties = sanitized;
|
|
53
|
+
}
|
|
54
|
+
// Recurse into items (array schemas)
|
|
55
|
+
if (result.items && typeof result.items === "object" && !Array.isArray(result.items)) {
|
|
56
|
+
result.items = sanitizeSchema(result.items);
|
|
57
|
+
}
|
|
58
|
+
// Recurse into additionalProperties if it's a schema
|
|
59
|
+
if (result.additionalProperties &&
|
|
60
|
+
typeof result.additionalProperties === "object" &&
|
|
61
|
+
!Array.isArray(result.additionalProperties)) {
|
|
62
|
+
result.additionalProperties = sanitizeSchema(result.additionalProperties);
|
|
63
|
+
}
|
|
64
|
+
return result;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Merge multiple JSON Schema branch objects into a single flat object schema.
|
|
68
|
+
* Properties from all branches are collected; required arrays are unioned.
|
|
69
|
+
*/
|
|
70
|
+
function mergeBranches(branches) {
|
|
71
|
+
const mergedProps = {};
|
|
72
|
+
const mergedRequired = new Set();
|
|
73
|
+
let hasProperties = false;
|
|
74
|
+
for (const branch of branches) {
|
|
75
|
+
if (branch === null || typeof branch !== "object")
|
|
76
|
+
continue;
|
|
77
|
+
// Recursively sanitize each branch first
|
|
78
|
+
const clean = sanitizeSchema(branch);
|
|
79
|
+
if (clean.properties && typeof clean.properties === "object") {
|
|
80
|
+
hasProperties = true;
|
|
81
|
+
const props = clean.properties;
|
|
82
|
+
for (const [key, value] of Object.entries(props)) {
|
|
83
|
+
// First branch wins for conflicting property definitions
|
|
84
|
+
if (!(key in mergedProps)) {
|
|
85
|
+
mergedProps[key] = value;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
if (Array.isArray(clean.required)) {
|
|
90
|
+
for (const r of clean.required) {
|
|
91
|
+
if (typeof r === "string")
|
|
92
|
+
mergedRequired.add(r);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
const result = { type: "object" };
|
|
97
|
+
if (hasProperties) {
|
|
98
|
+
result.properties = mergedProps;
|
|
99
|
+
}
|
|
100
|
+
// Only include required fields that actually exist in merged properties
|
|
101
|
+
const validRequired = [...mergedRequired].filter((r) => r in mergedProps);
|
|
102
|
+
if (validRequired.length > 0) {
|
|
103
|
+
result.required = validRequired;
|
|
104
|
+
}
|
|
105
|
+
return result;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Check if a schema (or any nested part) contains oneOf/anyOf/allOf.
|
|
109
|
+
*/
|
|
110
|
+
export function schemaHasUnion(schema) {
|
|
111
|
+
if (schema === null || typeof schema !== "object" || Array.isArray(schema)) {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
const obj = schema;
|
|
115
|
+
if (obj.oneOf || obj.anyOf || obj.allOf)
|
|
116
|
+
return true;
|
|
117
|
+
// Check nested properties
|
|
118
|
+
if (obj.properties && typeof obj.properties === "object") {
|
|
119
|
+
for (const value of Object.values(obj.properties)) {
|
|
120
|
+
if (schemaHasUnion(value))
|
|
121
|
+
return true;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
if (obj.items && typeof obj.items === "object") {
|
|
125
|
+
if (schemaHasUnion(obj.items))
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
128
|
+
if (obj.additionalProperties && typeof obj.additionalProperties === "object") {
|
|
129
|
+
if (schemaHasUnion(obj.additionalProperties))
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
// ── JSON-RPC message processing ─────────────────────────────────────
|
|
135
|
+
/**
|
|
136
|
+
* Process a JSON-RPC response. If it's a tools/list result, sanitize
|
|
137
|
+
* tool input schemas. Returns the (possibly modified) message string.
|
|
138
|
+
*/
|
|
139
|
+
function processMessage(line) {
|
|
140
|
+
let msg;
|
|
141
|
+
try {
|
|
142
|
+
msg = JSON.parse(line);
|
|
143
|
+
}
|
|
144
|
+
catch {
|
|
145
|
+
return line; // Not JSON — pass through
|
|
146
|
+
}
|
|
147
|
+
// Only process JSON-RPC responses that have a result with tools array
|
|
148
|
+
if (!msg.result || typeof msg.result !== "object")
|
|
149
|
+
return line;
|
|
150
|
+
const result = msg.result;
|
|
151
|
+
if (!Array.isArray(result.tools))
|
|
152
|
+
return line;
|
|
153
|
+
// This is a tools/list response — sanitize each tool's inputSchema
|
|
154
|
+
const tools = result.tools;
|
|
155
|
+
const patched = [];
|
|
156
|
+
for (const tool of tools) {
|
|
157
|
+
if (!tool.inputSchema || typeof tool.inputSchema !== "object")
|
|
158
|
+
continue;
|
|
159
|
+
const schema = tool.inputSchema;
|
|
160
|
+
if (schemaHasUnion(schema)) {
|
|
161
|
+
const name = tool.name || "(unknown)";
|
|
162
|
+
tool.inputSchema = sanitizeSchema(schema);
|
|
163
|
+
patched.push(name);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
if (patched.length > 0) {
|
|
167
|
+
process.stderr.write(`[claude-context-mcp proxy] sanitized ${patched.length} tool schema(s): ${patched.join(", ")}\n`);
|
|
168
|
+
}
|
|
169
|
+
return JSON.stringify(msg);
|
|
170
|
+
}
|
|
171
|
+
// ── Main proxy logic ────────────────────────────────────────────────
|
|
172
|
+
export function runProxy(childArgs) {
|
|
173
|
+
if (childArgs.length === 0) {
|
|
174
|
+
process.stderr.write("[claude-context-mcp proxy] error: no command specified\n" +
|
|
175
|
+
"Usage: claude-context-mcp proxy <command> [args...]\n");
|
|
176
|
+
process.exit(1);
|
|
177
|
+
}
|
|
178
|
+
const [command, ...args] = childArgs;
|
|
179
|
+
const child = spawn(command, args, {
|
|
180
|
+
stdio: ["pipe", "pipe", "inherit"], // stdin: pipe, stdout: pipe, stderr: inherit
|
|
181
|
+
env: process.env,
|
|
182
|
+
});
|
|
183
|
+
child.on("error", (err) => {
|
|
184
|
+
process.stderr.write(`[claude-context-mcp proxy] failed to spawn "${command}": ${err.message}\n`);
|
|
185
|
+
process.exit(1);
|
|
186
|
+
});
|
|
187
|
+
child.on("exit", (code, signal) => {
|
|
188
|
+
if (signal) {
|
|
189
|
+
process.stderr.write(`[claude-context-mcp proxy] child killed by signal ${signal}\n`);
|
|
190
|
+
process.exit(1);
|
|
191
|
+
}
|
|
192
|
+
process.exit(code ?? 0);
|
|
193
|
+
});
|
|
194
|
+
// stdin → child stdin (pass through, no processing needed)
|
|
195
|
+
process.stdin.pipe(child.stdin);
|
|
196
|
+
// child stdout → process stdout (intercept and sanitize)
|
|
197
|
+
const rl = createInterface({ input: child.stdout, crlfDelay: Infinity });
|
|
198
|
+
rl.on("line", (line) => {
|
|
199
|
+
const processed = processMessage(line);
|
|
200
|
+
process.stdout.write(processed + "\n");
|
|
201
|
+
});
|
|
202
|
+
// Handle parent stdin closing
|
|
203
|
+
process.stdin.on("end", () => {
|
|
204
|
+
child.stdin.end();
|
|
205
|
+
});
|
|
206
|
+
process.stderr.write(`[claude-context-mcp proxy] proxying: ${command} ${args.join(" ")}\n`);
|
|
207
|
+
}
|
|
208
|
+
//# sourceMappingURL=proxy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy.js","sourceRoot":"","sources":["../src/proxy.ts"],"names":[],"mappings":"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"}
|
|
@@ -13,12 +13,15 @@ export interface AgentWriteResult {
|
|
|
13
13
|
preview?: string;
|
|
14
14
|
}
|
|
15
15
|
/** List all agent markdown files in a scope. */
|
|
16
|
-
export declare function listAgents(scope: "user" | "project", projectPath?: string
|
|
16
|
+
export declare function listAgents(scope: "user" | "project", projectPath?: string, opts?: {
|
|
17
|
+
allowOutsideHome?: boolean;
|
|
18
|
+
}): Promise<AgentRecord[]>;
|
|
17
19
|
/** Read one agent file (by agent name, not file name). */
|
|
18
20
|
export declare function getAgent(params: {
|
|
19
21
|
scope: "user" | "project";
|
|
20
22
|
name: string;
|
|
21
23
|
projectPath?: string;
|
|
24
|
+
allowOutsideHome?: boolean;
|
|
22
25
|
}): Promise<AgentRecord | null>;
|
|
23
26
|
/** Serialize an agent record back to the on-disk SKILL.md format. */
|
|
24
27
|
export declare function serializeAgent(frontmatter: AgentFrontmatter, body: string): string;
|
|
@@ -34,6 +37,7 @@ export declare function createAgent(params: {
|
|
|
34
37
|
projectPath?: string;
|
|
35
38
|
overwrite?: boolean;
|
|
36
39
|
dryRun?: boolean;
|
|
40
|
+
allowOutsideHome?: boolean;
|
|
37
41
|
}): Promise<AgentWriteResult>;
|
|
38
42
|
/** Patch frontmatter fields and/or replace the body of an existing agent. */
|
|
39
43
|
export declare function updateAgent(params: {
|
|
@@ -46,6 +50,7 @@ export declare function updateAgent(params: {
|
|
|
46
50
|
body?: string;
|
|
47
51
|
projectPath?: string;
|
|
48
52
|
dryRun?: boolean;
|
|
53
|
+
allowOutsideHome?: boolean;
|
|
49
54
|
}): Promise<AgentWriteResult>;
|
|
50
55
|
/** Delete an agent file. */
|
|
51
56
|
export declare function deleteAgent(params: {
|
|
@@ -53,4 +58,5 @@ export declare function deleteAgent(params: {
|
|
|
53
58
|
name: string;
|
|
54
59
|
projectPath?: string;
|
|
55
60
|
dryRun?: boolean;
|
|
61
|
+
allowOutsideHome?: boolean;
|
|
56
62
|
}): Promise<AgentWriteResult>;
|
package/dist/services/agents.js
CHANGED
|
@@ -6,8 +6,8 @@ import { atomicWriteFile } from "./atomic-write.js";
|
|
|
6
6
|
import { backupFile } from "./backup.js";
|
|
7
7
|
import { agentsDirFor } from "./paths.js";
|
|
8
8
|
/** List all agent markdown files in a scope. */
|
|
9
|
-
export async function listAgents(scope, projectPath) {
|
|
10
|
-
const dir = agentsDirFor(scope, projectPath);
|
|
9
|
+
export async function listAgents(scope, projectPath, opts) {
|
|
10
|
+
const dir = agentsDirFor(scope, projectPath, { allowOutsideHome: opts?.allowOutsideHome });
|
|
11
11
|
let names;
|
|
12
12
|
try {
|
|
13
13
|
names = await fs.readdir(dir);
|
|
@@ -35,7 +35,7 @@ export async function listAgents(scope, projectPath) {
|
|
|
35
35
|
}
|
|
36
36
|
/** Read one agent file (by agent name, not file name). */
|
|
37
37
|
export async function getAgent(params) {
|
|
38
|
-
const dir = agentsDirFor(params.scope, params.projectPath);
|
|
38
|
+
const dir = agentsDirFor(params.scope, params.projectPath, { allowOutsideHome: params.allowOutsideHome });
|
|
39
39
|
const filePath = path.join(dir, `${params.name}.md`);
|
|
40
40
|
try {
|
|
41
41
|
return await readAgentFile(params.scope, filePath);
|
|
@@ -90,7 +90,7 @@ export async function createAgent(params) {
|
|
|
90
90
|
color: params.color,
|
|
91
91
|
});
|
|
92
92
|
const body = params.body ?? "";
|
|
93
|
-
const dir = agentsDirFor(params.scope, params.projectPath);
|
|
93
|
+
const dir = agentsDirFor(params.scope, params.projectPath, { allowOutsideHome: params.allowOutsideHome });
|
|
94
94
|
const filePath = path.join(dir, `${frontmatter.name}.md`);
|
|
95
95
|
if (!params.overwrite) {
|
|
96
96
|
try {
|
|
@@ -117,6 +117,7 @@ export async function updateAgent(params) {
|
|
|
117
117
|
scope: params.scope,
|
|
118
118
|
name: params.name,
|
|
119
119
|
projectPath: params.projectPath,
|
|
120
|
+
allowOutsideHome: params.allowOutsideHome,
|
|
120
121
|
});
|
|
121
122
|
if (!current)
|
|
122
123
|
throw new Error(`Agent "${params.name}" not found in scope ${params.scope}.`);
|
|
@@ -142,6 +143,7 @@ export async function deleteAgent(params) {
|
|
|
142
143
|
scope: params.scope,
|
|
143
144
|
name: params.name,
|
|
144
145
|
projectPath: params.projectPath,
|
|
146
|
+
allowOutsideHome: params.allowOutsideHome,
|
|
145
147
|
});
|
|
146
148
|
if (!current)
|
|
147
149
|
throw new Error(`Agent "${params.name}" not found in scope ${params.scope}.`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agents.js","sourceRoot":"","sources":["../../src/services/agents.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EACL,sBAAsB,EAEtB,cAAc,GACf,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAiB1C,gDAAgD;AAChD,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,KAAyB,EACzB,WAAoB;
|
|
1
|
+
{"version":3,"file":"agents.js","sourceRoot":"","sources":["../../src/services/agents.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { WriteResult } from "./mcp-config.js";
|
|
2
|
+
export declare function listHooks(scope: "user" | "project", projectPath?: string, _opts?: {
|
|
3
|
+
allowOutsideHome?: boolean;
|
|
4
|
+
}): Promise<{
|
|
5
|
+
path: string;
|
|
6
|
+
hooks: Record<string, unknown>;
|
|
7
|
+
}>;
|
|
8
|
+
export declare function addHook(params: {
|
|
9
|
+
scope: "user" | "project";
|
|
10
|
+
event: string;
|
|
11
|
+
matcher?: string;
|
|
12
|
+
type?: string;
|
|
13
|
+
command: string;
|
|
14
|
+
timeout?: number;
|
|
15
|
+
projectPath?: string;
|
|
16
|
+
allowOutsideHome?: boolean;
|
|
17
|
+
dryRun?: boolean;
|
|
18
|
+
}): Promise<WriteResult>;
|
|
19
|
+
export declare function removeHook(params: {
|
|
20
|
+
scope: "user" | "project";
|
|
21
|
+
event: string;
|
|
22
|
+
index: number;
|
|
23
|
+
hookIndex?: number;
|
|
24
|
+
projectPath?: string;
|
|
25
|
+
allowOutsideHome?: boolean;
|
|
26
|
+
dryRun?: boolean;
|
|
27
|
+
}): Promise<WriteResult & {
|
|
28
|
+
removed: boolean;
|
|
29
|
+
}>;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { settingsPathFor } from "./paths.js";
|
|
2
|
+
import { loadSettings } from "./permissions.js";
|
|
3
|
+
import { atomicWriteFile, stringifyJson } from "./atomic-write.js";
|
|
4
|
+
import { backupFile } from "./backup.js";
|
|
5
|
+
export async function listHooks(scope, projectPath, _opts) {
|
|
6
|
+
const path = settingsPathFor(scope, projectPath);
|
|
7
|
+
const settings = await loadSettings(path);
|
|
8
|
+
return { path, hooks: settings.hooks ?? {} };
|
|
9
|
+
}
|
|
10
|
+
export async function addHook(params) {
|
|
11
|
+
const path = settingsPathFor(params.scope, params.projectPath);
|
|
12
|
+
const settings = await loadSettings(path);
|
|
13
|
+
const raw = settings;
|
|
14
|
+
const hooks = (raw.hooks ?? {});
|
|
15
|
+
const eventHooks = (hooks[params.event] ?? []);
|
|
16
|
+
const hookEntry = { type: params.type ?? "command", command: params.command };
|
|
17
|
+
if (params.timeout !== undefined)
|
|
18
|
+
hookEntry.timeout = params.timeout;
|
|
19
|
+
const matcherStr = params.matcher ?? "";
|
|
20
|
+
// Find existing matcher group or create new one
|
|
21
|
+
let group = eventHooks.find((g) => (g.matcher ?? "") === matcherStr);
|
|
22
|
+
if (!group) {
|
|
23
|
+
group = { matcher: matcherStr, hooks: [] };
|
|
24
|
+
eventHooks.push(group);
|
|
25
|
+
}
|
|
26
|
+
const groupHooks = (group.hooks ?? []);
|
|
27
|
+
groupHooks.push(hookEntry);
|
|
28
|
+
group.hooks = groupHooks;
|
|
29
|
+
hooks[params.event] = eventHooks;
|
|
30
|
+
raw.hooks = hooks;
|
|
31
|
+
if (params.dryRun) {
|
|
32
|
+
return { path, backup: null, dryRun: true, diff: JSON.stringify(raw, null, 2) };
|
|
33
|
+
}
|
|
34
|
+
const backup = await backupFile(path);
|
|
35
|
+
await atomicWriteFile(path, stringifyJson(raw));
|
|
36
|
+
return { path, backup, dryRun: false };
|
|
37
|
+
}
|
|
38
|
+
export async function removeHook(params) {
|
|
39
|
+
const path = settingsPathFor(params.scope, params.projectPath);
|
|
40
|
+
const settings = await loadSettings(path);
|
|
41
|
+
const raw = settings;
|
|
42
|
+
const hooks = (raw.hooks ?? {});
|
|
43
|
+
const eventHooks = (hooks[params.event] ?? []);
|
|
44
|
+
if (params.index < 0 || params.index >= eventHooks.length) {
|
|
45
|
+
return { path, backup: null, dryRun: params.dryRun ?? false, removed: false };
|
|
46
|
+
}
|
|
47
|
+
if (params.hookIndex !== undefined) {
|
|
48
|
+
const group = eventHooks[params.index];
|
|
49
|
+
const groupHooks = (group.hooks ?? []);
|
|
50
|
+
if (params.hookIndex < 0 || params.hookIndex >= groupHooks.length) {
|
|
51
|
+
return { path, backup: null, dryRun: params.dryRun ?? false, removed: false };
|
|
52
|
+
}
|
|
53
|
+
groupHooks.splice(params.hookIndex, 1);
|
|
54
|
+
group.hooks = groupHooks;
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
eventHooks.splice(params.index, 1);
|
|
58
|
+
}
|
|
59
|
+
hooks[params.event] = eventHooks;
|
|
60
|
+
raw.hooks = hooks;
|
|
61
|
+
if (params.dryRun) {
|
|
62
|
+
return { path, backup: null, dryRun: true, removed: true, diff: JSON.stringify(raw, null, 2) };
|
|
63
|
+
}
|
|
64
|
+
const backup = await backupFile(path);
|
|
65
|
+
await atomicWriteFile(path, stringifyJson(raw));
|
|
66
|
+
return { path, backup, dryRun: false, removed: true };
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=hooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../src/services/hooks.ts"],"names":[],"mappings":"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"}
|
|
@@ -25,6 +25,7 @@ export interface ListEntry {
|
|
|
25
25
|
export declare function listServers(scope: Scope, opts?: {
|
|
26
26
|
projectPath?: string;
|
|
27
27
|
revealSecrets?: boolean;
|
|
28
|
+
allowOutsideHome?: boolean;
|
|
28
29
|
}): Promise<ListEntry[]>;
|
|
29
30
|
/** Add or replace a server entry in a scope. */
|
|
30
31
|
export declare function addServer(params: {
|
|
@@ -34,6 +35,7 @@ export declare function addServer(params: {
|
|
|
34
35
|
projectPath?: string;
|
|
35
36
|
dryRun?: boolean;
|
|
36
37
|
overwrite?: boolean;
|
|
38
|
+
allowOutsideHome?: boolean;
|
|
37
39
|
}): Promise<WriteResult>;
|
|
38
40
|
/** Patch individual fields of an existing server entry. */
|
|
39
41
|
export declare function updateServer(params: {
|
|
@@ -42,6 +44,7 @@ export declare function updateServer(params: {
|
|
|
42
44
|
patch: Partial<McpServerEntry>;
|
|
43
45
|
projectPath?: string;
|
|
44
46
|
dryRun?: boolean;
|
|
47
|
+
allowOutsideHome?: boolean;
|
|
45
48
|
}): Promise<WriteResult>;
|
|
46
49
|
/** Remove a server by name. */
|
|
47
50
|
export declare function removeServer(params: {
|
|
@@ -49,6 +52,7 @@ export declare function removeServer(params: {
|
|
|
49
52
|
name: string;
|
|
50
53
|
projectPath?: string;
|
|
51
54
|
dryRun?: boolean;
|
|
55
|
+
allowOutsideHome?: boolean;
|
|
52
56
|
}): Promise<WriteResult>;
|
|
53
57
|
/** Toggle the `disabled` flag on an existing server entry. */
|
|
54
58
|
export declare function setServerDisabled(params: {
|
|
@@ -57,6 +61,7 @@ export declare function setServerDisabled(params: {
|
|
|
57
61
|
disabled: boolean;
|
|
58
62
|
projectPath?: string;
|
|
59
63
|
dryRun?: boolean;
|
|
64
|
+
allowOutsideHome?: boolean;
|
|
60
65
|
}): Promise<WriteResult>;
|
|
61
66
|
/** Get a single server entry. */
|
|
62
67
|
export declare function getServer(params: {
|
|
@@ -64,6 +69,7 @@ export declare function getServer(params: {
|
|
|
64
69
|
name: string;
|
|
65
70
|
projectPath?: string;
|
|
66
71
|
revealSecrets?: boolean;
|
|
72
|
+
allowOutsideHome?: boolean;
|
|
67
73
|
}): Promise<ListEntry | null>;
|
|
68
74
|
/**
|
|
69
75
|
* Minimal unified diff for dry-run output. Not a full diff engine — just
|
|
@@ -54,7 +54,7 @@ export async function saveMcpConfig(path, next, { dryRun = false } = {}) {
|
|
|
54
54
|
}
|
|
55
55
|
/** List servers across one scope. Redacts secrets by default. */
|
|
56
56
|
export async function listServers(scope, opts = {}) {
|
|
57
|
-
const path = mcpConfigPathFor(scope, opts.projectPath);
|
|
57
|
+
const path = mcpConfigPathFor(scope, opts.projectPath, { allowOutsideHome: opts.allowOutsideHome });
|
|
58
58
|
const cfg = await loadMcpConfig(path);
|
|
59
59
|
const entries = Object.entries(cfg.mcpServers ?? {});
|
|
60
60
|
return entries.map(([name, entry]) => ({
|
|
@@ -66,9 +66,9 @@ export async function listServers(scope, opts = {}) {
|
|
|
66
66
|
}
|
|
67
67
|
/** Add or replace a server entry in a scope. */
|
|
68
68
|
export async function addServer(params) {
|
|
69
|
-
const { scope, name, entry, projectPath, dryRun, overwrite } = params;
|
|
69
|
+
const { scope, name, entry, projectPath, dryRun, overwrite, allowOutsideHome } = params;
|
|
70
70
|
const validatedEntry = McpServerEntrySchema.parse(entry);
|
|
71
|
-
const path = mcpConfigPathFor(scope, projectPath);
|
|
71
|
+
const path = mcpConfigPathFor(scope, projectPath, { allowOutsideHome });
|
|
72
72
|
const cfg = await loadMcpConfig(path);
|
|
73
73
|
cfg.mcpServers ??= {};
|
|
74
74
|
if (!overwrite && cfg.mcpServers[name] !== undefined) {
|
|
@@ -79,8 +79,8 @@ export async function addServer(params) {
|
|
|
79
79
|
}
|
|
80
80
|
/** Patch individual fields of an existing server entry. */
|
|
81
81
|
export async function updateServer(params) {
|
|
82
|
-
const { scope, name, patch, projectPath, dryRun } = params;
|
|
83
|
-
const path = mcpConfigPathFor(scope, projectPath);
|
|
82
|
+
const { scope, name, patch, projectPath, dryRun, allowOutsideHome } = params;
|
|
83
|
+
const path = mcpConfigPathFor(scope, projectPath, { allowOutsideHome });
|
|
84
84
|
const cfg = await loadMcpConfig(path);
|
|
85
85
|
const current = cfg.mcpServers?.[name];
|
|
86
86
|
if (!current) {
|
|
@@ -92,8 +92,8 @@ export async function updateServer(params) {
|
|
|
92
92
|
}
|
|
93
93
|
/** Remove a server by name. */
|
|
94
94
|
export async function removeServer(params) {
|
|
95
|
-
const { scope, name, projectPath, dryRun } = params;
|
|
96
|
-
const path = mcpConfigPathFor(scope, projectPath);
|
|
95
|
+
const { scope, name, projectPath, dryRun, allowOutsideHome } = params;
|
|
96
|
+
const path = mcpConfigPathFor(scope, projectPath, { allowOutsideHome });
|
|
97
97
|
const cfg = await loadMcpConfig(path);
|
|
98
98
|
if (!cfg.mcpServers?.[name]) {
|
|
99
99
|
throw new Error(`MCP server "${name}" not found in ${path}.`);
|
|
@@ -109,12 +109,13 @@ export async function setServerDisabled(params) {
|
|
|
109
109
|
patch: { disabled: params.disabled },
|
|
110
110
|
projectPath: params.projectPath,
|
|
111
111
|
dryRun: params.dryRun,
|
|
112
|
+
allowOutsideHome: params.allowOutsideHome,
|
|
112
113
|
});
|
|
113
114
|
}
|
|
114
115
|
/** Get a single server entry. */
|
|
115
116
|
export async function getServer(params) {
|
|
116
|
-
const { scope, name, projectPath, revealSecrets } = params;
|
|
117
|
-
const path = mcpConfigPathFor(scope, projectPath);
|
|
117
|
+
const { scope, name, projectPath, revealSecrets, allowOutsideHome } = params;
|
|
118
|
+
const path = mcpConfigPathFor(scope, projectPath, { allowOutsideHome });
|
|
118
119
|
const cfg = await loadMcpConfig(path);
|
|
119
120
|
const entry = cfg.mcpServers?.[name];
|
|
120
121
|
if (!entry)
|