# How to Create and Register MCP Server Plugins in Reasonix

> Learn to create and register MCP server plugins in Reasonix. Implement MCP metadata interfaces, register tools, and expose bindings for seamless integration.

- Repository: [YHH/DeepSeek-Reasonix](https://github.com/esengine/DeepSeek-Reasonix)
- Tags: how-to-guide
- Published: 2026-08-08

---

**To create and register MCP server plugins in Reasonix, implement the MCP metadata interfaces in your Go type, register the tool using `tool.Register()` in an `init` function, and expose the binding through the session store's `ConfigureToolBindings` hook.**

Reasonix supports Model-Controlled Plugin (MCP) servers that extend AI capabilities through external tools. Creating an MCP server plugin requires implementing specific metadata interfaces defined in the `internal/tool` package and registering your tool with the central registry. This guide walks through the exact implementation steps using the DeepSeek-Reasonix source code.

## Implementing MCP Metadata Interfaces

Every MCP server plugin must satisfy the interface requirements defined in [`internal/tool/tool.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/tool/tool.go). These interfaces provide the metadata necessary for Reasonix to generate portable tool bindings and capability identifiers.

### Required Interface Methods

Your tool type must implement the **`MCPMetadata`** interface, which defines two essential methods:

- **`MCPServerName() string`** – Returns the logical server name (e.g., `"myserver"`).
- **`MCPRawToolName() string`** – Returns the raw tool identifier (e.g., `"do_something"`).

### Optional Metadata Methods

For enhanced visibility and package management, implement these optional interfaces:

- **`MCPVisibleMetadata`** – Provides **`MCPVisibleToolName() string`** for user-facing display names.
- **`MCPPackageMetadata`** – Provides **`MCPPackageName() string`** to identify the plugin package for alias generation.

Example implementation skeleton:

```go
package myplugin

import "github.com/esengine/DeepSeek-Reasonix/internal/tool"

type DoSomething struct{}

func (DoSomething) MCPServerName() string      { return "myserver" }
func (DoSomething) MCPRawToolName() string     { return "do_something" }
func (DoSomething) MCPVisibleToolName() string { return "Do Something" }
func (DoSomething) MCPPackageName() string     { return "myplugin" }

```

## Registering Tools with the Global Registry

After defining your tool, register it with Reasonix’s global registry located in [`internal/tool/registry.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/tool/registry.go). The registry creates canonical callable names and maintains the mapping between portable references and concrete implementations.

### The Registration Flow

1. **Call `tool.Register()`** – Pass your tool instance to this function inside your package's `init()` function.
2. **Canonical Name Generation** – The registry constructs the callable name using the pattern:

   ```

   mcp__<server>__<tool>
   ```

   For the example above, this generates `mcp__myserver__do_something`.

3. **Alias Creation** – The registry automatically generates compatibility aliases using the `MCPBindingAliases` function. These follow the pattern:

   ```

   mcp__plugin_<package>_<server>__<tool>
   ```

   If your package is `"myplugin"`, the alias becomes `mcp__plugin_myplugin_myserver__do_something`.

Registration code:

```go
func init() {
    tool.Register(DoSomething{})
}

```

The `Register` method in [`internal/tool/registry.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/tool/registry.go) inserts the tool into the global `Registry` and builds the `MCPBinding` record containing the server name, raw name, visible name, callable name, capability ID, and package identifier.

## Exposing Plugins to the Runtime Session

To make registered tools available during a Reasonix session, you must configure the tool bindings in the skill store. The store implementation in [`internal/skill/skill.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/skill/skill.go) manages the runtime exposure of MCP capabilities.

### Configuring Tool Bindings

Use the **`ConfigureToolBindings`** hook on the `skill.Store` to inject your MCP bindings into the session resolver. This function should return a slice of `tool.MCPBinding` structures that match your registered tools.

Example configuration:

```go
store.ConfigureToolBindings(func(sk skill.Skill) []tool.MCPBinding {
    return []tool.MCPBinding{
        {
            Server:       "myserver",
            RawName:      "do_something",
            VisibleName:  "Do Something",
            CallableName: "mcp__myserver__do_something",
            CapabilityID: "mcp-tool:myserver/do_something",
            Package:      "myplugin",
        },
    }
})

```

### Runtime MCP Tool Bindings Section

When a skill is prepared, the `Store.Prepare` method writes a "## Runtime MCP tool bindings" section into the skill body. This section lists the concrete callable names and capability IDs, enabling the model to resolve short references to authoritative binding records. The model can then invoke tools using either the direct callable name (`mcp__myserver__do_something`) or the stable capability ID (`mcp-tool:myserver/do_something`).

## Complete Implementation Example

Here is a complete, runnable example combining all three stages:

```go
// myplugin/tool.go
package myplugin

import (
    "github.com/esengine/DeepSeek-Reasonix/internal/tool"
)

type DoSomething struct{}

func (DoSomething) MCPServerName() string      { return "myserver" }
func (DoSomething) MCPRawToolName() string     { return "do_something" }
func (DoSomething) MCPVisibleToolName() string { return "Do Something" }
func (DoSomething) MCPPackageName() string     { return "myplugin" }

func init() {
    tool.Register(DoSomething{})
}

```

```go
// main.go
package main

import (
    "github.com/esengine/DeepSeek-Reasonix/internal/skill"
    "github.com/esengine/DeepSeek-Reasonix/internal/tool"
    _ "github.com/esengine/DeepSeek-Reasonix/myplugin" // Import for side effects
)

func main() {
    store := skill.NewStore()
    
    store.ConfigureToolBindings(func(sk skill.Skill) []tool.MCPBinding {
        return []tool.MCPBinding{
            {
                Server:       "myserver",
                RawName:      "do_something",
                VisibleName:  "Do Something",
                CallableName: "mcp__myserver__do_something",
                CapabilityID: "mcp-tool:myserver/do_something",
                Package:      "myplugin",
            },
        }
    })
    
    // Continue with session initialization...
}

```

When the model issues `use_tool "mcp__myserver__do_something"`, Reasonix resolves the call through the registry, invokes the `DoSomething` implementation, and returns the result.

## Summary

- **Implement metadata interfaces** – Satisfy `MCPMetadata` (required) and optionally `MCPVisibleMetadata` and `MCPPackageMetadata` in [`internal/tool/tool.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/tool/tool.go).
- **Register during initialization** – Call `tool.Register()` inside your package's `init()` function to add the tool to the global registry in [`internal/tool/registry.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/tool/registry.go).
- **Generate canonical names** – The registry automatically creates callable names (`mcp__<server>__<tool>`) and package aliases.
- **Expose via session store** – Use `ConfigureToolBindings` in [`internal/skill/skill.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/skill/skill.go) to make tools available to the model runtime.
- **Runtime resolution** – The skill body includes a "## Runtime MCP tool bindings" section mapping portable names to concrete tool implementations.

## Frequently Asked Questions

### What is the difference between the callable name and the capability ID in Reasonix MCP plugins?

The **callable name** (e.g., `mcp__myserver__do_something`) is the direct function reference the model uses to invoke the tool, while the **capability ID** (e.g., `mcp-tool:myserver/do_something`) provides a stable, URI-style identifier for capability-based invocation systems. Both resolve to the same tool implementation through the registry.

### Where does Reasonix store the global tool registry?

The global tool registry is implemented in [`internal/tool/registry.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/tool/registry.go) as the `Registry` variable. This centralized store maintains all registered MCP tools and generates the `MCPBinding` structures that connect server names and tool names to their concrete Go implementations.

### Can I register multiple tools from the same MCP server package?

Yes. You can define multiple types in the same package, each implementing the metadata interfaces with the same `MCPServerName()` return value but different `MCPRawToolName()` values. Register each type in the same `init()` function or separate `init()` functions within the package; the registry in [`internal/tool/registry.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/tool/registry.go) handles multiple registrations from the same source.

### How does Reasonix handle tool name collisions between different MCP server plugins?

The registry constructs unique callable names using the pattern `mcp__<server>__<tool>`, which namespaces tools by their server name. If two different packages register tools with identical server and tool names, the later registration will overwrite the earlier one in the global registry. To avoid collisions, use distinct server names or leverage the `MCPPackageMetadata` interface to generate unique aliases via `MCPBindingAliases`.