@olib-ai/owl-browser-mcp 1.0.1 → 1.0.3

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.
Files changed (2) hide show
  1. package/dist/index.js +56 -1
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -22297,6 +22297,10 @@ var openapi_default = {
22297
22297
  selector: {
22298
22298
  type: "string",
22299
22299
  description: "CSS selector or natural language description for the element to capture. Required when mode is 'element'. Examples: 'div.profile', '#submit-btn', 'the login form'"
22300
+ },
22301
+ scale: {
22302
+ type: "integer",
22303
+ description: "Scale percentage for the output image (1-100). Default is 100 (no scaling). Example: 50 will return an image at 50% of the original size (half width and height)."
22300
22304
  }
22301
22305
  },
22302
22306
  required: [
@@ -26793,6 +26797,7 @@ var openapi_default = {
26793
26797
  var API_ENDPOINT = process.env.OWL_API_ENDPOINT || "http://127.0.0.1:8080";
26794
26798
  var API_TOKEN = process.env.OWL_API_TOKEN || "";
26795
26799
  var activeContexts = /* @__PURE__ */ new Map();
26800
+ var toolIntegerFields = /* @__PURE__ */ new Map();
26796
26801
  function convertOpenAPIToMCPTools(schema) {
26797
26802
  const tools = [];
26798
26803
  for (const [path, pathItem] of Object.entries(schema.paths)) {
@@ -26806,6 +26811,7 @@ function convertOpenAPIToMCPTools(schema) {
26806
26811
  };
26807
26812
  if (requestSchema?.properties) {
26808
26813
  const properties = {};
26814
+ const integerFields = /* @__PURE__ */ new Set();
26809
26815
  for (const [propName, propDef] of Object.entries(requestSchema.properties)) {
26810
26816
  const prop = {};
26811
26817
  if (propDef.type === "string") {
@@ -26817,6 +26823,9 @@ function convertOpenAPIToMCPTools(schema) {
26817
26823
  prop.type = "boolean";
26818
26824
  } else if (propDef.type === "number" || propDef.type === "integer") {
26819
26825
  prop.type = "number";
26826
+ if (propDef.type === "integer") {
26827
+ integerFields.add(propName);
26828
+ }
26820
26829
  } else if (propDef.type === "array") {
26821
26830
  prop.type = "array";
26822
26831
  if (propDef.items) {
@@ -26834,6 +26843,9 @@ function convertOpenAPIToMCPTools(schema) {
26834
26843
  properties[propName] = prop;
26835
26844
  }
26836
26845
  inputSchema.properties = properties;
26846
+ if (integerFields.size > 0) {
26847
+ toolIntegerFields.set(toolName, integerFields);
26848
+ }
26837
26849
  }
26838
26850
  if (requestSchema?.required && requestSchema.required.length > 0) {
26839
26851
  inputSchema.required = requestSchema.required;
@@ -26846,6 +26858,19 @@ function convertOpenAPIToMCPTools(schema) {
26846
26858
  }
26847
26859
  return tools;
26848
26860
  }
26861
+ function coerceIntegerFields(toolName, args) {
26862
+ const integerFields = toolIntegerFields.get(toolName);
26863
+ if (!integerFields || integerFields.size === 0) {
26864
+ return args;
26865
+ }
26866
+ const coerced = { ...args };
26867
+ for (const field of integerFields) {
26868
+ if (field in coerced && typeof coerced[field] === "number") {
26869
+ coerced[field] = Math.round(coerced[field]);
26870
+ }
26871
+ }
26872
+ return coerced;
26873
+ }
26849
26874
  async function callBrowserAPI(toolName, args) {
26850
26875
  const url2 = `${API_ENDPOINT}/api/execute/${toolName}`;
26851
26876
  const headers = {
@@ -26854,11 +26879,12 @@ async function callBrowserAPI(toolName, args) {
26854
26879
  if (API_TOKEN) {
26855
26880
  headers["Authorization"] = `Bearer ${API_TOKEN}`;
26856
26881
  }
26882
+ const coercedArgs = coerceIntegerFields(toolName, args);
26857
26883
  try {
26858
26884
  const response = await fetch(url2, {
26859
26885
  method: "POST",
26860
26886
  headers,
26861
- body: JSON.stringify(args)
26887
+ body: JSON.stringify(coercedArgs)
26862
26888
  });
26863
26889
  const contentType = response.headers.get("content-type") || "";
26864
26890
  let data;
@@ -26917,6 +26943,35 @@ function formatResponse(toolName, result) {
26917
26943
  };
26918
26944
  }
26919
26945
  const data = result.data;
26946
+ const isImageTool = toolName === "browser_screenshot" || toolName === "browser_get_live_frame";
26947
+ if (isImageTool) {
26948
+ let base64Data = null;
26949
+ if (typeof data === "object" && data !== null) {
26950
+ const dataObj = data;
26951
+ if (typeof dataObj.result === "string") {
26952
+ base64Data = dataObj.result;
26953
+ } else if (typeof dataObj.success === "boolean" && typeof dataObj.result === "string") {
26954
+ base64Data = dataObj.result;
26955
+ }
26956
+ } else if (typeof data === "string") {
26957
+ base64Data = data;
26958
+ }
26959
+ if (base64Data) {
26960
+ if (base64Data.startsWith("data:image/")) {
26961
+ const [, actualBase64] = base64Data.split(",");
26962
+ base64Data = actualBase64;
26963
+ }
26964
+ return {
26965
+ content: [
26966
+ {
26967
+ type: "image",
26968
+ data: base64Data,
26969
+ mimeType: "image/png"
26970
+ }
26971
+ ]
26972
+ };
26973
+ }
26974
+ }
26920
26975
  if (typeof data === "object" && data !== null && "image" in data) {
26921
26976
  const imageData = data.image;
26922
26977
  if (imageData.startsWith("data:image/")) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@olib-ai/owl-browser-mcp",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "MCP server for Owl Browser HTTP API - 144 browser automation tools with anti-detection",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",