flipped-aurora/gin-vue-admin · error

缺少MCP鉴权请求头: %s

Error message

缺少MCP鉴权请求头: %s

What it means

doUpstream requires an auth token extracted from the request context (authTokenFromContext); when the configured auth header's token is empty it refuses to call upstream. This prevents unauthenticated requests to the GVA main service.

Source

Thrown at server/mcp/http_client.go:157

	return &result, nil
}

func getUpstream[T any](ctx context.Context, endpoint string, query url.Values) (*upstreamEnvelope[T], error) {
	return doUpstream[T](ctx, http.MethodGet, endpoint, query, nil)
}

func postUpstream[T any](ctx context.Context, endpoint string, body any) (*upstreamEnvelope[T], error) {
	return doUpstream[T](ctx, http.MethodPost, endpoint, nil, body)
}

func deleteUpstream[T any](ctx context.Context, endpoint string, body any) (*upstreamEnvelope[T], error) {
	return doUpstream[T](ctx, http.MethodDelete, endpoint, nil, body)
}

func doUpstream[T any](ctx context.Context, method, endpoint string, query url.Values, body any) (*upstreamEnvelope[T], error) {
	token := authTokenFromContext(ctx)
	if token == "" {
		return nil, fmt.Errorf("缺少MCP鉴权请求头: %s", configuredAuthHeader())
	}

	endpoint = strings.TrimSpace(endpoint)
	if endpoint == "" {
		return nil, fmt.Errorf("上游接口路径不能为空")
	}
	if !strings.HasPrefix(endpoint, "/") {
		endpoint = "/" + endpoint
	}

	baseURL := upstreamBaseURL()
	requestURL, err := url.Parse(baseURL + endpoint)
	if err != nil {
		return nil, fmt.Errorf("构建上游请求地址失败: %w", err)
	}
	if len(query) > 0 {
		requestURL.RawQuery = query.Encode()
	}

View on GitHub (pinned to 3136500ef3)

Solutions

  1. Ensure the AI client sends the configured auth header with a valid token on every MCP request
  2. Confirm configuredAuthHeader() matches what clients actually send (check env/config)
  3. Verify the MCP auth middleware stores the token in the request context before tool handlers run
  4. If calling from non-HTTP code paths, inject a valid token into the context explicitly

Example fix

// before
token := authTokenFromContext(ctx)
if token == "" {
	return nil, fmt.Errorf("缺少MCP鉴权请求头: %s", configuredAuthHeader())
}
// after (caller side check)
func callTool(ctx context.Context) error {
	if authTokenFromContext(ctx) == "" {
		return fmt.Errorf("callTool: context missing %s token", configuredAuthHeader())
	}
	_, err := getUpstream[SomeData](ctx, "/api/target", nil)
	return err
}
Defensive patterns

Strategy: validation

Validate before calling

func ensureAuthToken(ctx context.Context) error {
	if authTokenFromContext(ctx) == "" {
		return fmt.Errorf("request is missing %s header", configuredAuthHeader())
	}
	return nil
}

Type guard

func hasAuthToken(ctx context.Context) bool {
	return authTokenFromContext(ctx) != ""
}

Try / catch

result, err := getUpstream[Data](ctx, "/api/x", nil)
if err != nil {
	if strings.Contains(err.Error(), "缺少MCP鉴权请求头") {
		// return 401-style guidance to the AI client
	}
	return err
}

Prevention

When it happens

Trigger: MCP request arrived without the configured auth header (e.g. x-api-key / Authorization); token was set on the wrong header name; context value never populated by the MCP auth middleware before calling getUpstream/postUpstream/deleteUpstream.

Common situations: AI client misconfigured and not sending the MCP auth header; configuredAuthHeader() (env/config) changed while clients still send the old header name; calling upstream helpers outside the authenticated MCP handler flow (e.g. from a background task with a bare context.Context).

Related errors


AI-assisted analysis of flipped-aurora/gin-vue-admin@3136500ef3 (2026-08-31). Data as JSON: /api/errors/a3607b3b198a8a44. Report an issue: GitHub.