fix(mcp): require xVerae- commercial key when EDGE_URL set; batch via edge

This commit is contained in:
George Lambert 2026-10-17 00:26:50 -04:00
commit 13d1c5851b
2 changed files with 47 additions and 6 deletions

View file

@ -21,8 +21,8 @@ type Client struct {
Channel string
}
// DefaultBaseURL is the public edge.
const DefaultBaseURL = "https://zap.verae.ai"
// DefaultBaseURL is the public commercial edge (non-Zapier).
const DefaultBaseURL = "https://services.verae.ai"
// FromEnv builds a client when VERAE_MCP_EDGE_URL is set (non-empty).
// Empty env disables edge billing (legacy direct VeraeTime only).

View file

@ -30,6 +30,14 @@ func (d *Deps) resolveBearer(ctx context.Context, req *mcp.CallToolRequest) (str
return authctx.Resolve(ctx, BearerFromRequest(req), d.RequireBearer, d.Keeper)
}
// isCommercialEdgeKey reports tokens that edge apiKeyAuth can map to a prepaid customer.
func isCommercialEdgeKey(tok string) bool {
t := strings.TrimSpace(tok)
return strings.HasPrefix(t, "xVerae-") ||
strings.HasPrefix(t, "key-") ||
strings.HasPrefix(t, "zmw_")
}
func (d *Deps) stamp(ctx context.Context, req *mcp.CallToolRequest, in StampArgs) (*mcp.CallToolResult, ReceiptsOut, error) {
if err := assertDigestArgs(req); err != nil {
return nil, ReceiptsOut{}, err
@ -49,8 +57,15 @@ func (d *Deps) stamp(ctx context.Context, req *mcp.CallToolRequest, in StampArgs
if err != nil {
return nil, ReceiptsOut{}, err
}
// Single commercial meter: when Edge is configured, bill via zap.verae.ai.
// Single commercial meter: when Edge is configured, bill via services.verae.ai.
// Caller must present a commercial key (xVerae- / key- / zmw_), not a bare chain JWT,
// so settleStampBilling attributes the customer prepaid ledger.
if d.Edge != nil {
if !isCommercialEdgeKey(tok) {
return nil, ReceiptsOut{}, fmt.Errorf(
"commercial stamp requires portal API key (xVerae-… or key-…); get one at https://customer.verae.ai/portal/ — bare VeraeTime JWT is not billed on MCP when VERAE_MCP_EDGE_URL is set",
)
}
if len(in.Metadata) > 0 || in.Restamp {
return nil, ReceiptsOut{}, fmt.Errorf("metadata/restamp on edge-billed stamps is not supported yet; omit metadata or unset VERAE_MCP_EDGE_URL")
}
@ -121,13 +136,39 @@ func (d *Deps) stampBatch(ctx context.Context, req *mcp.CallToolRequest, in Stam
}
switch scope {
case "global":
if d.Global == nil {
return nil, StampBatchOut{}, fmt.Errorf("global VeraeTime client not configured")
}
tok, err := d.writeBearer(ctx, req)
if err != nil {
return nil, StampBatchOut{}, err
}
// Prefer edge meter (per-digest) when configured — same prepaid path as single stamp.
if d.Edge != nil {
if !isCommercialEdgeKey(tok) {
return nil, StampBatchOut{}, fmt.Errorf(
"commercial stamp requires portal API key (xVerae-… or key-…); get one at https://customer.verae.ai/portal/",
)
}
if len(in.Metadata) > 0 || in.Restamp {
return nil, StampBatchOut{}, fmt.Errorf("metadata/restamp on edge-billed batch not supported yet")
}
out := StampBatchOut{Count: len(in.SHA256s)}
for i, h := range in.SHA256s {
it := BatchItemDTO{Index: i, Hash: h, Status: "submitted"}
er, err := d.Edge.Stamp(ctx, h, tok)
if err != nil {
it.Status, it.Error = "failed", err.Error()
out.Failed++
} else {
it.ReceiptID = er.ReceiptID
it.Status = "completed"
out.Created++
}
out.Items = append(out.Items, it)
}
return nil, out, nil
}
if d.Global == nil {
return nil, StampBatchOut{}, fmt.Errorf("global VeraeTime client not configured")
}
var metas []veraetime.StampMeta
if len(in.Metadata) > 0 || in.Restamp {
if len(in.Metadata) > 0 && len(in.Metadata) != len(in.SHA256s) {