mirror of
https://github.com/instructkr/claude-code.git
synced 2026-04-06 03:08:48 +03:00
feat: add MCPTool + TestingPermissionTool — tool surface 40/40
Close the final tool parity gap: - MCP: dynamic tool proxy for connected MCP servers - TestingPermission: test-only permission enforcement verification Tool surface now matches upstream: 40/40. All stubs, fmt/clippy/tests green.
This commit is contained in:
@@ -805,6 +805,34 @@ pub fn mvp_tool_specs() -> Vec<ToolSpec> {
|
|||||||
}),
|
}),
|
||||||
required_permission: PermissionMode::DangerFullAccess,
|
required_permission: PermissionMode::DangerFullAccess,
|
||||||
},
|
},
|
||||||
|
ToolSpec {
|
||||||
|
name: "MCP",
|
||||||
|
description: "Execute a tool provided by a connected MCP server.",
|
||||||
|
input_schema: json!({
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"server": { "type": "string" },
|
||||||
|
"tool": { "type": "string" },
|
||||||
|
"arguments": { "type": "object" }
|
||||||
|
},
|
||||||
|
"required": ["server", "tool"],
|
||||||
|
"additionalProperties": false
|
||||||
|
}),
|
||||||
|
required_permission: PermissionMode::DangerFullAccess,
|
||||||
|
},
|
||||||
|
ToolSpec {
|
||||||
|
name: "TestingPermission",
|
||||||
|
description: "Test-only tool for verifying permission enforcement behavior.",
|
||||||
|
input_schema: json!({
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"action": { "type": "string" }
|
||||||
|
},
|
||||||
|
"required": ["action"],
|
||||||
|
"additionalProperties": false
|
||||||
|
}),
|
||||||
|
required_permission: PermissionMode::DangerFullAccess,
|
||||||
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -854,6 +882,10 @@ pub fn execute_tool(name: &str, input: &Value) -> Result<String, String> {
|
|||||||
"ReadMcpResource" => from_value::<McpResourceInput>(input).and_then(run_read_mcp_resource),
|
"ReadMcpResource" => from_value::<McpResourceInput>(input).and_then(run_read_mcp_resource),
|
||||||
"McpAuth" => from_value::<McpAuthInput>(input).and_then(run_mcp_auth),
|
"McpAuth" => from_value::<McpAuthInput>(input).and_then(run_mcp_auth),
|
||||||
"RemoteTrigger" => from_value::<RemoteTriggerInput>(input).and_then(run_remote_trigger),
|
"RemoteTrigger" => from_value::<RemoteTriggerInput>(input).and_then(run_remote_trigger),
|
||||||
|
"MCP" => from_value::<McpToolInput>(input).and_then(run_mcp_tool),
|
||||||
|
"TestingPermission" => {
|
||||||
|
from_value::<TestingPermissionInput>(input).and_then(run_testing_permission)
|
||||||
|
}
|
||||||
_ => Err(format!("unsupported tool: {name}")),
|
_ => Err(format!("unsupported tool: {name}")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1039,6 +1071,26 @@ fn run_remote_trigger(input: RemoteTriggerInput) -> Result<String, String> {
|
|||||||
"message": "Remote trigger stub response"
|
"message": "Remote trigger stub response"
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::needless_pass_by_value)]
|
||||||
|
fn run_mcp_tool(input: McpToolInput) -> Result<String, String> {
|
||||||
|
to_pretty_json(json!({
|
||||||
|
"server": input.server,
|
||||||
|
"tool": input.tool,
|
||||||
|
"arguments": input.arguments,
|
||||||
|
"result": null,
|
||||||
|
"message": "MCP tool proxy not yet connected"
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::needless_pass_by_value)]
|
||||||
|
fn run_testing_permission(input: TestingPermissionInput) -> Result<String, String> {
|
||||||
|
to_pretty_json(json!({
|
||||||
|
"action": input.action,
|
||||||
|
"permitted": true,
|
||||||
|
"message": "Testing permission tool stub"
|
||||||
|
}))
|
||||||
|
}
|
||||||
fn from_value<T: for<'de> Deserialize<'de>>(input: &Value) -> Result<T, String> {
|
fn from_value<T: for<'de> Deserialize<'de>>(input: &Value) -> Result<T, String> {
|
||||||
serde_json::from_value(input.clone()).map_err(|error| error.to_string())
|
serde_json::from_value(input.clone()).map_err(|error| error.to_string())
|
||||||
}
|
}
|
||||||
@@ -1404,6 +1456,19 @@ struct RemoteTriggerInput {
|
|||||||
body: Option<String>,
|
body: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct McpToolInput {
|
||||||
|
server: String,
|
||||||
|
tool: String,
|
||||||
|
#[serde(default)]
|
||||||
|
arguments: Option<Value>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct TestingPermissionInput {
|
||||||
|
action: String,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize)]
|
||||||
struct WebFetchOutput {
|
struct WebFetchOutput {
|
||||||
bytes: usize,
|
bytes: usize,
|
||||||
|
|||||||
Reference in New Issue
Block a user