Expose Tools over MCP
medium10 minmcp-server.ts
Your inventory tools should be usable from any MCP client — Claude Desktop, Cursor or another agent.
What it shows
- Register Cogitator tools and a resource template on
MCPServer - Serve over HTTP; a thrown error reaches the client as
MCPToolError
The code
mcp-server.ts
import { Agent, Cogitator, tool } from '@cogitator-ai/core';
import { MCPClient, MCPServer, MCPToolError } from '@cogitator-ai/mcp';
import { z } from 'zod';
const apiKey = process.env.GOOGLE_API_KEY;
if (!apiKey) throw new Error('Set GOOGLE_API_KEY');
const stock: Record<string, number> = { 'SKU-42': 137, 'SKU-7': 12 };
const lookupStock = tool({
name: 'lookup_stock',
description: 'Look up how many units of a product SKU are in stock.',
parameters: z.object({ sku: z.string().describe('Product SKU, e.g. "SKU-42"') }),
execute: async ({ sku }) => ({ sku, units: stock[sku] ?? 0 }),
});
const reserveUnits = tool({
name: 'reserve_units',
description: 'Reserve units of a product. Fails if not enough stock is available.',
parameters: z.object({ sku: z.string(), units: z.number().int().positive() }),
execute: async ({ sku, units }) => {
const available = stock[sku] ?? 0;
if (units > available) throw new Error(`Only ${available} units of ${sku} available`);
stock[sku] = available - units;
return { sku, reserved: units, remaining: stock[sku] };
},
});
const server = new MCPServer({
name: 'inventory',
version: '1.0.0',
transport: 'http',
host: '127.0.0.1',
port: 0,
});
server.registerTools([lookupStock, reserveUnits]);
server.registerResource({
uri: 'inventory://sku/{sku}',
name: 'sku',
mimeType: 'application/json',
read: async ({ sku }) => ({
uri: `inventory://sku/${sku}`,
text: JSON.stringify({ sku, units: stock[sku] ?? 0 }),
}),
});
await server.start();
const client = await MCPClient.connect({
transport: 'http',
url: `http://127.0.0.1:${server.getPort()}/mcp`,
});
try {
console.log(await client.callTool('lookup_stock', { sku: 'SKU-42' }));
console.log((await client.readResource('inventory://sku/SKU-7')).text);
try {
await client.callTool('reserve_units', { sku: 'SKU-7', units: 999 });
} catch (error) {
if (!(error instanceof MCPToolError)) throw error;
console.log('Refused:', error.message);
}
const cog = new Cogitator({ llm: { providers: { google: { apiKey } } } });
const agent = new Agent({
name: 'inventory-assistant',
model: 'google/gemini-3.5-flash-lite',
instructions: 'You manage inventory. Use the tools to check stock and reserve units. Be concise.',
tools: await client.getTools(),
temperature: 0.2,
});
const result = await cog.run(agent, { input: 'Reserve 40 units of SKU-42 and tell me what remains.' });
console.log(result.output);
await cog.close();
} finally {
await client.close();
await server.stop();
}Run it
install · bash
pnpm add @cogitator-ai/core @cogitator-ai/mcp zodEnvironment
GOOGLE_API_KEYrun · bash
GOOGLE_API_KEY=your-key npx tsx mcp-server.tsOr run the full example from a clone of the repository (keys in .env):
repository · bash
npx tsx examples/mcp/02-mcp-server.ts