@vecto-os/graph-tools
v0.1.0
Published
Shared graph-tool handlers used by the Vecto MCP server and the internal dash-api chat pipeline. Transport-agnostic: consumers inject a ToolContext that implements graph-verb operations (search, get, create, update, add_edge, etc.) — handlers never touch
Downloads
77
Maintainers
Readme
@vecto-os/graph-tools
Shared graph-tool handlers used by both the Vecto MCP server (external
agents, published as @vecto-os/mcp-server) and the Vecto dash-api internal
chat pipeline. One codepath, two transports.
Why this exists
Before v0.1.17, graph-operation logic lived in two places:
@vecto-os/mcp-server— REST-backed handlers for external agents (Claude Code, Cursor, Claude Desktop, etc.)dash-api/src/services/agentTools.ts— a separate registry for the internal chat, with no write-tools (only read/card tools), because reimplementing the same CRUD logic in two places guarantees drift.
Result: the internal chat could not create nodes. When Gemini Flash was
asked to "create an epic" it would pick the closest read-tool, narrate
success, and hallucinate a ref. See production chat session
e2adc7d0-5d5f-4ecb-9d00-53bed8ab4f7f for the full reproducer, and
EPC-59 / DOC-251 for the architecture decision.
This package is the fix: one set of handlers, one schema, one result shape. MCP wraps it in JSON-RPC; dash-api wraps it in-process. "MCP as implementation, not transport."
Architecture
The core abstraction is ToolContext — a verb-level interface.
Consumers implement the verbs; they do not expose REST clients or DB
clients at the interface boundary.
export interface ToolContext {
tenantId: string;
projectSlug?: string; // optional workspace default
actor: ToolActor;
audit?: (event: string, payload: unknown) => Promise<void>;
searchNodes(args: SearchNodesArgs): Promise<SearchNodesResult>;
getNode(args: GetNodeArgs): Promise<GetNodeResult>;
resolveQref(args: ResolveQrefArgs): Promise<ResolveQrefResult>;
createNode(args: CreateNodeArgs): Promise<CreateNodeResult>;
updateNode(args: UpdateNodeArgs): Promise<UpdateNodeResult>;
addEdge(args: AddEdgeArgs): Promise<AddEdgeResult>;
removeEdge(args: RemoveEdgeArgs): Promise<RemoveEdgeResult>;
}Two reference implementations live outside this package:
| Consumer | Implementation | Location |
|---|---|---|
| @vecto-os/mcp-server | RestToolContext — wraps the REST client, calls /api/v1/projects/:slug/... endpoints | packages/vecto-mcp/src/context.ts |
| dash-api internal chat | InProcessToolContext — wraps the dash-api DB/service layer directly | dash-api/src/services/graphToolsContext.ts (future — see STR-293) |
Handlers themselves are pure: (ctx, args) => Promise<HandlerResult>.
They validate args via Zod, invoke a ctx verb, and format a neutral
result shape. They contain no try/catch — errors propagate to the caller
(MCP adapter / dash-api adapter), which translates to its protocol-specific
error envelope.
Public API
import {
// Context
type ToolContext,
type ToolActor,
ToolError,
// Schemas (Zod + JSON-Schema-compatible)
searchNodesInputSchema,
getNodeInputSchema,
// ... etc
// Handlers
searchNodesHandler,
getNodeHandler,
// ... etc
// Registry (handler + schema + metadata bundles)
allTools,
// MCP adapter
registerAllTools, // (server: McpServer, ctx: ToolContext) => void
} from '@vecto-os/graph-tools';Used by
@vecto-os/mcp-server(packages/vecto-mcp) — re-exports tools via JSON-RPCdash-apiinternal chat (dash-api/src/services/agentTools.ts) — re-exports tools as Gemini/OpenAI/Anthropic function-calls (STR-293, EPC-59)
Build
npm install
npm run buildNo runtime deps on REST clients, DB drivers, or the MCP SDK. The MCP SDK
is an optional peer dep (only needed if you use registerAllTools or
mcpAdapter).
Versioning
Semver. Minor bumps for additive tool/schema additions. Major bumps only
on breaking changes to ToolContext or existing handler signatures.
Linked from sibling packages via file:../graph-tools (no workspaces yet
in this repo). Rebuild after changes:
cd packages/graph-tools && npm run build
cd ../vecto-mcp && rm -rf node_modules/@vecto-os/graph-tools && npm installReferences
- EPC-59 — Chat pipeline fix — shared graph-tools package + grounded tool-calls
- DOC-251 — Chat tool architecture blueprint (ADR)
- STR-287 — This story (scaffold + handler migration)
- STR-293 — Follow-up: wire write-tools into internal chat
