Repository: dgraph-io/dgraph
File: dgraph/cmd/mcp/mcp_server.go (Go)

Code before:
			ReadOnlyHint:    &True,
			DestructiveHint: &False,
			IdempotentHint:  &True,
			OpenWorldHint:   &False,
		}),
	)

	if !readOnly {
		alterSchemaTool := mcp.NewTool("alter_schema",
			mcp.WithDescription("Alter Dgraph DQL Schema in dgraph db"),
			mcp.WithString("schema",
				mcp.Required(),
				mcp.Description("Updated schema to insert inside the db"),
			),
			mcp.WithToolAnnotation(mcp.ToolAnnotation{
				ReadOnlyHint:    &False,
				DestructiveHint: &True,
				IdempotentHint:  &False,
				OpenWorldHint:   &False,
			}),
		)

		s.AddTool(alterSchemaTool, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
			schema, ok := request.GetArguments()["schema"].(string)
			if !ok {
				return mcp.NewToolResultError("Schema must be present"), nil
			}

			// Execute alter operation
			conn, err := getConn(connectionString)
			if err != nil {
				return mcp.NewToolResultErrorFromErr("Error opening connection with Dgraph Alpha", err), nil
			}
			if err = conn.SetSchema(ctx, dgo.RootNamespace, schema); err != nil {
				return mcp.NewToolResultErrorFromErr("Schema alteration failed", err), nil
			}

			return mcp.NewToolResultText("Schema updated successfully"), nil
		})

		mutationTool := mcp.NewTool("run_mutation",
			mcp.WithDescription("Run DQL Mutation on dgraph db"),
			mcp.WithString("mutation",
				mcp.Required(),
				mcp.Description("The mutation to perform in json format"),
			),
			mcp.WithToolAnnotation(mcp.ToolAnnotation{
				ReadOnlyHint:    &False,
				DestructiveHint: &True,
				IdempotentHint:  &False,
				OpenWorldHint:   &False,

Review comment (suggestion):
Handling errors via mcp.NewToolResultError is the correct mode. If we return an `err`, the SSE server internals will return a 500 server error.

Code after:
			ReadOnlyHint:    &True,
			DestructiveHint: &False,
			IdempotentHint:  &True,
			OpenWorldHint:   &False,
		}),
	)

	if !readOnly {
		alterSchemaTool := mcp.NewTool("alter_schema",
			mcp.WithDescription("Alter Dgraph DQL Schema in dgraph db"),
			mcp.WithString("schema",
				mcp.Required(),
				mcp.Description("Updated schema to insert inside the db"),
			),
			mcp.WithToolAnnotation(mcp.ToolAnnotation{
				ReadOnlyHint:    &False,
				DestructiveHint: &True,
				IdempotentHint:  &False,
				OpenWorldHint:   &False,
			}),
		)

		s.AddTool(alterSchemaTool, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
			args := request.GetArguments()
			if args == nil {
				return mcp.NewToolResultError("Schema must be present"), nil
			}

			schemaArg, ok := args["schema"]
			if !ok || schemaArg == nil {
				return mcp.NewToolResultError("Schema must be present"), nil
			}

			schema, ok := schemaArg.(string)
			if !ok {
				return mcp.NewToolResultError("Schema must be a string"), nil
			}

			// Execute alter operation
			conn, err := getConn(connectionString)
			if err != nil {
				return mcp.NewToolResultErrorFromErr("Error opening connection with Dgraph Alpha", err), nil
			}
			if err = conn.SetSchema(ctx, dgo.RootNamespace, schema); err != nil {
				return mcp.NewToolResultErrorFromErr("Schema alteration failed", err), nil
			}

			return mcp.NewToolResultText("Schema updated successfully"), nil
		})

		mutationTool := mcp.NewTool("run_mutation",