Custom tools don't receive project directory in ToolContext #7499

Closed
opened 2026-02-16 18:07:21 -05:00 by yindo · 2 comments
Owner

Originally created by @rickbassham on GitHub (Jan 24, 2026).

Originally assigned to: @thdxr on GitHub.

Description

Custom tools defined via @opencode-ai/plugin have no way to access the project's working directory at execution time. The ToolContext passed to execute() contains sessionID, messageID, agent, abort, callID, extra, metadata(), and ask() - but no directory or worktree.

This works fine when running opencode directly in a project directory (where process.cwd() happens to be correct), but fails when using opencode web as a daemon serving multiple projects.

Steps to reproduce

  1. Run opencode web as a daemon (e.g., via launchd with a fixed WorkingDirectory)
  2. Create a custom tool that needs the project directory:
    import { tool } from "@opencode-ai/plugin";
    
    export default tool({
      description: "Get git status",
      args: {},
      async execute(args, context) {
        // context has no directory property
        // process.cwd() returns the daemon's cwd, not the project
        const result = await Bun.$`git status`.text();
        return result;
      },
    });
    
  3. Open a project in the web UI and invoke the tool
  4. The tool runs in the wrong directory

Debug output

Logging the full context and environment from a custom tool shows:

{
  "context": {
    "sessionID": "ses_...",
    "messageID": "msg_...",
    "agent": "build",
    "callID": "toolu_...",
    "extra": { "model": {...} },
    "allKeys": ["sessionID", "abort", "messageID", "callID", "extra", "agent", "metadata", "ask"]
  },
  "cwd": "/Users/rick",
  "env": {
    "OPENCODE": "1",
    "HOME": "/Users/rick"
  }
}

Note: cwd is the daemon's working directory, not the project. No directory in context, no OPENCODE_DIRECTORY env var.

Expected behavior

Custom tools should receive directory and worktree in ToolContext, matching what plugins receive in PluginInput at initialization:

export type ToolContext = {
  sessionID: string
  messageID: string
  agent: string
  abort: AbortSignal
  directory: string    // <- add this
  worktree: string     // <- add this
  // ...
}

Workaround

None currently. Built-in tools work because they import Instance.directory directly, but custom tools can't access that module.

OpenCode version

1.0.x (current dev branch)

Operating System

macOS (but applies to any OS when running as daemon)

Originally created by @rickbassham on GitHub (Jan 24, 2026). Originally assigned to: @thdxr on GitHub. ### Description Custom tools defined via `@opencode-ai/plugin` have no way to access the project's working directory at execution time. The `ToolContext` passed to `execute()` contains `sessionID`, `messageID`, `agent`, `abort`, `callID`, `extra`, `metadata()`, and `ask()` - but no `directory` or `worktree`. This works fine when running `opencode` directly in a project directory (where `process.cwd()` happens to be correct), but fails when using `opencode web` as a daemon serving multiple projects. ### Steps to reproduce 1. Run `opencode web` as a daemon (e.g., via launchd with a fixed `WorkingDirectory`) 2. Create a custom tool that needs the project directory: ```typescript import { tool } from "@opencode-ai/plugin"; export default tool({ description: "Get git status", args: {}, async execute(args, context) { // context has no directory property // process.cwd() returns the daemon's cwd, not the project const result = await Bun.$`git status`.text(); return result; }, }); ``` 3. Open a project in the web UI and invoke the tool 4. The tool runs in the wrong directory ### Debug output Logging the full context and environment from a custom tool shows: ```json { "context": { "sessionID": "ses_...", "messageID": "msg_...", "agent": "build", "callID": "toolu_...", "extra": { "model": {...} }, "allKeys": ["sessionID", "abort", "messageID", "callID", "extra", "agent", "metadata", "ask"] }, "cwd": "/Users/rick", "env": { "OPENCODE": "1", "HOME": "/Users/rick" } } ``` Note: `cwd` is the daemon's working directory, not the project. No `directory` in context, no `OPENCODE_DIRECTORY` env var. ### Expected behavior Custom tools should receive `directory` and `worktree` in `ToolContext`, matching what plugins receive in `PluginInput` at initialization: ```typescript export type ToolContext = { sessionID: string messageID: string agent: string abort: AbortSignal directory: string // <- add this worktree: string // <- add this // ... } ``` ### Workaround None currently. Built-in tools work because they import `Instance.directory` directly, but custom tools can't access that module. ### OpenCode version 1.0.x (current dev branch) ### Operating System macOS (but applies to any OS when running as daemon)
yindo closed this issue 2026-02-16 18:07:21 -05:00
Author
Owner

@github-actions[bot] commented on GitHub (Jan 24, 2026):

This issue might be a duplicate of existing issues. Please check:

  • #9077: Can't run tools in OpenCode Desktop - tools executed from / instead of project cwd (same core issue with tools not receiving correct working directory)
  • #6697: Session switching doesn't change working directory context (related issue about working directory context)
  • #9366: Allow sessions to have custom working directories (feature request that would address this issue)

Feel free to ignore if none of these address your specific case.

@github-actions[bot] commented on GitHub (Jan 24, 2026): This issue might be a duplicate of existing issues. Please check: - #9077: Can't run tools in OpenCode Desktop - tools executed from / instead of project cwd (same core issue with tools not receiving correct working directory) - #6697: Session switching doesn't change working directory context (related issue about working directory context) - #9366: Allow sessions to have custom working directories (feature request that would address this issue) Feel free to ignore if none of these address your specific case.
Author
Owner
@adamdotdevin commented on GitHub (Jan 27, 2026): This will be resolved in today's release: https://github.com/anomalyco/opencode/commit/a8c18dba8205d7707a46ec0859db672370be8963 https://github.com/anomalyco/opencode/commit/1f9313847f61978faf3b8459e68386c1d3834b90
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#7499