MCPcopy Create free account
hub / github.com/adcontextprotocol/adcp / handleChatTool

Function handleChatTool

server/src/mcp/chat-tool.ts:185–247  ·  view source on GitHub ↗
(
  args: Record<string, unknown>,
  authContext?: MCPAuthContext,
)

Source from the content-addressed store, hash-verified

183 * Handle the chat_with_addie tool call
184 */
185export async function handleChatTool(
186 args: Record<string, unknown>,
187 authContext?: MCPAuthContext,
188): Promise<string> {
189 const message = args.message;
190 const history = args.history as ConversationMessage[] | undefined;
191
192 if (!message || typeof message !== 'string') {
193 return JSON.stringify({
194 error: 'message is required and must be a string',
195 });
196 }
197
198 // Check if knowledge search is ready
199 if (!isKnowledgeReady()) {
200 return JSON.stringify({
201 error: 'Addie is still initializing. Please try again in a moment.',
202 });
203 }
204
205 try {
206 const client = getChatClient();
207
208 // Convert history to thread context format expected by AddieClaudeClient
209 const threadContext = history?.map((msg) => ({
210 user: msg.role === 'user' ? 'user' : 'assistant',
211 text: msg.content,
212 }));
213
214 // Cost cap (#2790 / #2950): bucket by the authenticated MCP sub
215 // when available. In prod, MCP auth is OAuth Bearer, so `sub` is
216 // the user or M2M client id — either is a legitimate per-caller
217 // bucket key. The anonymous tier (~$1/day) is the right ceiling
218 // for safe-tools-only chat traffic. If auth is disabled (dev
219 // mode) or the sub is missing, fall back to `uncapped: true` so
220 // local testing isn't budget-limited; prod MCP requires auth by
221 // default so the fallback doesn't expose a production surface.
222 const sub = authContext?.sub;
223 const costOption = sub && sub !== 'anonymous'
224 ? { costScope: { userId: `mcp:${sub}`, tier: 'anonymous' as const } }
225 : { uncapped: true as const };
226
227 const response = await client.processMessage(
228 message,
229 threadContext,
230 undefined, // No request-specific tools for anonymous
231 undefined, // No rules override
232 { maxIterations: 5, ...costOption }, // Lower iteration limit for anonymous users
233 );
234
235 const result: ChatResponse = {
236 response: response.text,
237 tools_used: response.tools_used,
238 };
239
240 return JSON.stringify(result);
241 } catch (error) {
242 logger.error({ error }, 'MCP Chat: Error processing message');

Callers

nothing calls this directly

Calls 3

isKnowledgeReadyFunction · 0.85
getChatClientFunction · 0.85
processMessageMethod · 0.80

Tested by

no test coverage detected