@datalayer/agent-runtimes 1.3.55 → 1.3.56

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/lib/chat/base/ChatBase.js +8 -3
  2. package/lib/chat/index.d.ts +1 -0
  3. package/lib/chat/index.js +3 -0
  4. package/lib/chat/marks/SpecMark.d.ts +46 -0
  5. package/lib/chat/marks/SpecMark.js +90 -0
  6. package/lib/chat/marks/iconRef.d.ts +29 -0
  7. package/lib/chat/marks/iconRef.js +40 -0
  8. package/lib/chat/marks/index.d.ts +8 -0
  9. package/lib/chat/marks/index.js +12 -0
  10. package/lib/chat/marks/toolMarks.d.ts +43 -0
  11. package/lib/chat/marks/toolMarks.js +110 -0
  12. package/lib/chat/messages/ChatMessageList.d.ts +8 -1
  13. package/lib/chat/messages/ChatMessageList.js +11 -18
  14. package/lib/chat/parts/ToolPart.js +6 -1
  15. package/lib/chat/prompt/InputPrompt.d.ts +4 -1
  16. package/lib/chat/prompt/InputPrompt.js +2 -2
  17. package/lib/chat/prompt/menus/SkillsMenu.js +2 -1
  18. package/lib/chat/prompt/menus/ToolsMenu.d.ts +3 -1
  19. package/lib/chat/prompt/menus/ToolsMenu.js +25 -9
  20. package/lib/chat/tools/ToolCallDisplay.d.ts +8 -1
  21. package/lib/chat/tools/ToolCallDisplay.js +3 -2
  22. package/lib/loop/plugins/chat/ChatView.js +7 -5
  23. package/lib/specs/actions.js +56 -0
  24. package/lib/specs/frontendTools.js +6 -6
  25. package/lib/specs/mcpServers.d.ts +1 -0
  26. package/lib/specs/mcpServers.js +39 -16
  27. package/lib/specs/skills.js +7 -7
  28. package/lib/specs/tools.js +21 -21
  29. package/lib/types/chat.d.ts +4 -0
  30. package/lib/types/mcp.d.ts +2 -2
  31. package/lib/types/skills.d.ts +2 -2
  32. package/lib/types/tools.d.ts +4 -4
  33. package/package.json +1 -1
  34. package/scripts/codegen/agentspecs_clone.py +5 -3
  35. package/scripts/codegen/generate_frontend_tools.py +2 -0
  36. package/scripts/codegen/generate_mcp_servers.py +2 -0
  37. package/scripts/codegen/generate_skills.py +2 -0
  38. package/scripts/codegen/generate_tools.py +2 -0
  39. package/scripts/codegen/marks.py +33 -0
@@ -1,5 +1,5 @@
1
1
  import type { BuiltinTool, MCPServerConfig } from '../../../types';
2
- export declare function ToolsMenu({ codemodeEnabled, onToggleCodemode, mcpServers, enabledMcpTools, enabledMcpToolCount, onToggleMcpTool, onToggleAllMcpServerTools, approvedMcpTools, onToggleMcpToolApproval, availableTools, }: {
2
+ export declare function ToolsMenu({ codemodeEnabled, onToggleCodemode, mcpServers, enabledMcpTools, enabledMcpToolCount, onToggleMcpTool, onToggleAllMcpServerTools, approvedMcpTools, onToggleMcpToolApproval, availableTools, availableFrontendTools, }: {
3
3
  codemodeEnabled: boolean;
4
4
  onToggleCodemode?: (enabled: boolean) => void | Promise<void>;
5
5
  mcpServers: MCPServerConfig[];
@@ -10,4 +10,6 @@ export declare function ToolsMenu({ codemodeEnabled, onToggleCodemode, mcpServer
10
10
  approvedMcpTools: Map<string, Set<string>>;
11
11
  onToggleMcpToolApproval: (serverId: string, toolName: string) => void;
12
12
  availableTools: BuiltinTool[];
13
+ /** The frontend tools: the ones the page runs for the agent. */
14
+ availableFrontendTools?: BuiltinTool[];
13
15
  }): import("react").JSX.Element;
@@ -4,14 +4,20 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
4
4
  * Distributed under the terms of the Modified BSD License.
5
5
  */
6
6
  /**
7
- * What the agent may call: builtin tools, MCP servers, and codemode.
7
+ * What the agent may call: the runtime's tools, the frontend tools (the ones
8
+ * the page runs), MCP servers, and codemode — each drawn with its mark.
8
9
  *
9
10
  * @module chat/prompt/menus/ToolsMenu
10
11
  */
11
12
  import { Text, Button, ActionMenu, ActionList, ToggleSwitch, Tooltip, } from '@primer/react';
12
13
  import { Box } from '@datalayer/primer-addons';
13
14
  import { ToolsIcon } from '@primer/octicons-react';
14
- export function ToolsMenu({ codemodeEnabled, onToggleCodemode, mcpServers, enabledMcpTools, enabledMcpToolCount, onToggleMcpTool, onToggleAllMcpServerTools, approvedMcpTools, onToggleMcpToolApproval, availableTools, }) {
15
+ import { SpecMark, hasMark, marksOfFrontendTool, marksOfMcpServer, marksOfRuntimeTool, } from '../../marks';
16
+ /** A tool's mark, as the leading visual of its row. */
17
+ function LeadingMark({ marks }) {
18
+ return hasMark(marks) ? (_jsx(ActionList.LeadingVisual, { children: _jsx(SpecMark, { icon: marks.icon, emoji: marks.emoji, size: 16 }) })) : null;
19
+ }
20
+ export function ToolsMenu({ codemodeEnabled, onToggleCodemode, mcpServers, enabledMcpTools, enabledMcpToolCount, onToggleMcpTool, onToggleAllMcpServerTools, approvedMcpTools, onToggleMcpToolApproval, availableTools, availableFrontendTools = [], }) {
15
21
  const hasUsableMcpServers = mcpServers.some(server => server.isAvailable);
16
22
  /*
17
23
  * A count, not a word.
@@ -23,12 +29,17 @@ export function ToolsMenu({ codemodeEnabled, onToggleCodemode, mcpServers, enabl
23
29
  */
24
30
  const summary = [
25
31
  `${availableTools.length} tool${availableTools.length === 1 ? '' : 's'}`,
32
+ availableFrontendTools.length > 0
33
+ ? `${availableFrontendTools.length} frontend tool${availableFrontendTools.length === 1 ? '' : 's'}`
34
+ : null,
26
35
  enabledMcpToolCount > 0 ? `${enabledMcpToolCount} MCP enabled` : null,
27
36
  hasUsableMcpServers ? null : 'no MCP server available',
28
37
  ]
29
38
  .filter(Boolean)
30
39
  .join(' · ');
31
- return (_jsxs(ActionMenu, { children: [_jsx(ActionMenu.Anchor, { children: _jsx(Tooltip, { text: `Tools — ${summary}`, direction: "n", children: _jsx(Button, { type: "button", variant: "invisible", size: "small", "aria-label": `Tools — ${summary}`, leadingVisual: ToolsIcon, children: _jsx(Text, { sx: { fontSize: 0 }, children: availableTools.length + enabledMcpToolCount }) }) }) }), _jsx(ActionMenu.Overlay, { side: "outside-top", align: "start", width: "large", children: _jsx(Box, { sx: { maxHeight: '60vh', overflowY: 'auto' }, children: _jsxs(ActionList, { children: [_jsx(ActionList.Group, { title: "Codemode", children: _jsxs(Box, { sx: {
40
+ return (_jsxs(ActionMenu, { children: [_jsx(ActionMenu.Anchor, { children: _jsx(Tooltip, { text: `Tools — ${summary}`, direction: "n", children: _jsx(Button, { type: "button", variant: "invisible", size: "small", "aria-label": `Tools — ${summary}`, leadingVisual: ToolsIcon, children: _jsx(Text, { sx: { fontSize: 0 }, children: availableTools.length +
41
+ availableFrontendTools.length +
42
+ enabledMcpToolCount }) }) }) }), _jsx(ActionMenu.Overlay, { side: "outside-top", align: "start", width: "large", children: _jsx(Box, { sx: { maxHeight: '60vh', overflowY: 'auto' }, children: _jsxs(ActionList, { children: [_jsx(ActionList.Group, { title: "Codemode", children: _jsxs(Box, { sx: {
32
43
  display: 'flex',
33
44
  alignItems: 'center',
34
45
  justifyContent: 'space-between',
@@ -43,12 +54,13 @@ export function ToolsMenu({ codemodeEnabled, onToggleCodemode, mcpServers, enabl
43
54
  if (onToggleCodemode) {
44
55
  void onToggleCodemode(!codemodeEnabled);
45
56
  }
46
- }, "aria-labelledby": "toggle-codemode" })] }) }), availableTools.length > 0 ? (_jsx(ActionList.Group, { title: "Tools", children: availableTools.map(tool => (_jsx(ActionList.Item, { disabled: true, children: tool.name }, tool.id))) })) : null, mcpServers.length > 0 && hasUsableMcpServers ? (mcpServers.map(server => {
57
+ }, "aria-labelledby": "toggle-codemode" })] }) }), availableTools.length > 0 ? (_jsx(ActionList.Group, { title: "Tools", children: availableTools.map(tool => (_jsxs(ActionList.Item, { disabled: true, children: [_jsx(LeadingMark, { marks: marksOfRuntimeTool(tool.name) }), tool.name] }, tool.id))) })) : null, availableFrontendTools.length > 0 ? (_jsx(ActionList.Group, { title: "Frontend tools", children: availableFrontendTools.map(tool => (_jsxs(ActionList.Item, { disabled: true, children: [_jsx(LeadingMark, { marks: marksOfFrontendTool(tool.name) }), tool.name] }, tool.id))) })) : null, mcpServers.length > 0 && hasUsableMcpServers ? (mcpServers.map(server => {
47
58
  const serverTools = enabledMcpTools.get(server.id);
48
59
  const allToolNames = server.tools.map(t => t.name);
49
60
  const enabledCount = serverTools?.size ?? 0;
50
61
  const allEnabled = enabledCount === allToolNames.length &&
51
62
  allToolNames.length > 0;
63
+ const serverMarks = marksOfMcpServer(server);
52
64
  return (_jsxs(ActionList.Group, { title: `${server.name}${server.isAvailable ? '' : ' (unavailable)'}`, children: [server.isAvailable && server.tools.length > 0 && (_jsxs(Box, { sx: {
53
65
  display: 'flex',
54
66
  alignItems: 'center',
@@ -57,11 +69,15 @@ export function ToolsMenu({ codemodeEnabled, onToggleCodemode, mcpServers, enabl
57
69
  py: 2,
58
70
  borderBottom: '1px solid',
59
71
  borderColor: 'border.muted',
60
- }, children: [_jsxs(Text, { id: `toggle-all-${server.id}`, sx: {
61
- fontSize: 0,
62
- fontWeight: 'semibold',
63
- color: 'fg.muted',
64
- }, children: ["Enable all (", enabledCount, "/", allToolNames.length, ")"] }), _jsx(ToggleSwitch, { size: "small", checked: allEnabled, onClick: () => onToggleAllMcpServerTools(server.id, allToolNames, !allEnabled), "aria-labelledby": `toggle-all-${server.id}` })] })), server.isAvailable && server.tools.length > 0 ? (server.tools.map(tool => {
72
+ }, children: [_jsxs(Box, { sx: {
73
+ display: 'flex',
74
+ alignItems: 'center',
75
+ gap: 2,
76
+ }, children: [hasMark(serverMarks) && (_jsx(SpecMark, { icon: serverMarks.icon, emoji: serverMarks.emoji, size: 16 })), _jsxs(Text, { id: `toggle-all-${server.id}`, sx: {
77
+ fontSize: 0,
78
+ fontWeight: 'semibold',
79
+ color: 'fg.muted',
80
+ }, children: ["Enable all (", enabledCount, "/", allToolNames.length, ")"] })] }), _jsx(ToggleSwitch, { size: "small", checked: allEnabled, onClick: () => onToggleAllMcpServerTools(server.id, allToolNames, !allEnabled), "aria-labelledby": `toggle-all-${server.id}` })] })), server.isAvailable && server.tools.length > 0 ? (server.tools.map(tool => {
65
81
  const isEnabled = serverTools?.has(tool.name) ?? false;
66
82
  const serverApproved = approvedMcpTools.get(server.id);
67
83
  // Tools default to NOT approved — user must explicitly
@@ -6,6 +6,7 @@
6
6
  */
7
7
  import React from 'react';
8
8
  import type { CodeError, ExecutionResult, DisplayToolCallStatus } from '../../types';
9
+ import { type Marks } from '../marks';
9
10
  /**
10
11
  * Error type classification for display purposes
11
12
  */
@@ -43,6 +44,12 @@ export interface ToolCallDisplayProps {
43
44
  onDeny?: () => void;
44
45
  /** Loading state for approval actions */
45
46
  approvalLoading?: boolean;
47
+ /**
48
+ * The marks of whoever the tool belongs to — its MCP server, skill,
49
+ * frontend tool set or runtime tool spec — drawn before its name: the
50
+ * icon, else the emoji, else nothing.
51
+ */
52
+ marks?: Marks | null;
46
53
  }
47
54
  /**
48
55
  * ToolCallDisplay component - Default display for tool calls in chat
@@ -54,5 +61,5 @@ export interface ToolCallDisplayProps {
54
61
  * - Color-coded status indicators
55
62
  * - Rich error display distinguishing execution errors from code errors
56
63
  */
57
- export declare function ToolCallDisplay({ toolCallId, toolName, args, result, status, error, executionResult, codeError, exitCode, executionError, approvalRequired, approvalState, approvalDecisionSource, onApprove, onDeny, approvalLoading, }: ToolCallDisplayProps): React.JSX.Element;
64
+ export declare function ToolCallDisplay({ toolCallId, toolName, args, result, status, error, executionResult, codeError, exitCode, executionError, approvalRequired, approvalState, approvalDecisionSource, onApprove, onDeny, approvalLoading, marks, }: ToolCallDisplayProps): React.JSX.Element;
58
65
  export default ToolCallDisplay;
@@ -13,6 +13,7 @@ import { useEffect, useState } from 'react';
13
13
  import { Button, Text } from '@primer/react';
14
14
  import { Box } from '@datalayer/primer-addons';
15
15
  import { ChevronDownIcon, ChevronRightIcon, ToolsIcon, CheckCircleIcon, XCircleIcon, ClockIcon, AlertIcon, } from '@primer/octicons-react';
16
+ import { SpecMark, hasMark } from '../marks';
16
17
  /**
17
18
  * Get status icon and color based on tool call status
18
19
  */
@@ -124,7 +125,7 @@ function getArgsSummary(args) {
124
125
  * - Color-coded status indicators
125
126
  * - Rich error display distinguishing execution errors from code errors
126
127
  */
127
- export function ToolCallDisplay({ toolCallId, toolName, args, result, status, error, executionResult, codeError, exitCode, executionError, approvalRequired = false, approvalState, approvalDecisionSource, onApprove, onDeny, approvalLoading = false, }) {
128
+ export function ToolCallDisplay({ toolCallId, toolName, args, result, status, error, executionResult, codeError, exitCode, executionError, approvalRequired = false, approvalState, approvalDecisionSource, onApprove, onDeny, approvalLoading = false, marks, }) {
128
129
  const [isExpanded, setIsExpanded] = useState(false);
129
130
  // Determine effective exit code from props or execution result
130
131
  const effectiveExitCode = exitCode ?? executionResult?.exit_code;
@@ -189,7 +190,7 @@ export function ToolCallDisplay({ toolCallId, toolName, args, result, status, er
189
190
  '&:hover': {
190
191
  backgroundColor: 'neutral.muted',
191
192
  },
192
- }, children: [_jsx(Box, { sx: { color: 'fg.muted', flexShrink: 0 }, children: isExpanded ? (_jsx(ChevronDownIcon, { size: 16 })) : (_jsx(ChevronRightIcon, { size: 16 })) }), _jsx(Box, { sx: { color: 'fg.muted', flexShrink: 0 }, children: _jsx(ToolsIcon, { size: 16 }) }), _jsx(Text, { sx: {
193
+ }, children: [_jsx(Box, { sx: { color: 'fg.muted', flexShrink: 0 }, children: isExpanded ? (_jsx(ChevronDownIcon, { size: 16 })) : (_jsx(ChevronRightIcon, { size: 16 })) }), hasMark(marks) && (_jsx(Box, { sx: { color: 'fg.muted', flexShrink: 0, display: 'flex' }, children: _jsx(SpecMark, { icon: marks?.icon, emoji: marks?.emoji, size: 16 }) })), _jsx(Text, { sx: {
193
194
  fontWeight: 'semibold',
194
195
  fontSize: 1,
195
196
  color: 'fg.default',
@@ -1288,12 +1288,13 @@ export default function ChatView({ workspace }) {
1288
1288
  const offeredTools = useMemo(() => {
1289
1289
  const fromServer = configQuery.data?.builtinTools ?? [];
1290
1290
  const seen = new Set(fromServer.map(tool => tool.name));
1291
- return [
1292
- ...fromServer,
1293
- ...agentTools
1291
+ // The runtime's, and the frontend tools this page runs: named apart.
1292
+ return {
1293
+ runtime: fromServer,
1294
+ frontend: agentTools
1294
1295
  .filter(tool => !seen.has(tool.name))
1295
1296
  .map(tool => ({ id: tool.name, name: tool.name })),
1296
- ];
1297
+ };
1297
1298
  }, [configQuery.data?.builtinTools, agentTools]);
1298
1299
  /* Which skills are on, as the runtime last reported them. Derived rather
1299
1300
  than held: the source of truth is the agent, and a local copy would drift
@@ -1423,7 +1424,8 @@ export default function ChatView({ workspace }) {
1423
1424
  selectedModel: activeModel,
1424
1425
  onModelSelect: model => void selectModel(model),
1425
1426
  showToolsMenu: !presence,
1426
- availableTools: offeredTools,
1427
+ availableTools: offeredTools.runtime,
1428
+ availableFrontendTools: offeredTools.frontend,
1427
1429
  mcpServers: configQuery.data?.mcpServers ?? [],
1428
1430
  // Live from the host example, when one feeds it: the footer's MCP status
1429
1431
  // indicator. (Codemode surfaces through the toggle below, not a blob.)
@@ -547,6 +547,62 @@ export const SERVER_ACTIONS = {
547
547
  tools: {},
548
548
  conditions: {},
549
549
  },
550
+ 'odoo-accounting': {
551
+ checked: '2026-10-05',
552
+ default: [],
553
+ tools: {
554
+ odoo_accounting_list_invoices: ['read'],
555
+ odoo_accounting_get_invoice: ['read'],
556
+ odoo_accounting_list_journal_entries: ['read'],
557
+ odoo_accounting_list_open_balances: ['read'],
558
+ odoo_accounting_list_accounts: ['read'],
559
+ odoo_accounting_list_journals: ['read'],
560
+ odoo_accounting_get_journal_entry: ['read'],
561
+ odoo_accounting_trial_balance: ['read'],
562
+ odoo_accounting_general_ledger: ['read'],
563
+ odoo_accounting_create_draft_invoice: ['write'],
564
+ odoo_accounting_post_invoice: ['write'],
565
+ odoo_accounting_create_draft_journal_entry: ['write'],
566
+ odoo_accounting_post_journal_entry: ['write'],
567
+ odoo_accounting_list_partners: ['read'],
568
+ odoo_accounting_partner_ledger: ['read'],
569
+ odoo_accounting_aged_balance: ['read'],
570
+ odoo_accounting_list_taxes: ['read'],
571
+ odoo_accounting_list_assets: ['read'],
572
+ odoo_accounting_get_asset: ['read'],
573
+ odoo_accounting_reconcile_lines: ['write'],
574
+ odoo_accounting_unreconcile_lines: ['write'],
575
+ odoo_accounting_bank_status: ['read'],
576
+ odoo_accounting_list_bank_lines: ['read'],
577
+ odoo_accounting_get_bank_line: ['read'],
578
+ odoo_accounting_suggest_bank_matches: ['read'],
579
+ odoo_accounting_suggest_reconciliations: ['read'],
580
+ odoo_accounting_explain_account_balance: ['read'],
581
+ odoo_accounting_list_bank_feeds: ['read'],
582
+ odoo_accounting_list_currency_rates: ['read'],
583
+ odoo_accounting_get_lock_dates: ['read'],
584
+ odoo_accounting_book_bank_line: ['write'],
585
+ odoo_accounting_match_bank_line: ['write'],
586
+ odoo_accounting_reset_bank_line: ['write'],
587
+ odoo_accounting_remove_duplicate_bank_lines: ['delete'],
588
+ odoo_accounting_link_bank_feed: ['write'],
589
+ odoo_accounting_create_vendor_bill: ['write'],
590
+ odoo_accounting_create_customer_invoice: ['write'],
591
+ odoo_accounting_set_currency_rates: ['write'],
592
+ odoo_accounting_set_lock_date: ['write'],
593
+ odoo_accounting_create_matching_model: ['write'],
594
+ odoo_accounting_get_tax_settings: ['read'],
595
+ odoo_accounting_list_tax_returns: ['read'],
596
+ odoo_accounting_get_tax_return: ['read'],
597
+ odoo_accounting_tax_grids: ['read'],
598
+ odoo_accounting_list_tax_grid_lines: ['read'],
599
+ odoo_accounting_check_tax_period: ['read'],
600
+ odoo_accounting_list_untagged_tax_lines: ['read'],
601
+ odoo_accounting_set_tax_periodicity: ['write'],
602
+ odoo_accounting_set_tax_grids: ['write'],
603
+ },
604
+ conditions: {},
605
+ },
550
606
  salesforce: {
551
607
  default: [],
552
608
  tools: {},
@@ -32,7 +32,7 @@ export const DECKS_FRONTEND_TOOL_SPEC_0_0_1 = {
32
32
  'decks_present',
33
33
  'decks_print',
34
34
  ],
35
- icon: 'project',
35
+ icon: '@primer/octicons-react:project',
36
36
  emoji: '🃏',
37
37
  };
38
38
  export const JUPYTER_NOTEBOOK_EDIT_FRONTEND_TOOL_SPEC_0_0_1 = {
@@ -50,7 +50,7 @@ export const JUPYTER_NOTEBOOK_EDIT_FRONTEND_TOOL_SPEC_0_0_1 = {
50
50
  'runCell',
51
51
  'executeCode',
52
52
  ],
53
- icon: 'notebook',
53
+ icon: '@datalayer/icons-react:jupyter',
54
54
  emoji: '📓',
55
55
  };
56
56
  export const JUPYTER_NOTEBOOK_PROPOSE_FRONTEND_TOOL_SPEC_0_0_1 = {
@@ -61,7 +61,7 @@ export const JUPYTER_NOTEBOOK_PROPOSE_FRONTEND_TOOL_SPEC_0_0_1 = {
61
61
  tags: ['frontend', 'notebook', 'propose'],
62
62
  enabled: true,
63
63
  toolset: ['readCell', 'readAllCells', 'proposeCellUpdate', 'runCell'],
64
- icon: 'notebook',
64
+ icon: '@datalayer/icons-react:jupyter',
65
65
  emoji: '📓',
66
66
  };
67
67
  export const JUPYTER_NOTEBOOK_READ_FRONTEND_TOOL_SPEC_0_0_1 = {
@@ -72,7 +72,7 @@ export const JUPYTER_NOTEBOOK_READ_FRONTEND_TOOL_SPEC_0_0_1 = {
72
72
  tags: ['frontend', 'notebook', 'read'],
73
73
  enabled: true,
74
74
  toolset: ['readCell', 'readAllCells'],
75
- icon: 'notebook',
75
+ icon: '@datalayer/icons-react:jupyter',
76
76
  emoji: '📓',
77
77
  };
78
78
  export const JUPYTER_NOTEBOOK_FRONTEND_TOOL_SPEC_0_0_1 = {
@@ -83,7 +83,7 @@ export const JUPYTER_NOTEBOOK_FRONTEND_TOOL_SPEC_0_0_1 = {
83
83
  tags: ['frontend', 'notebook', 'jupyter-server'],
84
84
  enabled: true,
85
85
  toolset: 'all',
86
- icon: 'notebook',
86
+ icon: '@datalayer/icons-react:jupyter',
87
87
  emoji: '📓',
88
88
  };
89
89
  export const LEXICAL_DOCUMENT_FRONTEND_TOOL_SPEC_0_0_1 = {
@@ -94,7 +94,7 @@ export const LEXICAL_DOCUMENT_FRONTEND_TOOL_SPEC_0_0_1 = {
94
94
  tags: ['frontend', 'document', 'lexical', 'drawing', 'diagram'],
95
95
  enabled: true,
96
96
  toolset: 'all',
97
- icon: 'file',
97
+ icon: '@primer/octicons-react:file',
98
98
  emoji: '📄',
99
99
  };
100
100
  // ============================================================================
@@ -17,6 +17,7 @@ export declare const GITHUB_MCP_SERVER_0_0_1: MCPServer;
17
17
  export declare const GOOGLE_WORKSPACE_MCP_SERVER_0_0_1: MCPServer;
18
18
  export declare const HUGGINGFACE_MCP_SERVER_0_0_1: MCPServer;
19
19
  export declare const KAGGLE_MCP_SERVER_0_0_1: MCPServer;
20
+ export declare const ODOO_ACCOUNTING_MCP_SERVER_0_0_1: MCPServer;
20
21
  export declare const ODOO_MCP_SERVER_0_0_1: MCPServer;
21
22
  export declare const SALESFORCE_MCP_SERVER_0_0_1: MCPServer;
22
23
  export declare const SLACK_MCP_SERVER_0_0_1: MCPServer;
@@ -10,7 +10,7 @@ export const ALPHAVANTAGE_MCP_SERVER_0_0_1 = {
10
10
  version: '0.0.1',
11
11
  name: 'Alpha Vantage',
12
12
  description: 'Financial market data and stock information',
13
- icon: 'graph',
13
+ icon: '@primer/octicons-react:graph',
14
14
  emoji: '💹',
15
15
  url: '',
16
16
  command: 'uvx',
@@ -26,7 +26,7 @@ export const CHART_MCP_SERVER_0_0_1 = {
26
26
  version: '0.0.1',
27
27
  name: 'Chart Generator',
28
28
  description: 'Generate charts and visualizations',
29
- icon: 'graph',
29
+ icon: '@datalayer/icons-react:chart-bar',
30
30
  emoji: '📊',
31
31
  url: '',
32
32
  command: 'npx',
@@ -42,7 +42,7 @@ export const DATALAYER_MCP_SERVER_0_0_1 = {
42
42
  version: '0.0.1',
43
43
  name: 'Datalayer',
44
44
  description: 'Read, edit and run Jupyter notebooks on Datalayer, with sandboxes and data',
45
- icon: 'notebook',
45
+ icon: '@datalayer/icons-react:datalayer',
46
46
  emoji: '🚀',
47
47
  url: '',
48
48
  command: 'npx',
@@ -64,7 +64,7 @@ export const EARTHDATA_MCP_SERVER_0_0_1 = {
64
64
  version: '0.0.1',
65
65
  name: 'Earthdata MCP',
66
66
  description: 'Access NASA Earthdata search and metadata capabilities',
67
- icon: 'globe',
67
+ icon: '@datalayer/icons-react:globe-americas',
68
68
  emoji: '🌍',
69
69
  url: '',
70
70
  command: 'npx',
@@ -80,7 +80,7 @@ export const EURUS_MCP_SERVER_0_0_1 = {
80
80
  version: '0.0.1',
81
81
  name: 'Eurus Climate MCP',
82
82
  description: 'Climate and reanalysis analysis tools for spatial workflows',
83
- icon: 'graph',
83
+ icon: '@primer/octicons-react:cloud',
84
84
  emoji: '🌦️',
85
85
  url: '',
86
86
  command: 'eurus-mcp',
@@ -96,7 +96,7 @@ export const FILESYSTEM_MCP_SERVER_0_0_1 = {
96
96
  version: '0.0.1',
97
97
  name: 'Filesystem',
98
98
  description: 'Local filesystem read/write operations',
99
- icon: 'file-directory',
99
+ icon: '@primer/octicons-react:file-directory',
100
100
  emoji: '📁',
101
101
  url: '',
102
102
  command: 'npx',
@@ -112,7 +112,7 @@ export const GITHUB_MCP_SERVER_0_0_1 = {
112
112
  version: '0.0.1',
113
113
  name: 'GitHub',
114
114
  description: 'GitHub repository operations (issues, PRs, code search)',
115
- icon: 'mark-github',
115
+ icon: '@datalayer/icons-react:github-mark',
116
116
  emoji: '🐙',
117
117
  url: '',
118
118
  command: 'docker',
@@ -135,7 +135,7 @@ export const GOOGLE_WORKSPACE_MCP_SERVER_0_0_1 = {
135
135
  version: '0.0.1',
136
136
  name: 'Google Workspace',
137
137
  description: 'Google Drive, Gmail, Calendar, and Docs integration',
138
- icon: 'mail',
138
+ icon: '@datalayer/icons-react:google',
139
139
  emoji: '📧',
140
140
  url: '',
141
141
  command: 'uvx',
@@ -154,7 +154,7 @@ export const HUGGINGFACE_MCP_SERVER_0_0_1 = {
154
154
  version: '0.0.1',
155
155
  name: 'Hugging Face',
156
156
  description: 'Hugging Face models, datasets, spaces, and papers access',
157
- icon: 'brain',
157
+ icon: '@primer/octicons-react:hubot',
158
158
  emoji: '🤗',
159
159
  url: '',
160
160
  command: 'npx',
@@ -176,8 +176,8 @@ export const KAGGLE_MCP_SERVER_0_0_1 = {
176
176
  version: '0.0.1',
177
177
  name: 'Kaggle',
178
178
  description: 'Kaggle datasets, models, competitions, and notebooks access',
179
- icon: 'database',
180
- emoji: '📊',
179
+ icon: '@datalayer/icons-react:kaggle',
180
+ emoji: '🏆',
181
181
  url: '',
182
182
  command: 'npx',
183
183
  args: [
@@ -193,13 +193,35 @@ export const KAGGLE_MCP_SERVER_0_0_1 = {
193
193
  tools: [],
194
194
  requiredEnvVars: ['KAGGLE_API_TOKEN:0.0.1'],
195
195
  };
196
+ export const ODOO_ACCOUNTING_MCP_SERVER_0_0_1 = {
197
+ id: 'odoo-accounting',
198
+ version: '0.0.1',
199
+ name: 'Odoo Accounting',
200
+ description: "An accountant's day in Odoo — invoices, bills, journal entries, reconciliations, bank lines and tax returns — through the Datalayer MCP server",
201
+ icon: '@datalayer/icons-react:odoo',
202
+ emoji: '🧮',
203
+ url: '',
204
+ command: 'npx',
205
+ args: [
206
+ '-y',
207
+ 'mcp-remote',
208
+ 'https://mcp.datalayer.run/mcp?only=odoo-accounting',
209
+ '--header',
210
+ 'Authorization: Bearer ${DATALAYER_API_KEY}',
211
+ ],
212
+ transport: 'stdio',
213
+ enabled: false,
214
+ isAvailable: false,
215
+ tools: [],
216
+ requiredEnvVars: ['DATALAYER_API_KEY:0.0.1'],
217
+ };
196
218
  export const ODOO_MCP_SERVER_0_0_1 = {
197
219
  id: 'odoo',
198
220
  version: '0.0.1',
199
221
  name: 'Odoo',
200
222
  description: 'Odoo ERP operations (search, invoices, journals, reconciliations)',
201
- icon: 'server',
202
- emoji: '📚',
223
+ icon: '@datalayer/icons-react:odoo',
224
+ emoji: '🧾',
203
225
  url: '',
204
226
  command: 'uvx',
205
227
  args: ['mcp-server-odoo'],
@@ -214,7 +236,7 @@ export const SALESFORCE_MCP_SERVER_0_0_1 = {
214
236
  version: '0.0.1',
215
237
  name: 'Salesforce',
216
238
  description: 'Salesforce CRM operations (queries, reports, objects, SOQL)',
217
- icon: 'briefcase',
239
+ icon: '@primer/octicons-react:briefcase',
218
240
  emoji: '☁️',
219
241
  url: '',
220
242
  command: 'npx',
@@ -233,7 +255,7 @@ export const SLACK_MCP_SERVER_0_0_1 = {
233
255
  version: '0.0.1',
234
256
  name: 'Slack',
235
257
  description: 'Slack messaging and channel operations',
236
- icon: 'comment-discussion',
258
+ icon: '@datalayer/icons-react:slack',
237
259
  emoji: '💬',
238
260
  url: '',
239
261
  command: 'npx',
@@ -253,7 +275,7 @@ export const TAVILY_MCP_SERVER_0_0_1 = {
253
275
  version: '0.0.1',
254
276
  name: 'Tavily Search',
255
277
  description: 'Web search and research capabilities via Tavily API',
256
- icon: 'search',
278
+ icon: '@primer/octicons-react:search',
257
279
  emoji: '🔍',
258
280
  url: '',
259
281
  command: 'npx',
@@ -278,6 +300,7 @@ export const MCP_SERVER_LIBRARY = {
278
300
  'google-workspace': GOOGLE_WORKSPACE_MCP_SERVER_0_0_1,
279
301
  huggingface: HUGGINGFACE_MCP_SERVER_0_0_1,
280
302
  kaggle: KAGGLE_MCP_SERVER_0_0_1,
303
+ 'odoo-accounting': ODOO_ACCOUNTING_MCP_SERVER_0_0_1,
281
304
  odoo: ODOO_MCP_SERVER_0_0_1,
282
305
  salesforce: SALESFORCE_MCP_SERVER_0_0_1,
283
306
  slack: SLACK_MCP_SERVER_0_0_1,
@@ -18,7 +18,7 @@ export const ACCOUNTING_SKILL_SPEC_0_0_1 = {
18
18
  optionalEnvVars: [],
19
19
  dependencies: ['pandas>=2.0.0'],
20
20
  tags: ['accounting', 'finance', 'reconciliation', 'close'],
21
- icon: 'book',
21
+ icon: '@primer/octicons-react:book',
22
22
  emoji: '🧮',
23
23
  enabled: false,
24
24
  };
@@ -35,7 +35,7 @@ export const CRAWL_SKILL_SPEC_0_0_1 = {
35
35
  optionalEnvVars: [],
36
36
  dependencies: ['requests>=2.31.0', 'beautifulsoup4>=4.12.0'],
37
37
  tags: ['web', 'crawl', 'scraping'],
38
- icon: 'globe',
38
+ icon: '@primer/octicons-react:globe',
39
39
  emoji: '🌐',
40
40
  enabled: true,
41
41
  };
@@ -52,7 +52,7 @@ export const EVENTS_SKILL_SPEC_0_0_1 = {
52
52
  optionalEnvVars: [],
53
53
  dependencies: ['httpx>=0.27.0'],
54
54
  tags: ['events', 'orchestration', 'automation'],
55
- icon: 'bell',
55
+ icon: '@primer/octicons-react:calendar',
56
56
  emoji: '📅',
57
57
  enabled: false,
58
58
  };
@@ -69,7 +69,7 @@ export const GITHUB_SKILL_SPEC_0_0_1 = {
69
69
  optionalEnvVars: [],
70
70
  dependencies: ['PyGithub>=2.1.0'],
71
71
  tags: ['github', 'git', 'code'],
72
- icon: 'mark-github',
72
+ icon: '@datalayer/icons-react:github-mark',
73
73
  emoji: '🐙',
74
74
  enabled: false,
75
75
  };
@@ -86,7 +86,7 @@ export const JOKES_SKILL_SPEC_0_0_1 = {
86
86
  optionalEnvVars: [],
87
87
  dependencies: [],
88
88
  tags: ['fun', 'humor', 'demo'],
89
- icon: 'smiley',
89
+ icon: '@primer/octicons-react:smiley',
90
90
  emoji: '😄',
91
91
  enabled: false,
92
92
  };
@@ -103,7 +103,7 @@ export const PDF_SKILL_SPEC_0_0_1 = {
103
103
  optionalEnvVars: [],
104
104
  dependencies: ['PyPDF2>=3.0.0', 'pdfplumber>=0.10.0'],
105
105
  tags: ['pdf', 'documents', 'extraction'],
106
- icon: 'file',
106
+ icon: '@primer/octicons-react:file',
107
107
  emoji: '📄',
108
108
  enabled: false,
109
109
  };
@@ -120,7 +120,7 @@ export const TEXT_SUMMARIZER_SKILL_SPEC_0_0_1 = {
120
120
  optionalEnvVars: [],
121
121
  dependencies: ['agent-skills>=0.0.1'],
122
122
  tags: ['nlp', 'summarization', 'text-processing'],
123
- icon: 'note',
123
+ icon: '@primer/octicons-react:note',
124
124
  emoji: '📝',
125
125
  enabled: false,
126
126
  };