@aidex/tools
v1.2.0
Published
Aidex Tools — a central Tool Registry providing reusable, permission-gated tools for engines.
Maintainers
Readme
@aidex/tools
Installation
pnpm add @aidex/toolsnpm install @aidex/toolsA central registry providing reusable tools for engines: register once, discover by id or by required permission, execute by id with permission validation gating every call.
Contents
types/Tool—{ id, name, description, permissions?, inputSchema?, execute(input): Promise<TResult> }.permissionsdeclares what a caller must have been granted beforeexecute()runs.inputSchemais forward-compatible plumbing for future MCP (Model Context Protocol) compatibility — MCP describes tools by name/description/a JSON-Schema input shape, so carrying an optional JSON-Schema-shaped object today means a future MCP adapter can expose these tools without this package changing. No MCP transport or handshake is implemented — that's genuinely future work, not simulated here.registry/ToolRegistry—register(),has(),get(),list()(discovery: every tool),listByPermission(permission)(discovery: tools requiring a given permission),execute(id, input, grantedPermissions?). Duplicateidregistration throws@aidex/core's ownDuplicateRegistrationError(reused, not reimplemented).ToolNotFoundError— thrown byexecute()for an unregistered id.has()/get()stay plain accessors, matching every other registry in this codebase.ToolPermissionDeniedError— thrown byexecute()whengrantedPermissionsdoesn't cover every permission the tool declares as required. CarriesmissingPermissions— exactly what's absent, not the full required set. The tool's ownexecute()is never called when this check fails.
Permission validation
execute(id, input, grantedPermissions = []) compares the tool's declared
permissions against grantedPermissions (a flat list of permission name
strings) before invoking the tool. A tool declaring no permissions runs
unconditionally regardless of what's granted.
Dependency direction
@aidex/tools depends on @aidex/core only (DuplicateRegistrationError,
reused). No dependency on @aidex/engines, any provider, strategy, plugin,
or application code — tools are meant to be reusable by engines, not
coupled to any one of them.
Tool-calling foundation (Row 11) and the @aidex/mcp boundary
Aidex Gateway 1.1's tool-calling foundation — a ToolCallingProvider
interface, generateWithTools(), and the tool_use/tool_result
ContentPart variants a real model call actually produces/consumes —
lives in @aidex/providers, not here, and @aidex/providers depends on
@aidex/tools (never the reverse) to resolve a returned tool call against
this package's ToolRegistry: see @aidex/providers' README, "Tool
calling," for toToolDeclarations()/resolveToolCalls(). This preserves
the "core only" dependency direction above — @aidex/tools itself needed
no change to support it, since ToolRegistry.execute() already was, and
remains, the single place permission-gated tool execution happens.
@aidex/mcp (Model Context Protocol) remains a separate, unconnected
package, deliberately — the same "genuinely future work" status
Tool.inputSchema's own doc comment already described before Row 11.
Nothing in the tool-calling foundation adds an MCP transport, bridges
ToolRegistry to MCPToolRegistry, or otherwise connects the two
packages. Tool.inputSchema's JSON-Schema-shaped plumbing means a future
MCP adapter could expose these tools without this package changing, but
building that adapter is out of Row 11's scope, not silently done here.
