diff --git a/core/src/main/java/com/google/adk/tools/computeruse/BaseComputer.java b/core/src/main/java/com/google/adk/tools/computeruse/BaseComputer.java
new file mode 100644
index 000000000..3ddb91963
--- /dev/null
+++ b/core/src/main/java/com/google/adk/tools/computeruse/BaseComputer.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.adk.tools.computeruse;
+
+import com.google.adk.tools.Annotations.Schema;
+import io.reactivex.rxjava3.core.Completable;
+import io.reactivex.rxjava3.core.Single;
+import java.time.Duration;
+import java.util.List;
+
+/**
+ * Defines an interface for computer environments.
+ *
+ *
This interface defines the standard methods for controlling computer environments, including
+ * web browsers and other interactive systems.
+ */
+public interface BaseComputer {
+
+ /** Returns the screen size of the environment. */
+ Single screenSize();
+
+ /** Opens the web browser. */
+ Single openWebBrowser();
+
+ /** Clicks at a specific x, y coordinate on the webpage. */
+ Single clickAt(@Schema(name = "x") int x, @Schema(name = "y") int y);
+
+ /** Hovers at a specific x, y coordinate on the webpage. */
+ Single hoverAt(@Schema(name = "x") int x, @Schema(name = "y") int y);
+
+ /** Types text at a specific x, y coordinate. */
+ Single typeTextAt(
+ @Schema(name = "x") int x,
+ @Schema(name = "y") int y,
+ @Schema(name = "text") String text,
+ @Schema(name = "press_enter", optional = true) Boolean pressEnter,
+ @Schema(name = "clear_before_typing", optional = true) Boolean clearBeforeTyping);
+
+ /** Scrolls the entire webpage in a direction. */
+ Single scrollDocument(@Schema(name = "direction") String direction);
+
+ /** Scrolls at a specific x, y coordinate by magnitude. */
+ Single scrollAt(
+ @Schema(name = "x") int x,
+ @Schema(name = "y") int y,
+ @Schema(name = "direction") String direction,
+ @Schema(name = "magnitude") int magnitude);
+
+ /** Waits for specified duration. */
+ Single wait(@Schema(name = "duration") Duration duration);
+
+ /** Navigates back. */
+ Single goBack();
+
+ /** Navigates forward. */
+ Single goForward();
+
+ /** Jumps to search. */
+ Single search();
+
+ /** Navigates to URL. */
+ Single navigate(@Schema(name = "url") String url);
+
+ /** Presses key combination. */
+ Single keyCombination(@Schema(name = "keys") List keys);
+
+ /** Drag and drop. */
+ Single dragAndDrop(
+ @Schema(name = "x") int x,
+ @Schema(name = "y") int y,
+ @Schema(name = "destination_x") int destinationX,
+ @Schema(name = "destination_y") int destinationY);
+
+ /** Returns current state. */
+ Single currentState();
+
+ /** Initialize the computer. */
+ Completable initialize();
+
+ /** Cleanup resources. */
+ Completable close();
+
+ /** Returns the environment. */
+ Single environment();
+}
diff --git a/core/src/main/java/com/google/adk/tools/computeruse/ComputerEnvironment.java b/core/src/main/java/com/google/adk/tools/computeruse/ComputerEnvironment.java
new file mode 100644
index 000000000..2c897c794
--- /dev/null
+++ b/core/src/main/java/com/google/adk/tools/computeruse/ComputerEnvironment.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.adk.tools.computeruse;
+
+/** Enum for computer environments. */
+public enum ComputerEnvironment {
+ ENVIRONMENT_UNSPECIFIED,
+ ENVIRONMENT_BROWSER
+}
diff --git a/core/src/main/java/com/google/adk/tools/computeruse/ComputerState.java b/core/src/main/java/com/google/adk/tools/computeruse/ComputerState.java
new file mode 100644
index 000000000..4f3be46c2
--- /dev/null
+++ b/core/src/main/java/com/google/adk/tools/computeruse/ComputerState.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.adk.tools.computeruse;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.errorprone.annotations.CanIgnoreReturnValue;
+import java.util.Arrays;
+import java.util.Objects;
+import java.util.Optional;
+
+/**
+ * Represents the current state of the computer environment.
+ *
+ * Attributes: screenshot: The screenshot in PNG format as bytes. url: The current URL of the
+ * webpage being displayed.
+ */
+public final class ComputerState {
+ private final byte[] screenshot;
+ private final Optional url;
+
+ @JsonCreator
+ private ComputerState(
+ @JsonProperty("screenshot") byte[] screenshot, @JsonProperty("url") Optional url) {
+ this.screenshot = screenshot.clone();
+ this.url = url;
+ }
+
+ @JsonProperty("screenshot")
+ public byte[] screenshot() {
+ return screenshot.clone();
+ }
+
+ @JsonProperty("url")
+ public Optional url() {
+ return url;
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ /** Builder for {@link ComputerState}. */
+ public static final class Builder {
+ private byte[] screenshot;
+ private Optional url = Optional.empty();
+
+ @CanIgnoreReturnValue
+ public Builder screenshot(byte[] screenshot) {
+ this.screenshot = screenshot.clone();
+ return this;
+ }
+
+ @CanIgnoreReturnValue
+ public Builder url(Optional url) {
+ this.url = url;
+ return this;
+ }
+
+ @CanIgnoreReturnValue
+ public Builder url(String url) {
+ this.url = Optional.ofNullable(url);
+ return this;
+ }
+
+ public ComputerState build() {
+ return new ComputerState(screenshot, url);
+ }
+ }
+
+ public static ComputerState create(byte[] screenshot, String url) {
+ return builder().screenshot(screenshot).url(url).build();
+ }
+
+ public static ComputerState create(byte[] screenshot) {
+ return builder().screenshot(screenshot).build();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof ComputerState that)) {
+ return false;
+ }
+ return Objects.deepEquals(screenshot, that.screenshot) && Objects.equals(url, that.url);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(Arrays.hashCode(screenshot), url);
+ }
+}
diff --git a/core/src/main/java/com/google/adk/tools/computeruse/ComputerUseTool.java b/core/src/main/java/com/google/adk/tools/computeruse/ComputerUseTool.java
new file mode 100644
index 000000000..cedf7f35c
--- /dev/null
+++ b/core/src/main/java/com/google/adk/tools/computeruse/ComputerUseTool.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.adk.tools.computeruse;
+
+import static java.lang.String.format;
+
+import com.google.adk.tools.FunctionTool;
+import com.google.adk.tools.ToolContext;
+import com.google.common.collect.ImmutableMap;
+import io.reactivex.rxjava3.core.Single;
+import java.lang.reflect.Method;
+import java.util.Base64;
+import java.util.HashMap;
+import java.util.Map;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A tool that wraps computer control functions for use with LLMs.
+ *
+ * This tool automatically normalizes coordinates from a virtual coordinate space (by default
+ * 1000x1000) to the actual screen size.
+ */
+public class ComputerUseTool extends FunctionTool {
+
+ private static final Logger logger = LoggerFactory.getLogger(ComputerUseTool.class);
+
+ private final int[] screenSize;
+ private final int[] coordinateSpace;
+
+ public ComputerUseTool(Object instance, Method func, int[] screenSize, int[] virtualScreenSize) {
+ super(instance, func, /* isLongRunning= */ false);
+ this.screenSize = screenSize;
+ this.coordinateSpace = virtualScreenSize;
+ }
+
+ private int normalize(Object object, String coordinateName, int index) {
+ if (!(object instanceof Number number)) {
+ throw new IllegalArgumentException(format("%s coordinate must be numeric", coordinateName));
+ }
+ double coordinate = number.doubleValue();
+ int normalized = (int) (coordinate / coordinateSpace[index] * screenSize[index]);
+ // Clamp to screen bounds
+ int clamped = Math.max(0, Math.min(normalized, screenSize[index] - 1));
+ logger.atDebug().log(
+ format(
+ "%s: %.2f, normalized %s: %d, screen %s size: %d, coordinate-space %s size: %d, "
+ + "clamped %s: %d",
+ coordinateName,
+ coordinate,
+ coordinateName,
+ normalized,
+ coordinateName,
+ screenSize[index],
+ coordinateName,
+ coordinateSpace[index],
+ coordinateName,
+ clamped));
+ return clamped;
+ }
+
+ private int normalizeX(Object xObj) {
+ return normalize(xObj, "x", 0);
+ }
+
+ private int normalizeY(Object yObj) {
+ return normalize(yObj, "y", 1);
+ }
+
+ @Override
+ public Single