mirror of
https://github.com/tiennm99/goclaw.git
synced 2026-10-11 12:18:59 +00:00
fix(mcp): use json.RawMessage for JSONB fields to prevent base64 serialization (#25)
[]byte fields were base64-encoded during JSON serialization, causing frontend TypeError when calling .join() on non-array values. Added Array.isArray() guards in UI as defensive fallback.
This commit is contained in:
1 parent
27f73cde6a
commit
b07159894d
4 files changed
+20
-19
No files matched your search
@@ -176,8 +176,8 @@ func (h *MCPHandler) handleGrantAgent(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
var req struct {
|
||||
AgentID string `json:"agent_id"`
|
||||
ToolAllow []byte `json:"tool_allow,omitempty"`
|
||||
ToolDeny []byte `json:"tool_deny,omitempty"`
|
||||
ToolAllow json.RawMessage `json:"tool_allow,omitempty"`
|
||||
ToolDeny json.RawMessage `json:"tool_deny,omitempty"`
|
||||
}
|
||||
if err := json.NewDecoder(http.MaxBytesReader(w, r.Body, 1<<20)).Decode(&req); err != nil {
|
||||
writeJSON(w, http.StatusBadRequest, map[string]string{"error": "invalid JSON"})
|
||||
@@ -258,8 +258,8 @@ func (h *MCPHandler) handleGrantUser(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
var req struct {
|
||||
UserID string `json:"user_id"`
|
||||
ToolAllow []byte `json:"tool_allow,omitempty"`
|
||||
ToolDeny []byte `json:"tool_deny,omitempty"`
|
||||
ToolAllow json.RawMessage `json:"tool_allow,omitempty"`
|
||||
ToolDeny json.RawMessage `json:"tool_deny,omitempty"`
|
||||
}
|
||||
if err := json.NewDecoder(http.MaxBytesReader(w, r.Body, 1<<20)).Decode(&req); err != nil {
|
||||
writeJSON(w, http.StatusBadRequest, map[string]string{"error": "invalid JSON"})
|
||||
|
||||
+13
-12
@@ -2,6 +2,7 @@ package store
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
@@ -14,14 +15,14 @@ type MCPServerData struct {
|
||||
DisplayName string `json:"display_name,omitempty"`
|
||||
Transport string `json:"transport"` // "stdio", "sse", "streamable-http"
|
||||
Command string `json:"command,omitempty"` // stdio
|
||||
Args []byte `json:"args,omitempty"` // JSONB
|
||||
Args json.RawMessage `json:"args,omitempty"` // JSONB
|
||||
URL string `json:"url,omitempty"` // sse/http
|
||||
Headers []byte `json:"headers,omitempty"` // JSONB
|
||||
Env []byte `json:"env,omitempty"` // JSONB (stdio)
|
||||
Headers json.RawMessage `json:"headers,omitempty"` // JSONB
|
||||
Env json.RawMessage `json:"env,omitempty"` // JSONB (stdio)
|
||||
APIKey string `json:"api_key,omitempty"` // encrypted
|
||||
ToolPrefix string `json:"tool_prefix,omitempty"`
|
||||
TimeoutSec int `json:"timeout_sec"`
|
||||
Settings []byte `json:"settings,omitempty"` // JSONB
|
||||
Settings json.RawMessage `json:"settings,omitempty"` // JSONB
|
||||
Enabled bool `json:"enabled"`
|
||||
CreatedBy string `json:"created_by"`
|
||||
}
|
||||
@@ -32,9 +33,9 @@ type MCPAgentGrant struct {
|
||||
ServerID uuid.UUID `json:"server_id"`
|
||||
AgentID uuid.UUID `json:"agent_id"`
|
||||
Enabled bool `json:"enabled"`
|
||||
ToolAllow []byte `json:"tool_allow,omitempty"` // JSONB
|
||||
ToolDeny []byte `json:"tool_deny,omitempty"` // JSONB
|
||||
ConfigOverrides []byte `json:"config_overrides,omitempty"` // JSONB
|
||||
ToolAllow json.RawMessage `json:"tool_allow,omitempty"` // JSONB
|
||||
ToolDeny json.RawMessage `json:"tool_deny,omitempty"` // JSONB
|
||||
ConfigOverrides json.RawMessage `json:"config_overrides,omitempty"` // JSONB
|
||||
GrantedBy string `json:"granted_by"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
}
|
||||
@@ -45,10 +46,10 @@ type MCPUserGrant struct {
|
||||
ServerID uuid.UUID `json:"server_id"`
|
||||
UserID string `json:"user_id"`
|
||||
Enabled bool `json:"enabled"`
|
||||
ToolAllow []byte `json:"tool_allow,omitempty"` // JSONB
|
||||
ToolDeny []byte `json:"tool_deny,omitempty"` // JSONB
|
||||
GrantedBy string `json:"granted_by"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
ToolAllow json.RawMessage `json:"tool_allow,omitempty"` // JSONB
|
||||
ToolDeny json.RawMessage `json:"tool_deny,omitempty"` // JSONB
|
||||
GrantedBy string `json:"granted_by"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
// MCPAccessRequest represents a request for MCP server access.
|
||||
@@ -60,7 +61,7 @@ type MCPAccessRequest struct {
|
||||
Scope string `json:"scope"` // "agent" or "user"
|
||||
Status string `json:"status"` // "pending", "approved", "rejected"
|
||||
Reason string `json:"reason,omitempty"`
|
||||
ToolAllow []byte `json:"tool_allow,omitempty"` // JSONB
|
||||
ToolAllow json.RawMessage `json:"tool_allow,omitempty"` // JSONB
|
||||
RequestedBy string `json:"requested_by"`
|
||||
ReviewedBy string `json:"reviewed_by,omitempty"`
|
||||
ReviewedAt *time.Time `json:"reviewed_at,omitempty"`
|
||||
|
||||
@@ -46,7 +46,7 @@ export function MCPFormDialog({ open, onOpenChange, server, onSubmit }: MCPFormD
|
||||
setDisplayName(server?.display_name ?? "");
|
||||
setTransport(server?.transport ?? "stdio");
|
||||
setCommand(server?.command ?? "");
|
||||
setArgs(server?.args?.join(", ") ?? "");
|
||||
setArgs(Array.isArray(server?.args) ? server.args.join(", ") : "");
|
||||
setUrl(server?.url ?? "");
|
||||
setHeaders(server?.headers ? JSON.stringify(server.headers, null, 2) : "");
|
||||
setToolPrefix(server?.tool_prefix ?? "");
|
||||
|
||||
@@ -107,10 +107,10 @@ export function MCPGrantsDialog({
|
||||
<div key={grant.id} className="flex items-center justify-between border-b px-3 py-2 last:border-0">
|
||||
<div className="flex items-center gap-2">
|
||||
<Badge variant="outline" className="font-mono text-xs">{grant.agent_id}</Badge>
|
||||
{grant.tool_allow && (
|
||||
{Array.isArray(grant.tool_allow) && grant.tool_allow.length > 0 && (
|
||||
<span className="text-xs text-muted-foreground">allow: {grant.tool_allow.join(", ")}</span>
|
||||
)}
|
||||
{grant.tool_deny && (
|
||||
{Array.isArray(grant.tool_deny) && grant.tool_deny.length > 0 && (
|
||||
<span className="text-xs text-muted-foreground">deny: {grant.tool_deny.join(", ")}</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in new issue
Block a user