Bring your own agent

Wire the DOCX tools into Vercel AI SDK, OpenAI, Anthropic, LangChain, or any runtime that accepts OpenAI-style function schemas, with one shared executor.

Tool schemas

Every tool ships as an OpenAI-style function definition. Runtimes that accept that shape can use getToolSchemas() directly; other runtimes usually need a small mapping layer.

import { getToolSchemas } from '@eigenpal/docx-editor-agents';

const schemas = getToolSchemas();
// [{ type: 'function', function: { name: 'add_comment', description: '...', parameters: { ... } } }, ...]

Execution is the same everywhere: when your runtime returns a tool call, run it with executeToolCall(name, input, bridge). It is synchronous and returns { success, data?, error? }.

Vercel AI SDK

The AI SDK has a dedicated subpath: getAiSdkTools() returns the catalog in the AI SDK's tool shape, with no execute functions, so every call is forwarded to the client.

// server route
import { getAiSdkTools } from '@eigenpal/docx-editor-agents/ai-sdk/server';

const tools = getAiSdkTools(); // pass to streamText({ tools, ... })

The route also needs convertToModelMessages(messages) and a stopWhen so the agent loop can run more than one step. The AI editing tutorial walks through the complete server route and client wiring; start there if you are on the AI SDK.

Anthropic (Claude)

Anthropic's Messages API wants { name, description, input_schema } instead of the OpenAI envelope; the mapping is four lines.

import Anthropic from '@anthropic-ai/sdk';
import { getToolSchemas, executeToolCall } from '@eigenpal/docx-editor-agents';

const client = new Anthropic();

const tools = getToolSchemas().map(({ function: fn }) => ({
  name: fn.name,
  description: fn.description,
  input_schema: fn.parameters,
}));

const response = await client.messages.create({
  model: 'claude-sonnet-4-5',
  max_tokens: 1024,
  tools,
  messages: [
    /* ... */
  ],
});

// For each tool_use block, run it against your bridge and send the
// result back as a tool_result block:
for (const block of response.content) {
  if (block.type !== 'tool_use') continue;
  const result = executeToolCall(block.name, block.input as Record<string, unknown>, bridge);
}

OpenAI

Same schemas, same shape: pass them to tools: in the chat completions API.

import OpenAI from 'openai';
import { getToolSchemas, executeToolCall } from '@eigenpal/docx-editor-agents';

const client = new OpenAI();

const response = await client.chat.completions.create({
  model: 'gpt-4o',
  messages,
  tools: getToolSchemas(), // already in chat-completions tool format
});

for (const call of response.choices[0].message.tool_calls ?? []) {
  const result = executeToolCall(call.function.name, JSON.parse(call.function.arguments), bridge);
  messages.push({
    role: 'tool',
    tool_call_id: call.id,
    content: typeof result.data === 'string' ? result.data : JSON.stringify(result),
  });
}
// Send `messages` back to the model; repeat until there are no tool calls.

MCP clients

If your agent already supports MCP, expose the toolkit as a server instead:

import { McpServer } from '@eigenpal/docx-editor-agents/mcp';
import { DocxReviewer, createReviewerBridge } from '@eigenpal/docx-editor-agents';

const reviewer = await DocxReviewer.fromBuffer(buffer, 'Agent');
const server = new McpServer(createReviewerBridge(reviewer));
// wire to your MCP transport (stdio, websocket, etc.)

See MCP server for transports and hosting, and the API reference: agents for full signatures.

LangChain / custom

agentTools is the underlying tool definition array. Wrap each entry in the shape your framework expects, then dispatch through executeToolCall with a bridge. A headless DocxReviewer must be wrapped with createReviewerBridge first; a live editor uses createEditorBridge or the React/Vue hooks.

import { agentTools, executeToolCall, createReviewerBridge } from '@eigenpal/docx-editor-agents';

const bridge = createReviewerBridge(reviewer);

for (const tool of agentTools) {
  // Convert { name, description, inputSchema } to your framework's tool shape...
}

// When the framework dispatches a tool call:
const result = executeToolCall(toolName, toolInput, bridge);

Next steps

On this page