Skip to content

regenrek/oplink-mcp

Repository files navigation

Oplink

Oplink Logo

Create your own no-code workflows with MCP apps. Oplink combines multiple MCP servers into unified workflows that you define in simple YAML files.

Why Oplink?

🚀 No-code agent workflows — create your own agent workflows with just editing yaml files
🧩 One endpoint, many servers — bundle any MCP Server like Chrome DevTools, shadcn, Context7, etc. behind a single MCP server entry.
🛡️ Guided prompts & schemas — every workflow exposes typed parameters, instructions, and curated helper tools.
💾 Context-efficient discoverymcporter caches tool schemas in-memory, so agents discover tools via describe_tools without flooding your MCP client with dozens of external commands. Only your curated workflows appear in the tool list.
🧠 Works in any MCP client — Cursor, Claude Code, Codex, Windsurf, and friends can run complex flows without custom glue code.

Imagine you're debugging a frontend issue and need to:

  • Chrome DevTools to inspect the browser, capture screenshots, and analyze network requests
  • shadcn to understand component APIs and get the latest library documentation

Example

Without Oplink, you'd need to manually coordinate between multiple MCP servers, switching contexts and piecing together results. With Oplink, you define a single frontend_debugging workflow that orchestrates both servers in one call.

Overview

Oplink transforms YAML-based workflow definitions into executable MCP tools. Unlike tools that only reference tool names in prompts, Oplink can actually execute external MCP tools that you wire in via a lightweight registry (.mcp-workflows/servers.json).

Oplink combines multiple MCP servers into unified workflows. Define prompts and tool sequences in YAML, wire in external MCP servers via a simple registry, and expose everything as a single MCP tool that works in any MCP client (Cursor, Claude, Windsurf, etc.).

Example: Frontend Debugging Workflow

frontend_debugging:
  description: "Debug frontend issues using Chrome DevTools and shadcn components"
  prompt: |
    Analyze the reported issue systematically.
    Use Chrome DevTools to inspect the browser state and capture diagnostics.
    Reference shadcn component documentation to understand the UI library.
  externalServers:
    - chrome-devtools
    - shadcn

One workflow, multiple servers, seamless execution. That's why Oplink exists.

Installation

npx -y oplink@latest init

Cursor Configuration

{
  "mcpServers": {
    "oplink-get-docs": {
      "command": "npx",
      "args": [
        "oplink@latest",
        "server",
        "--config",
        "examples/deepwiki-demo/.mcp-workflows"
      ]
    },
    "oplink-frontend-debugging": {
      "command": "npx",
      "args": [
        "oplink@latest",
        "server",
        "--config",
        "examples/frontend-mcp-demo/.mcp-workflows"
      ],
      "env": {
        "FRONTEND_ROOT": "/path/to/oplink/examples/frontend-mcp-demo"
      }
    }
  }
}

Custom Configuration

{
  "mcpServers": {
    "oplink": {
      "command": "npx",
      "args": [
        "oplink@latest",
        "server",
        "--config",
        "/path/to/.mcp-workflows"
      ]
    }
  }
}

Configuration

Create a .mcp-workflows directory and add YAML workflow files:

debug_workflow:
  description: "Debug application issues"
  prompt: |
    Analyze the issue systematically.
    Gather logs and error information.
  externalServers:
    - your-server-alias

MCP Server Registry

External tools are resolved through .mcp-workflows/servers.json. Each entry maps a friendly alias to an MCP server definition (stdio command or HTTP endpoint). Use ${ENV_VAR} placeholders for secrets. When you run with --config <dir>, Oplink auto‑loads .env files from that directory before expanding placeholders (precedence: shell > .env.{NODE_ENV}.local > .env.{NODE_ENV} > .env.local > .env). You do not need a mcporter.json for Oplink to run.

{
  "servers": {
    "context7": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@upstash/context7-mcp"],
      "env": { "CONTEXT7_TOKEN": "${CONTEXT7_TOKEN}" }
    },
    "grafana": {
      "type": "http",
      "url": "https://grafana.example.com/mcp",
      "headers": { "Authorization": "Bearer ${GRAFANA_TOKEN}" }
    }
  }
}

The alias (context7, grafana, etc.) becomes the server prefix when you reference an external tool inside a scripted workflow step (for example, chrome-devtools:take_screenshot). Startup fails if an alias referenced in your workflows is missing, the registry is malformed, or an environment placeholder cannot be resolved.

See examples/context7-demo/ (Context7) and examples/deepwiki-demo/ (DeepWiki) for ready-to-run setups that wire real MCP servers into Oplink via this registry + workflow pair.

Auto Workflows (zero config)

To expose an MCP server without writing custom steps, declare a workflow with externalServers. Oplink now exposes one tool per workflow and ships a built-in describe_tools helper so agents can dynamically discover the proxied commands. The recommended flow is:

  1. Call describe_tools({ "workflow": "frontend_debugger" }) to retrieve the cached catalog (names, descriptions, JSON schemas, last refresh time).
  2. Pick a tool from the response and invoke the workflow with { "tool": "name", "args": { ... } }.

Every auto workflow prompt automatically appends a reminder to run describe_tools first, so you don't have to mention it manually—though you can still customize the prompt text if you want to provide extra context.

frontend_debugger:
  description: "Chrome DevTools helper"
  prompt: |
    Use Chrome DevTools MCP tools (e.g., take_screenshot, list_network_requests).
    Provide {"tool": "name", "args": { ... }} when calling this workflow.
  externalServers:
    - chrome-devtools

shadcn_helper:
  description: "shadcn helper"
  prompt: |
    Use shadcn MCP tools to list/search components.
  externalServers:
    - shadcn

full_helper:
  description: "Chrome DevTools + shadcn"
  prompt: |
    Access Chrome DevTools and shadcn MCP tools from one workflow.
  externalServers:
    - chrome-devtools
    - shadcn

Call the workflow with:

  • tool: the tool name (e.g., take_screenshot or chrome-devtools:take_screenshot).
  • server: optional unless you configured multiple aliases (like full_helper) and didn’t prefix the tool.
  • args: arguments object forwarded to the MCP tool.
describe_tools({
  "workflow": "frontend_debugger"
})

frontend_debugger({
  "tool": "take_screenshot",
  "args": {
    "url": "https://example.com",
    "format": "png"
  }
})

describe_tools accepts optional filters such as aliases, search, limit, and refresh. Set refresh: true if you need to force a re-discovery after changing the upstream MCP server. Use auto workflows for quick wiring, then switch to scripted workflows (below) when you need curated flows, defaults, or multi-step orchestration.

Optional per-tool proxies

By default, Oplink keeps the MCP surface limited to your workflows plus helper utilities (describe_tools, external_auth_setup). If you want to expose every external MCP tool as its own MCP tool (e.g., deepwiki.read_wiki_structure) you can opt in by setting OPLINK_AUTO_REGISTER_EXTERNAL_TOOLS=1 before starting the server (or by passing autoRegisterExternalTools: true when calling createMcpServer). This is mainly useful for debugging or when a client cannot call describe_tools. Similarly, the oplink_info helper is only registered when OPLINK_INFO_TOOL=1 (or includeInfoTool: true) for troubleshooting builds.

Scripted Workflow Steps

Modern Oplink workflows run entirely on the server: you declare the external steps to execute, and the MCP client only sees the high-level tool (e.g., frontend_debugger). Each step references an external MCP tool using the alias:tool format from servers.json and can template arguments from workflow parameters.

take_screenshot:
  description: "Capture screenshots for docs or testing"
  runtime: scripted
  parameters:
    url:
      type: string
      required: true
    wait_for:
      type: string
      description: "Optional text to wait for"
    format:
      type: string
      enum: [png, jpeg, webp]
      default: png
  steps:
    - call: chrome-devtools:navigate_page
      args:
        type: url
        url: "{{ url }}"
        ignoreCache: false
    - call: chrome-devtools:wait_for
      requires: wait_for
      args:
        text: "{{ wait_for }}"
        timeout: 10000
    - call: chrome-devtools:take_screenshot
      args:
        fullPage: true
        format: "{{ format }}"
  • runtime: scripted tells Oplink to execute these steps server-side via mcporter.
  • requires skips the step unless the named parameter (or saved value) is truthy.
  • Arguments can use {{ paramName }} templating.
  • Only the workflow tool (take_screenshot) is exposed to the MCP client; the chrome-devtools helpers stay internal.
  • Defaulted parameters like format keep the happy path simple (no extra args) while allowing overrides when you need a different image type.
  • Add quiet: true to a step if you don't want the runner to emit "Step X" logs for that call (useful for screenshot steps that already return binary content).

Prompt-Only Workflows

For simple workflows that only need a prompt without external tool execution, you can use parameter injection:

thinking_mode:
  description: "Reflect on thoughts"
  parameters:
    thought:
      type: "string"
      description: "The thought to reflect upon"
      required: true
    context:
      type: "string"
      description: "Additional context"
  prompt: |
    Deeply reflect upon: {{ thought }}
    Consider this context: {{ context }}
    Analyze implications and tradeoffs.

Examples

The repository includes example configurations under examples/ showing both prompt-only and scripted workflows. Use these as references when creating your own YAML in .mcp-workflows/.

External Tool Integration

Oplink uses mcporter under the hood to connect to external MCP servers, but it reads the registry from .mcp-workflows/servers.json in your chosen --config directory.

  1. Define servers in .mcp-workflows/servers.json (see the examples above)
  2. Reference tools as server:tool inside scripted workflow steps
  3. Only the workflow tools themselves are exposed to the MCP client; helper tools remain internal

Tool Call Flow:

MCP Client → Oplink → mcporter Runtime → External MCP Server → Result

External tools are discovered at startup, cached with schema hashes, and exposed through the describe_tools helper instead of flooding the MCP client with dozens of proxied commands. The cache automatically refreshes when it expires, and you can trigger a manual refresh by calling describe_tools({ "workflow": "name", "refresh": true }) if the upstream server changes.

See also:

  • Advanced: How Oplink Uses mcporter → docs/oplink-docs/content/5.advanced/3-mcporter.md
  • Advanced: Auth for External MCP Servers (API Key, OAuth) → docs/oplink-docs/content/5.advanced/4-authentication.md

Connecting to hosted MCP servers (OAuth)

Hosted providers like Linear expose MCP servers over HTTPS/SSE and expect an OAuth flow. mcporter 0.5+ already handles the browser/device dance, so you just need one config entry per server:

"linear": {
  "type": "stdio",
  "command": "npx",
  "args": ["-y", "mcp-remote", "https://mcp.linear.app/mcp"],
  "auth": "oauth",
  "clientName": "oplink-linear-demo",
  "oauthRedirectUrl": "http://127.0.0.1:43115/callback",
  "tokenCacheDir": "./.tokens/linear",
  "env": {
    "MCP_REMOTE_CLIENT_ID": "${LINEAR_CLIENT_ID}",
    "MCP_REMOTE_CLIENT_SECRET": "${LINEAR_CLIENT_SECRET}"
  }
}

Notes:

  1. type: "stdio" + npx mcp-remote lets Oplink spawn the hosted server even though it lives on HTTPS.
  2. mcporter caches refresh tokens under tokenCacheDir, so the OAuth prompt only happens once.
  3. Skip the client ID/secret prompts if you prefer dynamic registration—mcporter will open a browser during the first tool call.
  4. Run pnpm bootstrap:linear to copy the example config and (optionally) inject your credentials into examples/linear-discord-demo/.mcp-workflows/servers.json.

To inspect the tools exposed by any alias, reuse the same config directory:

npx mcporter list linear --config examples/linear-discord-demo/.mcp-workflows

For Discord in the demo, export `DISCORD_BOT_TOKEN` in your shell; Oplink maps it to `DISCORD_TOKEN` for the MCP server defined in `examples/linear-discord-demo/.mcp-workflows/servers.json`.

Requirements

  • Node.js 18+ or 20+
  • Optional: mcporter CLI for local inspection (npx mcporter list <alias> --config path/to/.mcp-workflows)
  • MCP client (Cursor, Claude Desktop, etc.)

Troubleshooting

  • Missing FRONTEND_ROOT (shadcn): set export FRONTEND_ROOT=$(pwd)/examples/frontend-mcp-demo or set it under your MCP client entry's env block.
  • Chrome won’t launch: ensure Chrome is installed and starts locally. For remote/debugging Chrome, launch it separately and update the Chrome DevTools server flags per its docs.
  • No tools appear: confirm --config points to the intended .mcp-workflows directory and your IDE picked up the MCP server entry.
  • Tool catalog looks stale: run describe_tools({ "workflow": "name", "refresh": true }) to force a re-discovery after changing the upstream MCP server.

Development

# Install dependencies
pnpm install

# Build packages
pnpm build

# Run tests
pnpm test

# Start development server
cd packages/oplink
pnpm dev

Definition

Oplink is an MCP server that orchestrates workflows by combining prompts with external MCP tool execution. It bridges your workflow definitions with mcporter-configured MCP servers, enabling automatic tool discovery and execution.

Credits

License

MIT

Repository

https://github.com/instructa/oplink

  • Chrome DevTools screenshot errors: if a workflow calls chrome-devtools:take_screenshot without specifying format, DevTools rejects the request. The provided examples set a default (png) and let you override it via the format/screenshot_format parameter.

About

easy workflows for mcp tools

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors