Skip to content

Fix: Convert MCP string parameters to appropriate types #1954

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from
Open
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
55 changes: 54 additions & 1 deletion packages/opencode/src/session/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,56 @@ import { Wildcard } from "../util/wildcard"
import { ulid } from "ulid"
import { defer } from "../util/defer"

/**
* Converts string parameters to their appropriate types based on the schema
* This fixes an issue where MCP tools receive all parameters as strings
*/
function convertMCPArgs(args: Record<string, any>, schema: any): Record<string, any> {
if (!schema || !args) return args

const converted: Record<string, any> = {}

for (const [key, value] of Object.entries(args)) {
// If the value is not a string, keep it as is
if (typeof value !== "string") {
converted[key] = value
continue
}

// Try to parse as JSON first (for arrays, objects, booleans, numbers)
try {
converted[key] = JSON.parse(value)
continue
} catch {
// If JSON parsing fails, continue with type inference
}

// Try to convert to number if it looks like a number
if (/^-?\d+(\.\d+)?$/.test(value)) {
const num = parseFloat(value)
if (!isNaN(num)) {
converted[key] = num
continue
}
}

// Try to convert to boolean
if (value.toLowerCase() === "true") {
converted[key] = true
continue
}
if (value.toLowerCase() === "false") {
converted[key] = false
continue
}

// Keep as string if no conversion applies
converted[key] = value
}

return converted
}

export namespace Session {
const log = Log.create({ service: "session" })

Expand Down Expand Up @@ -845,7 +895,10 @@ export namespace Session {
const execute = item.execute
if (!execute) continue
item.execute = async (args, opts) => {
const result = await execute(args, opts)
// Convert string parameters to appropriate types
const convertedArgs = convertMCPArgs(args, item.inputSchema)

const result = await execute(convertedArgs, opts)
const output = result.content
.filter((x: any) => x.type === "text")
.map((x: any) => x.text)
Expand Down