MCP Agent Workflow
Use MCP inside an AI agent workflow for position and transfer operations.
Overview
This cookbook demonstrates how to integrate the DMTR MCP server into an AI agent workflow. The agent uses MCP tools to surface inventory, evaluate transfers, and express intent—all within a conversational or automated flow. The pattern applies to portfolio assistants (e.g., "What positions do I have?"), transfer bots (e.g., "Can I sell 100 units of position X to buyer Y?"), and compliance checkers that validate transfer feasibility before submission.
The agent runs in your environment—LangChain, AutoGen, a custom orchestrator, or a chat UI—and connects to the DMTR MCP server as a tool provider. The MCP client handles authentication and API calls; the agent invokes tools by name and receives structured results. This cookbook walks through each step with code examples.
Agent architecture
The agent connects to the DMTR MCP server via the MCP protocol. The server exposes tools (surface_inventory, evaluate_transfer, express_intent, etc.) that map to DMTR API operations. The agent decides when to call each tool based on user intent and tool outputs. Design your agent's prompt to use tools appropriately and chain them for multi-step workflows.
The MCP server runs as a standalone process. Clients connect via stdio (for local use) or HTTP (for remote deployment). Configure the server command (e.g., npx @dmtr/mcp-server or uvx dmtr-mcp) and set DMTR_API_KEY in the server's environment. See MCP Overview for setup details.
Step 1: Connect to DMTR MCP server
Initialize an MCP client and connect to the DMTR MCP server. The server can be spawned locally via npx @dmtr/mcp-server (Node.js) or uvx dmtr-mcp (Python).
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
import { spawn } from "child_process";
const transport = new StdioClientTransport({
command: "npx",
args: ["@dmtr/mcp-server"],
env: { ...process.env, DMTR_API_KEY: process.env.DMTR_API_KEY },
});
const client = new Client({ name: "dmtr-agent", version: "1.0.0" });
await client.connect(transport);
const tools = await client.listTools();
console.log("Available tools:", tools.tools.map((t) => t.name));Step 2: Surface inventory
Call the surface_inventory tool to fetch positions for a participant. The tool returns a compact, copilot-optimized view: position IDs, portfolios, quantities, values, and transferability.
const result = await client.callTool({
name: "surface_inventory",
arguments: {
participant_id: "part-allocator-001",
status: "active",
},
});
const positions = JSON.parse(result.content[0].text).positions;
console.log("Positions:", positions);{
"positions": [
{
"entity_id": "meg-2026-112",
"owner": "part-allocator-001",
"status": "active",
"asset": {
"issuer": {
"name": "Acme Growth Fund III LLC"
},
"vehicle_class": "fund_lp"
},
"transferable": true,
"valuation": {
"current_mark": {
"value": 2500000,
"currency": "USD",
"as_of": "2026-03-01",
"provenance": "gp_mark"
}
}
},
{
"entity_id": "meg-2026-089",
"owner": "part-allocator-001",
"status": "active",
"asset": {
"issuer": {
"name": "Venture Growth Fund III LLC"
},
"vehicle_class": "fund_lp"
},
"transferable": true,
"valuation": {
"current_mark": {
"value": 1800000,
"currency": "USD",
"as_of": "2026-03-01",
"provenance": "gp_mark"
}
}
}
],
"total_value": 4300000
}Step 3: Evaluate transfer feasibility
Before expressing intent, check whether a transfer is feasible. Call the evaluate_transfer tool with the position ID, intended buyer, and quantity.
const result = await client.callTool({
name: "evaluate_transfer",
arguments: {
position_id: "meg-2026-112",
buyer_participant_id: "part-buyer-456",
quantity: 100,
},
});
const eval_ = JSON.parse(result.content[0].text);
console.log("Feasible:", eval_.feasible, "Reasons:", eval_.reasons);Step 4: Express intent
When the user confirms, call the express_intent tool to submit an Indication of Interest (IOI). Include position ID, direction (buy/sell), units, and indicative price.
const result = await client.callTool({
name: "express_intent",
arguments: {
position_id: "meg-2026-112",
direction: "sell",
units: 100,
indicative_price: 25000,
buyer_participant_id: "part-buyer-456",
},
});
const ioi = JSON.parse(result.content[0].text);
console.log("IOI created:", ioi.ioi_id);Human-in-the-loop: Always validate agent outputs before calling express_intent. The tool creates an IOI in Dark Matter—a write operation that may trigger notifications and workflows. Do not let the agent call express_intent without explicit user confirmation. Implement a confirmation step (e.g., "Confirm: Submit sell intent for 100 units at $25,000?") before invoking the tool.
Use dedicated API keys for the MCP client with minimal scopes. For read-only agents (inventory, feasibility checks), use keys with positions:read, portfolios:read, and transfers:evaluate only. Add ioi:write only when the agent needs to express intent. See MCP Security for deployment guidance.
Related docs
- MCP Overview — Setup and architecture
- MCP Tools — Full tool reference
- MCP Security — Authentication, scoping, and best practices