Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
150 changes: 77 additions & 73 deletions POLICY_INDEX.md

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions autogen/POLICY_INDEX.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ Risk score = `severity_weight × confidence × 100` (engine formula; weights: lo
| -- | ------- | ------- | ----- | --------------------------------------------------- | ------------------------------------------------------------------------ | -------- | ---------- | ---- | --------------------------------------------------------------------------------------------------------- |
| 1 | AG2-001 | AutoGen | agent | autogen_conversable_agent, autogen_user_proxy_agent | AutoGen executor runs code on the host without Docker | high | 0.90 | 63.0 | [agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/autogen/agent_safety.yaml) |
| 2 | AG2-002 | AutoGen | agent | autogen_conversable_agent, autogen_user_proxy_agent | AutoGen executor runs code with no human review (human_input_mode=NEVER) | high | 0.85 | 59.5 | [agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/autogen/agent_safety.yaml) |
| 3 | AG2-004 | AutoGen | agent | autogen_group_chat_manager | AutoGen GroupChatManager has no max_round bound | medium | 0.80 | 32.0 | [agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/autogen/agent_safety.yaml) |
| 3 | AG2-004 | AutoGen | agent | autogen_group_chat_manager | AutoGen GroupChatManager has no explicit max_round bound | low | 0.60 | 9.0 | [agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/autogen/agent_safety.yaml) |
| 4 | AG2-005 | AutoGen | agent | autogen_assistant_agent | AutoGen AssistantAgent enables code execution on the LLM agent | medium | 0.70 | 28.0 | [agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/autogen/agent_safety.yaml) |
| 5 | AG2-006 | AutoGen | agent | autogen_conversable_agent, autogen_user_proxy_agent | AutoGen executor with code execution has no auto-reply cap | medium | 0.70 | 28.0 | [agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/autogen/agent_safety.yaml) |
| 5 | AG2-006 | AutoGen | agent | autogen_conversable_agent, autogen_user_proxy_agent | AutoGen executor with code execution has no explicit auto-reply cap | medium | 0.70 | 28.0 | [agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/autogen/agent_safety.yaml) |
| 6 | AG2-007 | AutoGen | tool | autogen_tool | AutoGen tool has no description | low | 0.90 | 13.5 | [tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/autogen/tool_definition.yaml) |
| 7 | AG2-008 | AutoGen | tool | autogen_tool | AutoGen tool parameters are not type-annotated | medium | 0.85 | 34.0 | [tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/autogen/tool_definition.yaml) |
| 8 | AG2-009 | AutoGen | tool | autogen_tool | AutoGen tool body spawns a subprocess | high | 0.85 | 59.5 | [shell_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/autogen/shell_safety.yaml) |
| 9 | AG2-010 | AutoGen | tool | autogen_tool | AutoGen tool body evaluates dynamic code | high | 0.85 | 59.5 | [code_execution.yaml](https://github.com/trustabl/trustabl-rules/blob/main/autogen/code_execution.yaml) |
| 10 | AG2-011 | AutoGen | tool | autogen_tool | AutoGen tool fetches a caller-controlled URL (SSRF) | high | 0.80 | 56.0 | [ssrf.yaml](https://github.com/trustabl/trustabl-rules/blob/main/autogen/ssrf.yaml) |
| 11 | AG2-012 | AutoGen | tool | autogen_tool | AutoGen tool network call has no timeout | medium | 0.80 | 32.0 | [network.yaml](https://github.com/trustabl/trustabl-rules/blob/main/autogen/network.yaml) |
| 11 | AG2-012 | AutoGen | tool | autogen_tool | AutoGen tool network call has no timeout | high | 0.85 | 59.5 | [network.yaml](https://github.com/trustabl/trustabl-rules/blob/main/autogen/network.yaml) |
| 12 | AG2-201 | AutoGen | repo | autogen | AutoGen project ships no agent-guidance doc (AGENTS.md/CLAUDE.md) | low | 0.90 | 13.5 | [repo_hygiene.yaml](https://github.com/trustabl/trustabl-rules/blob/main/autogen/repo_hygiene.yaml) |
6 changes: 3 additions & 3 deletions claude_sdk/POLICY_INDEX.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,19 @@ Risk score = `severity_weight × confidence × 100` (engine formula; weights: lo
| 2 | CSDK-002 | Claude SDK | tool | claude_sdk_tool | Tool parameters are not type-annotated | medium | 0.90 | 36.0 | [tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/tool_definition.yaml) |
| 3 | CSDK-003 | Claude SDK | tool | claude_sdk_tool | Network call has no timeout | high | 0.85 | 59.5 | [network.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/network.yaml) |
| 4 | CSDK-004 | Claude SDK | tool | claude_sdk_tool | Path parameter used in I/O without validation | high | 0.70 | 49.0 | [path_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/path_safety.yaml) |
| 5 | CSDK-005 | Claude SDK | tool | claude_sdk_tool | Tool raises exceptions without a structured error contract | medium | 0.60 | 24.0 | [error_handling.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/error_handling.yaml) |
| 5 | CSDK-005 | Claude SDK | tool | claude_sdk_tool | Tool raises exceptions without a structured error contract | low | 0.60 | 9.0 | [error_handling.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/error_handling.yaml) |
| 6 | CSDK-006 | Claude SDK | tool | claude_sdk_tool | Mutating tool has no idempotency key | medium | 0.55 | 22.0 | [idempotency.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/idempotency.yaml) |
| 7 | CSDK-007 | Claude SDK | tool | claude_sdk_tool | Ambiguous tool name | low | 0.90 | 13.5 | [tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/tool_definition.yaml) |
| 8 | CSDK-008 | Claude SDK | tool | claude_sdk_tool | Tool exposes **kwargs without explicit input_schema | medium | 0.80 | 32.0 | [tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/tool_definition.yaml) |
| 9 | CSDK-009 | Claude SDK | tool | claude_sdk_tool | Tool fetches a caller-controlled URL (SSRF) | high | 0.60 | 42.0 | [ssrf.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/ssrf.yaml) |
| 10 | CSDK-010 | Claude SDK | tool | claude_sdk_tool | TypeScript Claude SDK tool shells out to the OS | high | 0.70 | 49.0 | [shell_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/shell_safety.yaml) |
| 11 | CSDK-011 | Claude SDK | tool | claude_sdk_tool | TypeScript Claude SDK tool evaluates dynamic code | high | 0.90 | 63.0 | [code_execution.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/code_execution.yaml) |
| 12 | CSDK-012 | Claude SDK | tool | claude_sdk_tool | TypeScript Claude SDK tool writes to the filesystem | medium | 0.50 | 20.0 | [path_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/path_safety.yaml) |
| 12 | CSDK-012 | Claude SDK | tool | claude_sdk_tool | TypeScript Claude SDK tool writes to the filesystem | low | 0.50 | 7.5 | [path_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/path_safety.yaml) |
| 13 | CSDK-013 | Claude SDK | tool | claude_sdk_tool | TypeScript Claude SDK tool fetches a caller-controlled URL (SSRF) | high | 0.60 | 42.0 | [ssrf.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/ssrf.yaml) |
| 14 | CSDK-014 | Claude SDK | tool | claude_sdk_tool | TypeScript Claude SDK tool has no description | low | 0.90 | 13.5 | [tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/tool_definition.yaml) |
| 15 | CSDK-016 | Claude SDK | tool | claude_sdk_tool | TypeScript Claude SDK mutating tool has no idempotency key | medium | 0.50 | 20.0 | [idempotency.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/idempotency.yaml) |
| 16 | CSDK-101 | Claude SDK | agent | claude_agent_definition | Claude subagent is granted the Bash tool | high | 0.80 | 56.0 | [agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/agent_safety.yaml) |
| 17 | CSDK-102 | Claude SDK | agent | claude_agent_definition | Claude subagent is granted the WebSearch tool | high | 0.80 | 56.0 | [agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/agent_safety.yaml) |
| 17 | CSDK-102 | Claude SDK | agent | claude_agent_definition | Claude subagent is granted the WebSearch tool | medium | 0.80 | 32.0 | [agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/agent_safety.yaml) |
| 18 | CSDK-103 | Claude SDK | agent | claude_agent_definition | AgentDefinition sets permissionMode to bypassPermissions | high | 0.90 | 63.0 | [agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/agent_safety.yaml) |
| 19 | CSDK-104 | Claude SDK | agent | claude_agent_definition | Claude subagent is granted filesystem-write built-ins | high | 0.80 | 56.0 | [agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/agent_safety.yaml) |
| 20 | CSDK-105 | Claude SDK | agent | claude_agent_definition | Claude subagent is granted the WebFetch tool | high | 0.75 | 52.5 | [agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/claude_sdk/agent_safety.yaml) |
Expand Down
82 changes: 78 additions & 4 deletions docs/Policy/mcp/tool_definition.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,34 @@ rules:
confidence: 0.85
scope: tool
fix_type: code
- id: MCP-015
severity: low
confidence: 0.85
scope: tool
fix_type: code
- id: MCP-016
severity: low
confidence: 0.85
scope: tool
fix_type: code
- id: MCP-017
severity: low
confidence: 0.85
scope: tool
fix_type: code
- id: MCP-018
severity: low
confidence: 0.85
scope: tool
fix_type: code
references: [LLM06]
---

# Policy Rationale: MCP Tool Definition Hygiene

**Policy ID:** `mcp_tool_definition`
**File:** `mcp/tool_definition.yaml`
**Rules:** MCP-001, MCP-002, MCP-003, MCP-011
**Rules:** MCP-001, MCP-002, MCP-003, MCP-011, MCP-015, MCP-016, MCP-017, MCP-018
**References:** LLM06 (Excessive Agency)

> Shares the structural-hygiene threat model with
Expand All @@ -44,8 +64,12 @@ references: [LLM06]
The structural hygiene of Model Context Protocol tool registrations — the
Python decorator forms (`@server.tool` / `@mcp.tool` / `.register_tool`,
predicate `mcp_tool` kind) and the TypeScript `@modelcontextprotocol/sdk`
`server.registerTool(...)` / `server.tool(...)` forms. MCP-001/002/003 are the
Python rules; MCP-011 is the TypeScript description rule.
`server.registerTool(...)` / `server.tool(...)` forms, the Go SDKs
(mark3labs/mcp-go's `mcp.NewTool(...)` and the official go-sdk's
`mcp.AddTool(server, &mcp.Tool{...}, fn)`), and the official C# SDK's
`[McpServerTool]`-attributed methods. MCP-001/002/003 are the Python rules;
MCP-011 is the TypeScript description rule; MCP-015/016 are the Go rules;
MCP-017 (no description) and MCP-018 (ambiguous name) are the C# rules.

## Why definition hygiene is sharper for MCP than for an in-process SDK

Expand Down Expand Up @@ -107,6 +131,49 @@ the registration config's `description` is the model's routing signal. Confidenc
0.85 (vs MCP-001's 0.9) reflects that the TypeScript capture can miss a
description supplied through an unusual expression shape.

### MCP-015 — Go MCP tool has no description (Severity: low, Confidence: 0.85, Fix type: code)

**What we detect:** a Go MCP tool whose description is empty
(`has_docstring: false`, reading the captured `Description`) — a mark3labs
`mcp.NewTool("name", ...)` with no `mcp.WithDescription(...)` option, or an
official-SDK `mcp.Tool{...}` with no `Description` field.

**Why it is flaggable:** identical mechanism to MCP-001 / MCP-011 on the Go
SDKs — the description is what the server advertises to connecting clients as the
model's routing signal. Confidence 0.85 mirrors the other description rules; the
residual gap is a description supplied through a non-literal expression, captured
as empty.

### MCP-016 — Ambiguous Go MCP tool name (Severity: low, Confidence: 0.85, Fix type: code)

**What we detect:** a Go MCP tool whose name — the first argument to
`mcp.NewTool(...)`, or the `Name` field of an `mcp.Tool` — is in the fixed
ambiguous set (`process`, `handle`, `run`, ...) via `name_in`.

**Why it is flaggable:** identical to MCP-003 — an ambiguous name gives the model
no intent signal and collides across servers in a shared session, and the cost is
paid by every uncontrolled consumer of the published catalog.

### MCP-017 — C# MCP tool has no description (Severity: low, Confidence: 0.85, Fix type: code)

**What we detect:** an `[McpServerTool]`-attributed C# method with no co-located
`[Description("...")]` attribute (`has_docstring: false`, reading the captured
`Description`).

**Why it is flaggable:** identical mechanism to MCP-001 / MCP-011 / MCP-015 on
the official ModelContextProtocol C# SDK — `[Description]` is what the server
advertises to connecting clients as the model's routing signal. Confidence 0.85
mirrors the other description rules.

### MCP-018 — Ambiguous C# MCP tool name (Severity: low, Confidence: 0.85, Fix type: code)

**What we detect:** an `[McpServerTool]` method whose name (the method name — the
SDK default) is in the fixed ambiguous set (`process`, `handle`, `run`, ...) via
`name_in` (case-insensitive, so PascalCase `Process` matches).

**Why it is flaggable:** identical to MCP-003 / MCP-016 — an ambiguous name gives
the model no intent signal and collides across servers in a shared session.

---

## What this policy does not cover
Expand All @@ -116,4 +183,11 @@ and the low-level `Server` + `setRequestHandler` authoring shape (tools there ar
returned from a `ListTools` handler, not named at a registration call site, so no
per-tool definition is extracted). Resource and prompt registrations
(`@mcp.resource` / `@mcp.prompt`, `registerResource` / `registerPrompt`) are not
yet discovered.
yet discovered. For Go, untyped-params has no analog (Go is statically typed, so
there is no MCP-002 equivalent), the official SDK's handler-struct input schema
and metoro-io/mcp-golang's reflection-based `RegisterTool` are not yet extracted,
and body-fact rules (shell / SSRF / timeout) await Go AST predicates. For C#,
untyped-params likewise has no analog (C# is statically typed), the
`[McpServerTool(Name = "...")]` name override is not read, and body-fact rules
plus the Semantic Kernel `[KernelFunction]` / AutoGen `[Function]` shapes await
later work.
2 changes: 1 addition & 1 deletion google_adk/POLICY_INDEX.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Risk score = `severity_weight × confidence × 100` (engine formula; weights: lo
| 2 | ADK-002 | Google ADK | tool | adk_function_tool | FunctionTool-wrapped function has no type-annotated parameters | medium | 0.85 | 34.0 | [tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/tool_definition.yaml) |
| 3 | ADK-003 | Google ADK | tool | adk_function_tool | Network call has no timeout | high | 0.85 | 59.5 | [network.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/network.yaml) |
| 4 | ADK-004 | Google ADK | tool | adk_function_tool | Path parameter used in I/O without normalization | high | 0.70 | 49.0 | [path_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/path_safety.yaml) |
| 5 | ADK-005 | Google ADK | tool | adk_function_tool | Tool raises exceptions without a structured error contract | medium | 0.60 | 24.0 | [error_handling.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/error_handling.yaml) |
| 5 | ADK-005 | Google ADK | tool | adk_function_tool | Tool raises exceptions without a structured error contract | low | 0.60 | 9.0 | [error_handling.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/error_handling.yaml) |
| 6 | ADK-006 | Google ADK | tool | adk_function_tool | Mutating tool has no idempotency key | medium | 0.55 | 22.0 | [idempotency.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/idempotency.yaml) |
| 7 | ADK-007 | Google ADK | tool | adk_function_tool | Ambiguous tool name | low | 0.90 | 13.5 | [tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/tool_definition.yaml) |
| 8 | ADK-008 | Google ADK | agent | adk_llm_agent | Agent grants BashTool with no restrictive command policy | high | 0.75 | 52.5 | [builtin_tools.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/builtin_tools.yaml) |
Expand Down
Loading
Loading