Once connected, your client can discover and use everything the server offers.
// Discover all tools the server offers
const { tools } = await client.listTools();
console.log("Available tools:");
for (const tool of tools) {
console.log(` - ${tool.name}: ${tool.description}`);
console.log(` Schema: ${JSON.stringify(tool.inputSchema)}`);
}
// Execute a tool with arguments
const result = await client.callTool("search_notes", {
query: "meeting agenda",
maxResults: 3
});
// Handle the response
for (const block of result.content) {
if (block.type === "text") {
console.log("Result:", block.text);
} else if (block.type === "image") {
console.log("Image:", block.mimeType, block.data.length, "bytes");
}
}
// Check for errors
if (result.isError) {
console.error("Tool returned an error:", result.content[0].text);
}
// List all available resources
const { resources } = await client.listResources();
// Read a specific resource
const { contents } = await client.readResource("notes://note/meeting-notes.md");
console.log("Note content:", contents[0].text);
// List resource templates for dynamic access
const { resourceTemplates } = await client.listResourceTemplates();
// List available prompts
const { prompts } = await client.listPrompts();
// Get a prompt with arguments
const { messages } = await client.getPrompt("summarize_topic", {
topic: "quarterly goals"
});
// Feed the messages to your LLM
const response = await llm.chat(messages);
| Operation | Method | Returns |
|---|---|---|
| Discover tools | client.listTools() | Array of tool schemas |
| Execute tool | client.callTool(name, args) | Content blocks (text/image) |
| List resources | client.listResources() | Array of resource URIs |
| Read resource | client.readResource(uri) | Resource contents |
| List prompts | client.listPrompts() | Array of prompt schemas |
| Get prompt | client.getPrompt(name, args) | Message array for LLM |
result.isError after calling a tool. Servers return errors as content blocks with isError: true rather than throwing exceptions.