Class: Aidp::Security::McpRiskProfile

Inherits:
Object
  • Object
show all
Defined in:
lib/aidp/security/mcp_risk_profile.rb

Overview

Deterministic MCP tool risk profile generated once during configuration.

Constant Summary collapse

VERSION =
1
VALID_FLAGS =
%w[untrusted_input private_data egress].freeze
VALID_RISK_LEVELS =
%w[low medium high].freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(generated_at: nil, generator_model: nil, version: VERSION, tools: {}) ⇒ McpRiskProfile

Returns a new instance of McpRiskProfile.



33
34
35
36
37
38
# File 'lib/aidp/security/mcp_risk_profile.rb', line 33

def initialize(generated_at: nil, generator_model: nil, version: VERSION, tools: {})
  @generated_at = generated_at
  @generator_model = generator_model
  @version = version
  @tools = normalize_tools(tools)
end

Instance Attribute Details

#generated_atObject (readonly)

Returns the value of attribute generated_at.



15
16
17
# File 'lib/aidp/security/mcp_risk_profile.rb', line 15

def generated_at
  @generated_at
end

#generator_modelObject (readonly)

Returns the value of attribute generator_model.



15
16
17
# File 'lib/aidp/security/mcp_risk_profile.rb', line 15

def generator_model
  @generator_model
end

#toolsObject (readonly)

Returns the value of attribute tools.



15
16
17
# File 'lib/aidp/security/mcp_risk_profile.rb', line 15

def tools
  @tools
end

#versionObject (readonly)

Returns the value of attribute version.



15
16
17
# File 'lib/aidp/security/mcp_risk_profile.rb', line 15

def version
  @version
end

Class Method Details

.load(project_dir = Dir.pwd) ⇒ Object



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/aidp/security/mcp_risk_profile.rb', line 17

def self.load(project_dir = Dir.pwd)
  path = Aidp::ConfigPaths.mcp_risk_profile_file(project_dir)
  return new(tools: {}) unless File.exist?(path)

  data = YAML.safe_load_file(path, permitted_classes: [Symbol], symbolize_names: true) || {}
  new(
    generated_at: data[:generated_at],
    generator_model: data[:generator_model],
    version: data[:version] || VERSION,
    tools: data[:tools] || {}
  )
rescue Psych::Exception => e
  Aidp.log_error("security.mcp_risk_profile", "load_failed", path: path, error: e.message)
  new(tools: {})
end

Instance Method Details

#empty?Boolean

Returns:

  • (Boolean)


57
58
59
# File 'lib/aidp/security/mcp_risk_profile.rb', line 57

def empty?
  tools.empty?
end

#flags_for(tool_name) ⇒ Object



49
50
51
# File 'lib/aidp/security/mcp_risk_profile.rb', line 49

def flags_for(tool_name)
  tool(tool_name)&.fetch(:flags, []) || []
end

#risk_level_for(tool_name) ⇒ Object



53
54
55
# File 'lib/aidp/security/mcp_risk_profile.rb', line 53

def risk_level_for(tool_name)
  tool(tool_name)&.fetch(:risk_level, nil)
end

#save!(project_dir = Dir.pwd) ⇒ Object



40
41
42
43
# File 'lib/aidp/security/mcp_risk_profile.rb', line 40

def save!(project_dir = Dir.pwd)
  Aidp::ConfigPaths.ensure_security_dir(project_dir)
  File.write(Aidp::ConfigPaths.mcp_risk_profile_file(project_dir), YAML.dump(to_h))
end

#to_hObject



61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/aidp/security/mcp_risk_profile.rb', line 61

def to_h
  {
    "generated_at" => generated_at,
    "generator_model" => generator_model,
    "version" => version,
    "tools" => tools.transform_values do |tool_data|
      {
        "flags" => tool_data[:flags],
        "risk_level" => tool_data[:risk_level],
        "rationale" => tool_data[:rationale]
      }
    end
  }
end

#tool(tool_name) ⇒ Object



45
46
47
# File 'lib/aidp/security/mcp_risk_profile.rb', line 45

def tool(tool_name)
  tools[tool_name.to_s]
end