Skip to content

[FEATURE]: add ensureServer() to PluginInput for plugins that need an HTTP server #31821

Closed as not planned

Description

@Eric-GoodBoy-Tech

Feature hasn't been suggested before.

  • I have verified this feature I'm about to request hasn't been suggested before.

Related issues considered

Describe the enhancement

Add an ensureServer() method to the plugin API (PluginInput):

export type PluginInput = {
  // ... existing fields
  serverUrl: URL
  ensureServer(options?: { port?: number; hostname?: string }): Promise<URL>
}

Problem I hit

I'm building a plugin (oh-my-openagent) that uses tmux to spawn sub-agent panes. Each pane runs opencode attach <url> --session <id>, which needs a real HTTP URL to connect to.

When opencode runs in default TUI mode (no --port), there's no HTTP server listening. The plugin gets ctx.serverUrl = "http://localhost:4096" (a fallback) but opencode attach fails because nothing is actually listening on that port.

I spent hours debugging this — tmux panes were spawning, opencode attach was running, but it kept failing with connection errors. The root cause: the server communicates via in-process RPC, so from opencode's perspective everything works fine, but from a separate process there's no HTTP endpoint to connect to.

The workaround is telling users to add --port 4096, which is unintuitive and poorly documented.

Proposed solution

ensureServer() would let plugins ensure an HTTP server is running:

// In plugin init:
if (ctx.ensureServer) {
    await ctx.ensureServer({ port: 4096 })
}

Implementation would be trivial — Server.listen() already exists in the plugin process, it's just not exposed:

// plugin/index.ts
ensureServer: async (options) => {
    if (Server.url) return Server.url
    await Server.listen({
        port: options?.port ?? 4096,
        hostname: options?.hostname ?? "127.0.0.1",
    })
    return Server.url!
},

Why not just use #9099's env var approach?

#9099 exports the URL but doesn't start a server. A plugin would still need to manually call Server.listen() — which it can't because Server is not part of the plugin API. ensureServer() solves both the discovery and the startup in one call.

Activity

  1. github-actions commented on Jun 11, 2026

    @github-actions
    Contributor

    This issue doesn't fully meet our contributing guidelines.

    What needs to be fixed:

    • The title should start with [FEATURE]: to match the feature request template
    • The feature request template requires a verification checkbox confirming the feature hasn't been suggested before — this is missing from the issue body
    • The issue appears to have been generated by an AI tool; we ask that issues reflect genuine, personal experience with the problem in your own words

    Please edit this issue to address the above within 2 hours, or it will be automatically closed.


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

    • [FEATURE]: Export actual server URL as environment variable #9099: Addresses the same root problem — plugins/child processes receiving a fallback http://localhost:4096 URL when no HTTP server is running, with the same tmux/oh-my-opencode use case

    If you believe this was flagged incorrectly, please let a maintainer know.

  2. changed the title [-]Feature Request: add ensureServer() to PluginInput for plugins requiring HTTP server[/-] [+][FEATURE]: add ensureServer() to PluginInput for plugins that need an HTTP server[/+] on Jun 11, 2026
  3. github-actions commented on Jun 11, 2026

    @github-actions
    Contributor

    Thanks for updating the issue! It now clearly describes the problem you hit, the proposed solution, and why the existing workaround falls short. Everything looks good — appreciate the detail.

  4. github-actions commented on Aug 11, 2026

    @github-actions
    Contributor

    To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions