github.com/anthropics/anthropic-sdk-go@v1.70.1/betatunnel.go (about)

     1  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
     2  
     3  package anthropic
     4  
     5  import (
     6  	"context"
     7  	"errors"
     8  	"fmt"
     9  	"net/http"
    10  	"net/url"
    11  	"slices"
    12  	"time"
    13  
    14  	"github.com/anthropics/anthropic-sdk-go/internal/apijson"
    15  	"github.com/anthropics/anthropic-sdk-go/internal/apiquery"
    16  	"github.com/anthropics/anthropic-sdk-go/internal/requestconfig"
    17  	"github.com/anthropics/anthropic-sdk-go/option"
    18  	"github.com/anthropics/anthropic-sdk-go/packages/pagination"
    19  	"github.com/anthropics/anthropic-sdk-go/packages/param"
    20  	"github.com/anthropics/anthropic-sdk-go/packages/respjson"
    21  	"github.com/anthropics/anthropic-sdk-go/shared/constant"
    22  )
    23  
    24  // BetaTunnelService contains methods and other services that help with interacting
    25  // with the anthropic API.
    26  //
    27  // Note, unlike clients, this service does not read variables from the environment
    28  // automatically. You should not instantiate this service directly, and instead use
    29  // the [NewBetaTunnelService] method instead.
    30  type BetaTunnelService struct {
    31  	Options      []option.RequestOption
    32  	Certificates BetaTunnelCertificateService
    33  }
    34  
    35  // NewBetaTunnelService generates a new service that applies the given options to
    36  // each request. These options are applied after the parent client's options (if
    37  // there is one), and before any request-specific options.
    38  func NewBetaTunnelService(opts ...option.RequestOption) (r BetaTunnelService) {
    39  	r = BetaTunnelService{}
    40  	r.Options = opts
    41  	r.Certificates = NewBetaTunnelCertificateService(opts...)
    42  	return
    43  }
    44  
    45  // The Tunnels API is in research preview. It requires the
    46  // `anthropic-beta: mcp-tunnels-2026-06-22` header and may change without a
    47  // deprecation period. It supersedes the Admin API endpoints at
    48  // `/v1/organizations/tunnels`, which remain available during a migration window.
    49  //
    50  // Creates a tunnel. Creation allocates a fresh hostname and provisions the tunnel;
    51  // it is not idempotent. The new tunnel rejects MCP traffic until at least one CA
    52  // certificate is added.
    53  func (r *BetaTunnelService) New(ctx context.Context, params BetaTunnelNewParams, opts ...option.RequestOption) (res *BetaTunnel, err error) {
    54  	for _, v := range params.Betas {
    55  		opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v)))
    56  	}
    57  	if !param.IsOmitted(params.WorkspaceID) {
    58  		opts = append(opts, option.WithHeader("anthropic-workspace-id", fmt.Sprintf("%v", params.WorkspaceID.Value)))
    59  	}
    60  	opts = slices.Concat(r.Options, opts)
    61  	opts = append([]option.RequestOption{option.WithHeader("anthropic-beta", "mcp-tunnels-2026-06-22")}, opts...)
    62  	path := "v1/tunnels?beta=true"
    63  	err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, params, &res, opts...)
    64  	return res, err
    65  }
    66  
    67  // The Tunnels API is in research preview. It requires the
    68  // `anthropic-beta: mcp-tunnels-2026-06-22` header and may change without a
    69  // deprecation period. It supersedes the Admin API endpoints at
    70  // `/v1/organizations/tunnels`, which remain available during a migration window.
    71  //
    72  // Fetches a tunnel by ID.
    73  func (r *BetaTunnelService) Get(ctx context.Context, tunnelID string, query BetaTunnelGetParams, opts ...option.RequestOption) (res *BetaTunnel, err error) {
    74  	for _, v := range query.Betas {
    75  		opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v)))
    76  	}
    77  	if !param.IsOmitted(query.WorkspaceID) {
    78  		opts = append(opts, option.WithHeader("anthropic-workspace-id", fmt.Sprintf("%v", query.WorkspaceID.Value)))
    79  	}
    80  	opts = slices.Concat(r.Options, opts)
    81  	opts = append([]option.RequestOption{option.WithHeader("anthropic-beta", "mcp-tunnels-2026-06-22")}, opts...)
    82  	if tunnelID == "" {
    83  		err = errors.New("missing required tunnel_id parameter")
    84  		return nil, err
    85  	}
    86  	path := fmt.Sprintf("v1/tunnels/%s?beta=true", tunnelID)
    87  	err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &res, opts...)
    88  	return res, err
    89  }
    90  
    91  // The Tunnels API is in research preview. It requires the
    92  // `anthropic-beta: mcp-tunnels-2026-06-22` header and may change without a
    93  // deprecation period. It supersedes the Admin API endpoints at
    94  // `/v1/organizations/tunnels`, which remain available during a migration window.
    95  //
    96  // Lists tunnels. Results are ordered by creation time, newest first; archived
    97  // tunnels are excluded unless include_archived is set.
    98  func (r *BetaTunnelService) List(ctx context.Context, params BetaTunnelListParams, opts ...option.RequestOption) (res *pagination.PageCursor[BetaTunnel], err error) {
    99  	var raw *http.Response
   100  	for _, v := range params.Betas {
   101  		opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v)))
   102  	}
   103  	if !param.IsOmitted(params.WorkspaceID) {
   104  		opts = append(opts, option.WithHeader("anthropic-workspace-id", fmt.Sprintf("%v", params.WorkspaceID.Value)))
   105  	}
   106  	opts = slices.Concat(r.Options, opts)
   107  	opts = append([]option.RequestOption{option.WithHeader("anthropic-beta", "mcp-tunnels-2026-06-22"), option.WithResponseInto(&raw)}, opts...)
   108  	path := "v1/tunnels?beta=true"
   109  	cfg, err := requestconfig.NewRequestConfig(ctx, http.MethodGet, path, params, &res, opts...)
   110  	if err != nil {
   111  		return nil, err
   112  	}
   113  	err = cfg.Execute()
   114  	if err != nil {
   115  		return nil, err
   116  	}
   117  	res.SetPageConfig(cfg, raw)
   118  	return res, nil
   119  }
   120  
   121  // The Tunnels API is in research preview. It requires the
   122  // `anthropic-beta: mcp-tunnels-2026-06-22` header and may change without a
   123  // deprecation period. It supersedes the Admin API endpoints at
   124  // `/v1/organizations/tunnels`, which remain available during a migration window.
   125  //
   126  // Lists tunnels. Results are ordered by creation time, newest first; archived
   127  // tunnels are excluded unless include_archived is set.
   128  func (r *BetaTunnelService) ListAutoPaging(ctx context.Context, params BetaTunnelListParams, opts ...option.RequestOption) *pagination.PageCursorAutoPager[BetaTunnel] {
   129  	return pagination.NewPageCursorAutoPager(r.List(ctx, params, opts...))
   130  }
   131  
   132  // The Tunnels API is in research preview. It requires the
   133  // `anthropic-beta: mcp-tunnels-2026-06-22` header and may change without a
   134  // deprecation period. It supersedes the Admin API endpoints at
   135  // `/v1/organizations/tunnels`, which remain available during a migration window.
   136  //
   137  // Archives a tunnel. Archival is irreversible: every non-archived certificate on
   138  // the tunnel is archived in the same operation, the hostname is retired and never
   139  // re-allocated, and the tunnel token is invalidated. Retrying against an
   140  // already-archived tunnel returns the existing record unchanged.
   141  func (r *BetaTunnelService) Archive(ctx context.Context, tunnelID string, body BetaTunnelArchiveParams, opts ...option.RequestOption) (res *BetaTunnel, err error) {
   142  	for _, v := range body.Betas {
   143  		opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v)))
   144  	}
   145  	if !param.IsOmitted(body.WorkspaceID) {
   146  		opts = append(opts, option.WithHeader("anthropic-workspace-id", fmt.Sprintf("%v", body.WorkspaceID.Value)))
   147  	}
   148  	opts = slices.Concat(r.Options, opts)
   149  	opts = append([]option.RequestOption{option.WithHeader("anthropic-beta", "mcp-tunnels-2026-06-22")}, opts...)
   150  	if tunnelID == "" {
   151  		err = errors.New("missing required tunnel_id parameter")
   152  		return nil, err
   153  	}
   154  	path := fmt.Sprintf("v1/tunnels/%s/archive?beta=true", tunnelID)
   155  	err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, nil, &res, opts...)
   156  	return res, err
   157  }
   158  
   159  // The Tunnels API is in research preview. It requires the
   160  // `anthropic-beta: mcp-tunnels-2026-06-22` header and may change without a
   161  // deprecation period. It supersedes the Admin API endpoints at
   162  // `/v1/organizations/tunnels`, which remain available during a migration window.
   163  //
   164  // Reveals a tunnel's connector token. The value is fetched live on each call;
   165  // Anthropic does not store it. Repeated calls return the same value until the
   166  // token is rotated. Exposed as POST so the token does not appear in intermediary
   167  // access logs.
   168  func (r *BetaTunnelService) RevealToken(ctx context.Context, tunnelID string, body BetaTunnelRevealTokenParams, opts ...option.RequestOption) (res *BetaTunnelToken, err error) {
   169  	for _, v := range body.Betas {
   170  		opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v)))
   171  	}
   172  	if !param.IsOmitted(body.WorkspaceID) {
   173  		opts = append(opts, option.WithHeader("anthropic-workspace-id", fmt.Sprintf("%v", body.WorkspaceID.Value)))
   174  	}
   175  	opts = slices.Concat(r.Options, opts)
   176  	opts = append([]option.RequestOption{option.WithHeader("anthropic-beta", "mcp-tunnels-2026-06-22")}, opts...)
   177  	if tunnelID == "" {
   178  		err = errors.New("missing required tunnel_id parameter")
   179  		return nil, err
   180  	}
   181  	path := fmt.Sprintf("v1/tunnels/%s/reveal_token?beta=true", tunnelID)
   182  	err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, nil, &res, opts...)
   183  	return res, err
   184  }
   185  
   186  // The Tunnels API is in research preview. It requires the
   187  // `anthropic-beta: mcp-tunnels-2026-06-22` header and may change without a
   188  // deprecation period. It supersedes the Admin API endpoints at
   189  // `/v1/organizations/tunnels`, which remain available during a migration window.
   190  //
   191  // Rotates a tunnel's connector token. Rotation invalidates the current token for
   192  // new connections and returns a fresh value; established connections are not
   193  // severed. A connector restarted after rotation must use the new value.
   194  func (r *BetaTunnelService) RotateToken(ctx context.Context, tunnelID string, params BetaTunnelRotateTokenParams, opts ...option.RequestOption) (res *BetaTunnelToken, err error) {
   195  	for _, v := range params.Betas {
   196  		opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v)))
   197  	}
   198  	if !param.IsOmitted(params.WorkspaceID) {
   199  		opts = append(opts, option.WithHeader("anthropic-workspace-id", fmt.Sprintf("%v", params.WorkspaceID.Value)))
   200  	}
   201  	opts = slices.Concat(r.Options, opts)
   202  	opts = append([]option.RequestOption{option.WithHeader("anthropic-beta", "mcp-tunnels-2026-06-22")}, opts...)
   203  	if tunnelID == "" {
   204  		err = errors.New("missing required tunnel_id parameter")
   205  		return nil, err
   206  	}
   207  	path := fmt.Sprintf("v1/tunnels/%s/rotate_token?beta=true", tunnelID)
   208  	err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, params, &res, opts...)
   209  	return res, err
   210  }
   211  
   212  // An MCP tunnel.
   213  type BetaTunnel struct {
   214  	// Unique identifier for the tunnel, prefixed with `tnl_`.
   215  	ID string `json:"id" api:"required"`
   216  	// A timestamp in RFC 3339 format
   217  	ArchivedAt time.Time `json:"archived_at" api:"required" format:"date-time"`
   218  	// A timestamp in RFC 3339 format
   219  	CreatedAt time.Time `json:"created_at" api:"required" format:"date-time"`
   220  	// Human-readable name for the tunnel (1-255 characters). Null if unset.
   221  	DisplayName string `json:"display_name" api:"required"`
   222  	// Anthropic-assigned hostname for the tunnel. MCP server URLs whose host is a
   223  	// subdomain of this value are routed through the tunnel. Globally unique and never
   224  	// reused, even after the tunnel is archived.
   225  	Domain string          `json:"domain" api:"required"`
   226  	Type   constant.Tunnel `json:"type" default:"tunnel"`
   227  	// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
   228  	JSON struct {
   229  		ID          respjson.Field
   230  		ArchivedAt  respjson.Field
   231  		CreatedAt   respjson.Field
   232  		DisplayName respjson.Field
   233  		Domain      respjson.Field
   234  		Type        respjson.Field
   235  		ExtraFields map[string]respjson.Field
   236  		raw         string
   237  	} `json:"-"`
   238  }
   239  
   240  // Returns the unmodified JSON received from the API
   241  func (r BetaTunnel) RawJSON() string { return r.JSON.raw }
   242  func (r *BetaTunnel) UnmarshalJSON(data []byte) error {
   243  	return apijson.UnmarshalRoot(data, r)
   244  }
   245  
   246  // A tunnel's connector token.
   247  type BetaTunnelToken struct {
   248  	// Stable identifier for the current token value. Changes when the token is
   249  	// rotated.
   250  	ID string `json:"id" api:"required"`
   251  	// The connector token used to run the tunnel. Treat as a credential.
   252  	TunnelToken string               `json:"tunnel_token" api:"required"`
   253  	Type        constant.TunnelToken `json:"type" default:"tunnel_token"`
   254  	// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
   255  	JSON struct {
   256  		ID          respjson.Field
   257  		TunnelToken respjson.Field
   258  		Type        respjson.Field
   259  		ExtraFields map[string]respjson.Field
   260  		raw         string
   261  	} `json:"-"`
   262  }
   263  
   264  // Returns the unmodified JSON received from the API
   265  func (r BetaTunnelToken) RawJSON() string { return r.JSON.raw }
   266  func (r *BetaTunnelToken) UnmarshalJSON(data []byte) error {
   267  	return apijson.UnmarshalRoot(data, r)
   268  }
   269  
   270  type BetaTunnelNewParams struct {
   271  	// Optional human-readable name for the tunnel (1-255 characters).
   272  	DisplayName param.Opt[string] `json:"display_name,omitzero"`
   273  	WorkspaceID param.Opt[string] `header:"anthropic-workspace-id,omitzero" json:"-"`
   274  	// Optional header to specify the beta version(s) you want to use.
   275  	Betas []AnthropicBeta `header:"anthropic-beta,omitzero" json:"-"`
   276  	paramObj
   277  }
   278  
   279  func (r BetaTunnelNewParams) MarshalJSON() (data []byte, err error) {
   280  	type shadow BetaTunnelNewParams
   281  	return param.MarshalObject(r, (*shadow)(&r))
   282  }
   283  func (r *BetaTunnelNewParams) UnmarshalJSON(data []byte) error {
   284  	return apijson.UnmarshalRoot(data, r)
   285  }
   286  
   287  type BetaTunnelGetParams struct {
   288  	WorkspaceID param.Opt[string] `header:"anthropic-workspace-id,omitzero" json:"-"`
   289  	// Optional header to specify the beta version(s) you want to use.
   290  	Betas []AnthropicBeta `header:"anthropic-beta,omitzero" json:"-"`
   291  	paramObj
   292  }
   293  
   294  type BetaTunnelListParams struct {
   295  	// Whether to include archived tunnels in the results. Defaults to false.
   296  	IncludeArchived param.Opt[bool] `query:"include_archived,omitzero" json:"-"`
   297  	// Maximum number of tunnels to return per page. Defaults to 20, maximum 1000.
   298  	Limit param.Opt[int64] `query:"limit,omitzero" json:"-"`
   299  	// Opaque pagination cursor from a previous `list_tunnels` response.
   300  	Page        param.Opt[string] `query:"page,omitzero" json:"-"`
   301  	WorkspaceID param.Opt[string] `header:"anthropic-workspace-id,omitzero" json:"-"`
   302  	// Optional header to specify the beta version(s) you want to use.
   303  	Betas []AnthropicBeta `header:"anthropic-beta,omitzero" json:"-"`
   304  	paramObj
   305  }
   306  
   307  // URLQuery serializes [BetaTunnelListParams]'s query parameters as `url.Values`.
   308  func (r BetaTunnelListParams) URLQuery() (v url.Values, err error) {
   309  	return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{
   310  		ArrayFormat:  apiquery.ArrayQueryFormatBrackets,
   311  		NestedFormat: apiquery.NestedQueryFormatBrackets,
   312  	})
   313  }
   314  
   315  type BetaTunnelArchiveParams struct {
   316  	WorkspaceID param.Opt[string] `header:"anthropic-workspace-id,omitzero" json:"-"`
   317  	// Optional header to specify the beta version(s) you want to use.
   318  	Betas []AnthropicBeta `header:"anthropic-beta,omitzero" json:"-"`
   319  	paramObj
   320  }
   321  
   322  type BetaTunnelRevealTokenParams struct {
   323  	WorkspaceID param.Opt[string] `header:"anthropic-workspace-id,omitzero" json:"-"`
   324  	// Optional header to specify the beta version(s) you want to use.
   325  	Betas []AnthropicBeta `header:"anthropic-beta,omitzero" json:"-"`
   326  	paramObj
   327  }
   328  
   329  type BetaTunnelRotateTokenParams struct {
   330  	// Optional free-text reason for the rotation, recorded for audit.
   331  	Reason      param.Opt[string] `json:"reason,omitzero"`
   332  	WorkspaceID param.Opt[string] `header:"anthropic-workspace-id,omitzero" json:"-"`
   333  	// Optional header to specify the beta version(s) you want to use.
   334  	Betas []AnthropicBeta `header:"anthropic-beta,omitzero" json:"-"`
   335  	paramObj
   336  }
   337  
   338  func (r BetaTunnelRotateTokenParams) MarshalJSON() (data []byte, err error) {
   339  	type shadow BetaTunnelRotateTokenParams
   340  	return param.MarshalObject(r, (*shadow)(&r))
   341  }
   342  func (r *BetaTunnelRotateTokenParams) UnmarshalJSON(data []byte) error {
   343  	return apijson.UnmarshalRoot(data, r)
   344  }