@kya-os/mcp-i 1.5.1 → 1.5.3-canary.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/compiler/config/injection.d.ts +5 -1
- package/dist/compiler/config/injection.js +25 -0
- package/dist/compiler/get-webpack-config/get-injected-variables.js +2 -0
- package/dist/runtime/adapter-express.js +1 -1
- package/dist/runtime/adapter-nextjs.js +1 -1
- package/dist/runtime/auth-handshake.d.ts +2 -0
- package/dist/runtime/auth-handshake.js +2 -3
- package/dist/runtime/http.js +1 -1
- package/dist/runtime/index.d.ts +2 -0
- package/dist/runtime/index.js +13 -1
- package/dist/runtime/mcpi-runtime.d.ts +16 -0
- package/dist/runtime/mcpi-runtime.js +63 -0
- package/dist/runtime/proof-batch-queue.d.ts +3 -0
- package/dist/runtime/proof-batch-queue.js +21 -4
- package/dist/runtime/proof.d.ts +8 -6
- package/dist/runtime/proof.js +35 -16
- package/dist/runtime/request-context.d.ts +37 -0
- package/dist/runtime/request-context.js +56 -0
- package/dist/runtime/session.js +1 -0
- package/dist/runtime/stdio.js +1 -1
- package/dist/runtime/tool-protection-registry.d.ts +94 -0
- package/dist/runtime/tool-protection-registry.js +140 -0
- package/dist/runtime/tool-protection.d.ts +120 -0
- package/dist/runtime/tool-protection.js +192 -0
- package/dist/runtime/transports/http/index.js +2 -1
- package/dist/runtime/utils/tools.js +293 -76
- package/package.json +1 -1
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Global Tool Protection Registry
|
|
3
|
+
*
|
|
4
|
+
* Provides a global registry for tool protection configuration that can be
|
|
5
|
+
* accessed from compiled bundle code where the MCPIRuntime instance is not directly available.
|
|
6
|
+
*
|
|
7
|
+
* This is used by the compiler-generated tool handlers to check if a tool requires delegation
|
|
8
|
+
* BEFORE executing the handler function.
|
|
9
|
+
*/
|
|
10
|
+
import type { ToolProtectionConfig } from './tool-protection';
|
|
11
|
+
import type { SessionContext } from '@kya-os/contracts/handshake';
|
|
12
|
+
/**
|
|
13
|
+
* Global registry for tool protection configuration
|
|
14
|
+
*/
|
|
15
|
+
declare class ToolProtectionRegistry {
|
|
16
|
+
private config;
|
|
17
|
+
private delegationVerifier;
|
|
18
|
+
private authConfig;
|
|
19
|
+
private debug;
|
|
20
|
+
private currentSession;
|
|
21
|
+
/**
|
|
22
|
+
* Register tool protection configuration
|
|
23
|
+
*/
|
|
24
|
+
register(toolName: string, config: ToolProtectionConfig): void;
|
|
25
|
+
/**
|
|
26
|
+
* Bulk register multiple tool protections
|
|
27
|
+
*/
|
|
28
|
+
registerAll(configs: Record<string, ToolProtectionConfig>): void;
|
|
29
|
+
/**
|
|
30
|
+
* Get tool protection configuration
|
|
31
|
+
*/
|
|
32
|
+
get(toolName: string): ToolProtectionConfig | null;
|
|
33
|
+
/**
|
|
34
|
+
* Check if a tool requires delegation
|
|
35
|
+
*/
|
|
36
|
+
requiresDelegation(toolName: string): boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Get required scopes for a tool
|
|
39
|
+
*/
|
|
40
|
+
getRequiredScopes(toolName: string): string[];
|
|
41
|
+
/**
|
|
42
|
+
* Set delegation verifier (for runtime verification)
|
|
43
|
+
*/
|
|
44
|
+
setDelegationVerifier(verifier: any): void;
|
|
45
|
+
/**
|
|
46
|
+
* Set auth config (for authorization handshake)
|
|
47
|
+
*/
|
|
48
|
+
setAuthConfig(config: any): void;
|
|
49
|
+
/**
|
|
50
|
+
* Get delegation verifier
|
|
51
|
+
*/
|
|
52
|
+
getDelegationVerifier(): any;
|
|
53
|
+
/**
|
|
54
|
+
* Get auth config
|
|
55
|
+
*/
|
|
56
|
+
getAuthConfig(): any;
|
|
57
|
+
/**
|
|
58
|
+
* Enable debug logging
|
|
59
|
+
*/
|
|
60
|
+
setDebug(enabled: boolean): void;
|
|
61
|
+
/**
|
|
62
|
+
* Set current session for tool execution context
|
|
63
|
+
*/
|
|
64
|
+
setCurrentSession(session: SessionContext | null): void;
|
|
65
|
+
/**
|
|
66
|
+
* Get current session (for extracting client DID during tool execution)
|
|
67
|
+
*/
|
|
68
|
+
getCurrentSession(): SessionContext | null;
|
|
69
|
+
/**
|
|
70
|
+
* Get current agent DID from session
|
|
71
|
+
*/
|
|
72
|
+
getCurrentAgentDid(): string | null;
|
|
73
|
+
/**
|
|
74
|
+
* Clear all registrations
|
|
75
|
+
*/
|
|
76
|
+
clear(): void;
|
|
77
|
+
/**
|
|
78
|
+
* Get all registered tool names
|
|
79
|
+
*/
|
|
80
|
+
getProtectedTools(): string[];
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Global singleton instance
|
|
84
|
+
*/
|
|
85
|
+
export declare const toolProtectionRegistry: ToolProtectionRegistry;
|
|
86
|
+
/**
|
|
87
|
+
* Helper to check if a tool is protected
|
|
88
|
+
*/
|
|
89
|
+
export declare function isToolProtected(toolName: string): boolean;
|
|
90
|
+
/**
|
|
91
|
+
* Helper to get tool protection config
|
|
92
|
+
*/
|
|
93
|
+
export declare function getToolProtection(toolName: string): ToolProtectionConfig | null;
|
|
94
|
+
export {};
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Global Tool Protection Registry
|
|
4
|
+
*
|
|
5
|
+
* Provides a global registry for tool protection configuration that can be
|
|
6
|
+
* accessed from compiled bundle code where the MCPIRuntime instance is not directly available.
|
|
7
|
+
*
|
|
8
|
+
* This is used by the compiler-generated tool handlers to check if a tool requires delegation
|
|
9
|
+
* BEFORE executing the handler function.
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.toolProtectionRegistry = void 0;
|
|
13
|
+
exports.isToolProtected = isToolProtected;
|
|
14
|
+
exports.getToolProtection = getToolProtection;
|
|
15
|
+
/**
|
|
16
|
+
* Global registry for tool protection configuration
|
|
17
|
+
*/
|
|
18
|
+
class ToolProtectionRegistry {
|
|
19
|
+
config = new Map();
|
|
20
|
+
delegationVerifier = null;
|
|
21
|
+
authConfig = null;
|
|
22
|
+
debug = false;
|
|
23
|
+
currentSession = null;
|
|
24
|
+
/**
|
|
25
|
+
* Register tool protection configuration
|
|
26
|
+
*/
|
|
27
|
+
register(toolName, config) {
|
|
28
|
+
this.config.set(toolName, config);
|
|
29
|
+
if (this.debug) {
|
|
30
|
+
console.error(`[ToolProtectionRegistry] Registered protection for tool: ${toolName}`, config);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Bulk register multiple tool protections
|
|
35
|
+
*/
|
|
36
|
+
registerAll(configs) {
|
|
37
|
+
for (const [toolName, config] of Object.entries(configs)) {
|
|
38
|
+
this.register(toolName, config);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Get tool protection configuration
|
|
43
|
+
*/
|
|
44
|
+
get(toolName) {
|
|
45
|
+
return this.config.get(toolName) || null;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Check if a tool requires delegation
|
|
49
|
+
*/
|
|
50
|
+
requiresDelegation(toolName) {
|
|
51
|
+
const config = this.get(toolName);
|
|
52
|
+
return config?.requiresDelegation || false;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Get required scopes for a tool
|
|
56
|
+
*/
|
|
57
|
+
getRequiredScopes(toolName) {
|
|
58
|
+
const config = this.get(toolName);
|
|
59
|
+
return config?.requiredScopes || [];
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Set delegation verifier (for runtime verification)
|
|
63
|
+
*/
|
|
64
|
+
setDelegationVerifier(verifier) {
|
|
65
|
+
this.delegationVerifier = verifier;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Set auth config (for authorization handshake)
|
|
69
|
+
*/
|
|
70
|
+
setAuthConfig(config) {
|
|
71
|
+
this.authConfig = config;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Get delegation verifier
|
|
75
|
+
*/
|
|
76
|
+
getDelegationVerifier() {
|
|
77
|
+
return this.delegationVerifier;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Get auth config
|
|
81
|
+
*/
|
|
82
|
+
getAuthConfig() {
|
|
83
|
+
return this.authConfig;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Enable debug logging
|
|
87
|
+
*/
|
|
88
|
+
setDebug(enabled) {
|
|
89
|
+
this.debug = enabled;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Set current session for tool execution context
|
|
93
|
+
*/
|
|
94
|
+
setCurrentSession(session) {
|
|
95
|
+
this.currentSession = session;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Get current session (for extracting client DID during tool execution)
|
|
99
|
+
*/
|
|
100
|
+
getCurrentSession() {
|
|
101
|
+
return this.currentSession;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Get current agent DID from session
|
|
105
|
+
*/
|
|
106
|
+
getCurrentAgentDid() {
|
|
107
|
+
return this.currentSession?.agentDid || null;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Clear all registrations
|
|
111
|
+
*/
|
|
112
|
+
clear() {
|
|
113
|
+
this.config.clear();
|
|
114
|
+
this.delegationVerifier = null;
|
|
115
|
+
this.authConfig = null;
|
|
116
|
+
this.currentSession = null;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Get all registered tool names
|
|
120
|
+
*/
|
|
121
|
+
getProtectedTools() {
|
|
122
|
+
return Array.from(this.config.keys());
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Global singleton instance
|
|
127
|
+
*/
|
|
128
|
+
exports.toolProtectionRegistry = new ToolProtectionRegistry();
|
|
129
|
+
/**
|
|
130
|
+
* Helper to check if a tool is protected
|
|
131
|
+
*/
|
|
132
|
+
function isToolProtected(toolName) {
|
|
133
|
+
return exports.toolProtectionRegistry.requiresDelegation(toolName);
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Helper to get tool protection config
|
|
137
|
+
*/
|
|
138
|
+
function getToolProtection(toolName) {
|
|
139
|
+
return exports.toolProtectionRegistry.get(toolName);
|
|
140
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool Protection Configuration and Resolution System (Phase 1.5)
|
|
3
|
+
*
|
|
4
|
+
* Enables zero-code tool protection by configuring which tools require delegation
|
|
5
|
+
* through configuration rather than manual code wrapping.
|
|
6
|
+
*
|
|
7
|
+
* Configuration Resolution Priority (highest to lowest):
|
|
8
|
+
* 1. Inline config (passed to runtime) - for testing and overrides
|
|
9
|
+
* 2. Local file (tool-protections.json) - for development
|
|
10
|
+
* 3. AgentShield API - for production (NOT IMPLEMENTED YET)
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Protection configuration for a single tool
|
|
14
|
+
*/
|
|
15
|
+
export interface ToolProtectionConfig {
|
|
16
|
+
/** Whether this tool requires delegation authorization */
|
|
17
|
+
requiresDelegation: boolean;
|
|
18
|
+
/** Required scopes for this tool (Phase 1: simple string array) */
|
|
19
|
+
requiredScopes?: string[];
|
|
20
|
+
/** Optional risk level indicator (for AgentShield UI) */
|
|
21
|
+
riskLevel?: 'low' | 'medium' | 'high' | 'critical';
|
|
22
|
+
/** Optional custom authorization URL for this specific tool */
|
|
23
|
+
authorizationUrl?: string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Map of tool names to their protection configurations
|
|
27
|
+
*/
|
|
28
|
+
export type ToolProtectionMap = Record<string, ToolProtectionConfig>;
|
|
29
|
+
/**
|
|
30
|
+
* Tool protection configuration source
|
|
31
|
+
*/
|
|
32
|
+
export interface ToolProtectionConfigSource {
|
|
33
|
+
/** Source name for debugging */
|
|
34
|
+
name: string;
|
|
35
|
+
/** Priority level (higher = higher priority) */
|
|
36
|
+
priority: number;
|
|
37
|
+
/** Load the configuration */
|
|
38
|
+
load(): Promise<ToolProtectionMap | null>;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Inline configuration source (highest priority)
|
|
42
|
+
*/
|
|
43
|
+
export declare class InlineToolProtectionSource implements ToolProtectionConfigSource {
|
|
44
|
+
private config;
|
|
45
|
+
name: string;
|
|
46
|
+
priority: number;
|
|
47
|
+
constructor(config: ToolProtectionMap);
|
|
48
|
+
load(): Promise<ToolProtectionMap | null>;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Local file configuration source
|
|
52
|
+
*/
|
|
53
|
+
export declare class FileToolProtectionSource implements ToolProtectionConfigSource {
|
|
54
|
+
private filePath;
|
|
55
|
+
name: string;
|
|
56
|
+
priority: number;
|
|
57
|
+
constructor(filePath: string);
|
|
58
|
+
load(): Promise<ToolProtectionMap | null>;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* AgentShield API configuration source (lowest priority)
|
|
62
|
+
* NOTE: This is a placeholder for future implementation
|
|
63
|
+
*/
|
|
64
|
+
export declare class AgentShieldToolProtectionSource implements ToolProtectionConfigSource {
|
|
65
|
+
private apiUrl;
|
|
66
|
+
private agentDid;
|
|
67
|
+
private apiKey?;
|
|
68
|
+
name: string;
|
|
69
|
+
priority: number;
|
|
70
|
+
constructor(apiUrl: string, agentDid: string, apiKey?: string | undefined);
|
|
71
|
+
load(): Promise<ToolProtectionMap | null>;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Tool protection resolver - merges configs from multiple sources
|
|
75
|
+
*/
|
|
76
|
+
export declare class ToolProtectionResolver {
|
|
77
|
+
private sources;
|
|
78
|
+
private mergedConfig;
|
|
79
|
+
private debug;
|
|
80
|
+
constructor(options?: {
|
|
81
|
+
debug?: boolean;
|
|
82
|
+
});
|
|
83
|
+
/**
|
|
84
|
+
* Add a configuration source
|
|
85
|
+
*/
|
|
86
|
+
addSource(source: ToolProtectionConfigSource): void;
|
|
87
|
+
/**
|
|
88
|
+
* Load and merge all configurations
|
|
89
|
+
*/
|
|
90
|
+
resolve(): Promise<ToolProtectionMap>;
|
|
91
|
+
/**
|
|
92
|
+
* Get protection config for a specific tool
|
|
93
|
+
*/
|
|
94
|
+
getToolProtection(toolName: string): ToolProtectionConfig | null;
|
|
95
|
+
/**
|
|
96
|
+
* Check if a tool requires delegation
|
|
97
|
+
*/
|
|
98
|
+
requiresDelegation(toolName: string): boolean;
|
|
99
|
+
/**
|
|
100
|
+
* Get required scopes for a tool
|
|
101
|
+
*/
|
|
102
|
+
getRequiredScopes(toolName: string): string[];
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Create default tool protection resolver
|
|
106
|
+
*/
|
|
107
|
+
export declare function createToolProtectionResolver(options: {
|
|
108
|
+
/** Inline configuration (highest priority) */
|
|
109
|
+
inline?: ToolProtectionMap;
|
|
110
|
+
/** Local file path (default: tool-protections.json) */
|
|
111
|
+
localFile?: string | false;
|
|
112
|
+
/** AgentShield API configuration */
|
|
113
|
+
agentShield?: {
|
|
114
|
+
apiUrl: string;
|
|
115
|
+
agentDid: string;
|
|
116
|
+
apiKey?: string;
|
|
117
|
+
};
|
|
118
|
+
/** Enable debug logging */
|
|
119
|
+
debug?: boolean;
|
|
120
|
+
}): ToolProtectionResolver;
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Tool Protection Configuration and Resolution System (Phase 1.5)
|
|
4
|
+
*
|
|
5
|
+
* Enables zero-code tool protection by configuring which tools require delegation
|
|
6
|
+
* through configuration rather than manual code wrapping.
|
|
7
|
+
*
|
|
8
|
+
* Configuration Resolution Priority (highest to lowest):
|
|
9
|
+
* 1. Inline config (passed to runtime) - for testing and overrides
|
|
10
|
+
* 2. Local file (tool-protections.json) - for development
|
|
11
|
+
* 3. AgentShield API - for production (NOT IMPLEMENTED YET)
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.ToolProtectionResolver = exports.AgentShieldToolProtectionSource = exports.FileToolProtectionSource = exports.InlineToolProtectionSource = void 0;
|
|
15
|
+
exports.createToolProtectionResolver = createToolProtectionResolver;
|
|
16
|
+
/**
|
|
17
|
+
* Inline configuration source (highest priority)
|
|
18
|
+
*/
|
|
19
|
+
class InlineToolProtectionSource {
|
|
20
|
+
config;
|
|
21
|
+
name = 'inline';
|
|
22
|
+
priority = 100;
|
|
23
|
+
constructor(config) {
|
|
24
|
+
this.config = config;
|
|
25
|
+
}
|
|
26
|
+
async load() {
|
|
27
|
+
return this.config;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
exports.InlineToolProtectionSource = InlineToolProtectionSource;
|
|
31
|
+
/**
|
|
32
|
+
* Local file configuration source
|
|
33
|
+
*/
|
|
34
|
+
class FileToolProtectionSource {
|
|
35
|
+
filePath;
|
|
36
|
+
name = 'file';
|
|
37
|
+
priority = 50;
|
|
38
|
+
constructor(filePath) {
|
|
39
|
+
this.filePath = filePath;
|
|
40
|
+
}
|
|
41
|
+
async load() {
|
|
42
|
+
try {
|
|
43
|
+
// Dynamic import to avoid bundling issues
|
|
44
|
+
const fs = await import('fs/promises');
|
|
45
|
+
const path = await import('path');
|
|
46
|
+
const fullPath = path.resolve(process.cwd(), this.filePath);
|
|
47
|
+
const content = await fs.readFile(fullPath, 'utf-8');
|
|
48
|
+
const config = JSON.parse(content);
|
|
49
|
+
// Validate structure
|
|
50
|
+
if (typeof config !== 'object' || config === null) {
|
|
51
|
+
console.warn(`[ToolProtection] Invalid config file at ${fullPath}: not an object`);
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
return config;
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
// File not found is OK - just means no local config
|
|
58
|
+
if (error.code === 'ENOENT') {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
console.warn(`[ToolProtection] Error loading config from ${this.filePath}:`, error);
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
exports.FileToolProtectionSource = FileToolProtectionSource;
|
|
67
|
+
/**
|
|
68
|
+
* AgentShield API configuration source (lowest priority)
|
|
69
|
+
* NOTE: This is a placeholder for future implementation
|
|
70
|
+
*/
|
|
71
|
+
class AgentShieldToolProtectionSource {
|
|
72
|
+
apiUrl;
|
|
73
|
+
agentDid;
|
|
74
|
+
apiKey;
|
|
75
|
+
name = 'agentshield';
|
|
76
|
+
priority = 10;
|
|
77
|
+
constructor(apiUrl, agentDid, apiKey) {
|
|
78
|
+
this.apiUrl = apiUrl;
|
|
79
|
+
this.agentDid = agentDid;
|
|
80
|
+
this.apiKey = apiKey;
|
|
81
|
+
}
|
|
82
|
+
async load() {
|
|
83
|
+
// TODO: Implement AgentShield API fetch
|
|
84
|
+
// GET /v1/agents/{agentDid}/tool-protections
|
|
85
|
+
// Headers: { Authorization: `Bearer ${apiKey}` }
|
|
86
|
+
console.warn('[ToolProtection] AgentShield API source not yet implemented');
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
exports.AgentShieldToolProtectionSource = AgentShieldToolProtectionSource;
|
|
91
|
+
/**
|
|
92
|
+
* Tool protection resolver - merges configs from multiple sources
|
|
93
|
+
*/
|
|
94
|
+
class ToolProtectionResolver {
|
|
95
|
+
sources = [];
|
|
96
|
+
mergedConfig = null;
|
|
97
|
+
debug;
|
|
98
|
+
constructor(options = {}) {
|
|
99
|
+
this.debug = options.debug || false;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Add a configuration source
|
|
103
|
+
*/
|
|
104
|
+
addSource(source) {
|
|
105
|
+
this.sources.push(source);
|
|
106
|
+
// Sort by priority (highest first)
|
|
107
|
+
this.sources.sort((a, b) => b.priority - a.priority);
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Load and merge all configurations
|
|
111
|
+
*/
|
|
112
|
+
async resolve() {
|
|
113
|
+
if (this.mergedConfig) {
|
|
114
|
+
return this.mergedConfig;
|
|
115
|
+
}
|
|
116
|
+
const configs = [];
|
|
117
|
+
// Load from all sources in priority order
|
|
118
|
+
for (const source of this.sources) {
|
|
119
|
+
if (this.debug) {
|
|
120
|
+
console.error(`[ToolProtection] Loading config from source: ${source.name} (priority: ${source.priority})`);
|
|
121
|
+
}
|
|
122
|
+
const config = await source.load();
|
|
123
|
+
if (config) {
|
|
124
|
+
configs.push({ source: source.name, config });
|
|
125
|
+
if (this.debug) {
|
|
126
|
+
console.error(`[ToolProtection] Loaded ${Object.keys(config).length} tool configs from ${source.name}`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
// Merge configs (higher priority sources override lower priority)
|
|
131
|
+
// Start with lowest priority and overlay higher priority configs
|
|
132
|
+
this.mergedConfig = {};
|
|
133
|
+
for (let i = configs.length - 1; i >= 0; i--) {
|
|
134
|
+
const { source, config } = configs[i];
|
|
135
|
+
for (const [toolName, toolConfig] of Object.entries(config)) {
|
|
136
|
+
if (this.debug && this.mergedConfig[toolName]) {
|
|
137
|
+
console.error(`[ToolProtection] Tool "${toolName}" config from ${source} overrides previous config`);
|
|
138
|
+
}
|
|
139
|
+
this.mergedConfig[toolName] = toolConfig;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
if (this.debug) {
|
|
143
|
+
console.error(`[ToolProtection] Final merged config has ${Object.keys(this.mergedConfig).length} protected tools`);
|
|
144
|
+
console.error('[ToolProtection] Protected tools:', Object.keys(this.mergedConfig));
|
|
145
|
+
}
|
|
146
|
+
return this.mergedConfig;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Get protection config for a specific tool
|
|
150
|
+
*/
|
|
151
|
+
getToolProtection(toolName) {
|
|
152
|
+
if (!this.mergedConfig) {
|
|
153
|
+
throw new Error('ToolProtectionResolver not initialized - call resolve() first');
|
|
154
|
+
}
|
|
155
|
+
return this.mergedConfig[toolName] || null;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Check if a tool requires delegation
|
|
159
|
+
*/
|
|
160
|
+
requiresDelegation(toolName) {
|
|
161
|
+
const config = this.getToolProtection(toolName);
|
|
162
|
+
return config?.requiresDelegation || false;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Get required scopes for a tool
|
|
166
|
+
*/
|
|
167
|
+
getRequiredScopes(toolName) {
|
|
168
|
+
const config = this.getToolProtection(toolName);
|
|
169
|
+
return config?.requiredScopes || [];
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
exports.ToolProtectionResolver = ToolProtectionResolver;
|
|
173
|
+
/**
|
|
174
|
+
* Create default tool protection resolver
|
|
175
|
+
*/
|
|
176
|
+
function createToolProtectionResolver(options) {
|
|
177
|
+
const resolver = new ToolProtectionResolver({ debug: options.debug });
|
|
178
|
+
// Add inline source if provided
|
|
179
|
+
if (options.inline) {
|
|
180
|
+
resolver.addSource(new InlineToolProtectionSource(options.inline));
|
|
181
|
+
}
|
|
182
|
+
// Add local file source unless explicitly disabled
|
|
183
|
+
if (options.localFile !== false) {
|
|
184
|
+
const filePath = options.localFile || 'tool-protections.json';
|
|
185
|
+
resolver.addSource(new FileToolProtectionSource(filePath));
|
|
186
|
+
}
|
|
187
|
+
// Add AgentShield source if configured
|
|
188
|
+
if (options.agentShield) {
|
|
189
|
+
resolver.addSource(new AgentShieldToolProtectionSource(options.agentShield.apiUrl, options.agentShield.agentDid, options.agentShield.apiKey));
|
|
190
|
+
}
|
|
191
|
+
return resolver;
|
|
192
|
+
}
|
|
@@ -11,7 +11,8 @@ const corsConfig = HTTP_CORS_CONFIG;
|
|
|
11
11
|
const middleware = INJECTED_MIDDLEWARE;
|
|
12
12
|
// oauth config
|
|
13
13
|
// @ts-expect-error: injected by compiler
|
|
14
|
-
const
|
|
14
|
+
const oauthConfigRaw = OAUTH_CONFIG;
|
|
15
|
+
const oauthConfig = (oauthConfigRaw && JSON.parse(oauthConfigRaw));
|
|
15
16
|
async function main() {
|
|
16
17
|
const options = {
|
|
17
18
|
port: httpConfig?.port,
|