Skip to content
Merged
Show file tree
Hide file tree
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
9 changes: 6 additions & 3 deletions cmd/cmds.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@ package cmd

import (
"fmt"
"github.com/alecthomas/kong"
"github.com/netapp/ontap-mcp/config"
"github.com/netapp/ontap-mcp/server"
"log/slog"
"os"
"path/filepath"
"strings"

"github.com/alecthomas/kong"
"github.com/netapp/ontap-mcp/config"
"github.com/netapp/ontap-mcp/server"
)

var logger = setupLogger()
Expand All @@ -29,6 +30,7 @@ type StartCmd struct {
Port int `default:"8080" help:"Listening port" env:"ONTAP_MCP_PORT"`
InspectTraffic bool `default:"false" help:"Inspect MCP HTTP traffic"`
ReadOnly bool `default:"false" help:"Run MCP in read-only mode. This disables all tool calls that modify ONTAP state."`
Stateless bool `default:"false" help:"Run in stateless mode (no mcp-session-id header validation). Required when deploying behind proxies or gateways that don't preserve session headers, e.g. on-premises data gateways."`
}

func (a *StartCmd) Run(cli *CLI) error {
Expand All @@ -47,6 +49,7 @@ func (a *StartCmd) Run(cli *CLI) error {
Port: cli.Start.Port,
InspectTraffic: cli.Start.InspectTraffic,
ReadOnly: cli.Start.ReadOnly,
Stateless: cli.Start.Stateless,
}

app := server.NewApp(cfg, opts, logger)
Expand Down
8 changes: 8 additions & 0 deletions docs/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,14 @@ docker run --rm ghcr.io/netapp/ontap-mcp:latest start --help

This displays all available environment variables with descriptions, authentication options, and advanced settings.

Some commonly used flags:

| Flag | Description |
|---|---|
| `--read-only` | Disable all mutating operations. Only read-only tools are registered. |
| `--stateless` | Disable mcp-session-id header validation. Required when deploying behind proxies or gateways that do not preserve session headers, e.g. on-premises data gateways. |
| `--inspect-traffic` | Log all MCP HTTP request and response bodies for debugging. |

## Next Steps

- Explore [Prepare ONTAP](prepare-ontap.md)
Expand Down
4 changes: 3 additions & 1 deletion docs/tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ ONTAP MCP provides a set of tools that can be used to interact with the ONTAP AP

All ONTAP MCP tools are annotated with hint metadata: `readOnlyHint`, `idempotentHint`, and `destructiveHint`. The `readOnlyHint` indicates that the tool does not modify any data and is safe to use for discovery and information retrieval. The `destructiveHint` indicates that the tool performs actions that can modify or delete data, and should be used with caution.

If you want to run the ONTAP MCP server in read-only mode, you can start the server with the `--read-only` flag. In this mode, only tools with the `readOnlyHint` will be available for use, ensuring that no modifications can be made to the ONTAP cluster. See the [configuration documentation](install.md#configuration) for more details on how to start the server in read-only mode.
If you want to run the ONTAP MCP server in read-only mode, you can start the server with the `--read-only` flag. In this mode, only tools with the `readOnlyHint` will be available for use, ensuring that no modifications can be made to the ONTAP cluster.

To run without mcp-session-id header validation (e.g. behind proxies that strip session headers), use the `--stateless` flag. See the [configuration documentation](install.md#configuration) for more details.

## API Discovery

Expand Down
6 changes: 5 additions & 1 deletion server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ type Options struct {
IsTest bool
Port int
ReadOnly bool
Stateless bool
TestHTTPClient *http.Client // Optional HTTP client for testing
}

Expand Down Expand Up @@ -78,6 +79,9 @@ func (a *App) StartServer() {
if a.options.ReadOnly {
a.logger.Info("MCP server is running in read-only mode; mutating operations are disabled")
}
if a.options.Stateless {
a.logger.Info("MCP server is running in stateless mode; mcp-session-id header validation is disabled")
}
server := a.createMCPServer()
a.runHTTPServer(server)
}
Expand Down Expand Up @@ -239,7 +243,7 @@ func (a *App) runHTTPServer(server *mcp.Server) {

handler = mcp.NewStreamableHTTPHandler(func(*http.Request) *mcp.Server {
return server
}, nil)
}, &mcp.StreamableHTTPOptions{Stateless: a.options.Stateless})

if a.options.InspectTraffic {
prevHandler := handler
Expand Down
Loading