mirror of
https://github.com/AgentDeskAI/browser-tools-mcp.git
synced 2025-06-27 00:41:26 +00:00
removed yaml from docs
This commit is contained in:
parent
efa2799301
commit
3e31babf4f
@ -1,8 +1,5 @@
|
||||
---
|
||||
description: When architecting and building an MCP server
|
||||
globs: *.ts
|
||||
---
|
||||
## Resources
|
||||
|
||||
Expose data and content from your servers to LLMs
|
||||
|
||||
Resources are a core primitive in the Model Context Protocol (MCP) that allow servers to expose data and content that can be read by clients and used as context for LLM interactions.
|
||||
@ -31,7 +28,6 @@ Each resource is identified by a unique URI and can contain either text or binar
|
||||
Resource URIs
|
||||
Resources are identified using URIs that follow this format:
|
||||
|
||||
|
||||
[protocol]://[host]/[path]
|
||||
For example:
|
||||
|
||||
@ -70,7 +66,6 @@ Clients can discover available resources through two main methods:
|
||||
Direct resources
|
||||
Servers expose a list of concrete resources via the resources/list endpoint. Each resource includes:
|
||||
|
||||
|
||||
{
|
||||
uri: string; // Unique identifier for the resource
|
||||
name: string; // Human-readable name
|
||||
@ -81,7 +76,6 @@ Servers expose a list of concrete resources via the resources/list endpoint. Eac
|
||||
Resource templates
|
||||
For dynamic resources, servers can expose URI templates that clients can use to construct valid resource URIs:
|
||||
|
||||
|
||||
{
|
||||
uriTemplate: string; // URI template following RFC 6570
|
||||
name: string; // Human-readable name for this type
|
||||
@ -94,7 +88,6 @@ To read a resource, clients make a resources/read request with the resource URI.
|
||||
|
||||
The server responds with a list of resource contents:
|
||||
|
||||
|
||||
{
|
||||
contents: [
|
||||
{
|
||||
@ -105,6 +98,7 @@ The server responds with a list of resource contents:
|
||||
text?: string; // For text resources
|
||||
blob?: string; // For binary resources (base64 encoded)
|
||||
}
|
||||
|
||||
]
|
||||
}
|
||||
Servers may return multiple resources in response to one resources/read request. This could be used, for example, to return a list of files inside a directory when the directory is read.
|
||||
@ -129,8 +123,8 @@ Client can unsubscribe with resources/unsubscribe
|
||||
Example implementation
|
||||
Here’s a simple example of implementing resource support in an MCP server:
|
||||
|
||||
|
||||
## Prompts
|
||||
|
||||
Create reusable prompt templates and workflows
|
||||
|
||||
Prompts enable servers to define reusable prompt templates and workflows that clients can easily surface to users and LLMs. They provide a powerful way to standardize and share common LLM interactions.
|
||||
@ -150,7 +144,6 @@ Surface as UI elements (like slash commands)
|
||||
Prompt structure
|
||||
Each prompt is defined with:
|
||||
|
||||
|
||||
{
|
||||
name: string; // Unique identifier for the prompt
|
||||
description?: string; // Human-readable description
|
||||
@ -166,7 +159,6 @@ Each prompt is defined with:
|
||||
Discovering prompts
|
||||
Clients can discover available prompts through the prompts/list endpoint:
|
||||
|
||||
|
||||
// Request
|
||||
{
|
||||
method: "prompts/list"
|
||||
@ -192,7 +184,6 @@ Clients can discover available prompts through the prompts/list endpoint:
|
||||
Using prompts
|
||||
To use a prompt, clients make a prompts/get request:
|
||||
|
||||
|
||||
// Request
|
||||
{
|
||||
method: "prompts/get",
|
||||
@ -212,7 +203,7 @@ To use a prompt, clients make a prompts/get request:
|
||||
role: "user",
|
||||
content: {
|
||||
type: "text",
|
||||
text: "Please analyze the following Python code for potential improvements:\n\n```python\ndef calculate_sum(numbers):\n total = 0\n for num in numbers:\n total = total + num\n return total\n\nresult = calculate_sum([1, 2, 3, 4, 5])\nprint(result)\n```"
|
||||
text: "Please analyze the following Python code for potential improvements:\n\n`python\ndef calculate_sum(numbers):\n total = 0\n for num in numbers:\n total = total + num\n return total\n\nresult = calculate_sum([1, 2, 3, 4, 5])\nprint(result)\n`"
|
||||
}
|
||||
}
|
||||
]
|
||||
@ -242,7 +233,6 @@ Embedded resource context
|
||||
}
|
||||
When handling the prompts/get request:
|
||||
|
||||
|
||||
{
|
||||
"messages": [
|
||||
{
|
||||
@ -472,7 +462,6 @@ Like resources, tools are identified by unique names and can include description
|
||||
Tool definition structure
|
||||
Each tool is defined with the following structure:
|
||||
|
||||
|
||||
{
|
||||
name: string; // Unique identifier for the tool
|
||||
description?: string; // Human-readable description
|
||||
@ -538,7 +527,6 @@ Here are some examples of types of tools that a server could provide:
|
||||
System operations
|
||||
Tools that interact with the local system:
|
||||
|
||||
|
||||
{
|
||||
name: "execute_command",
|
||||
description: "Run a shell command",
|
||||
@ -554,7 +542,6 @@ Tools that interact with the local system:
|
||||
API integrations
|
||||
Tools that wrap external APIs:
|
||||
|
||||
|
||||
{
|
||||
name: "github_create_issue",
|
||||
description: "Create a GitHub issue",
|
||||
@ -571,7 +558,6 @@ Tools that wrap external APIs:
|
||||
Data processing
|
||||
Tools that transform or analyze data:
|
||||
|
||||
|
||||
{
|
||||
name: "analyze_csv",
|
||||
description: "Analyze a CSV file",
|
||||
@ -681,6 +667,7 @@ Performance testing: Check behavior under load, timeout handling, and resource c
|
||||
Error handling: Ensure tools properly report errors through the MCP protocol and clean up resources
|
||||
|
||||
## Sampling
|
||||
|
||||
Sampling
|
||||
Let your servers request completions from LLMs
|
||||
|
||||
@ -703,7 +690,6 @@ This human-in-the-loop design ensures users maintain control over what the LLM s
|
||||
Message format
|
||||
Sampling requests use a standardized message format:
|
||||
|
||||
|
||||
{
|
||||
messages: [
|
||||
{
|
||||
@ -719,6 +705,7 @@ Sampling requests use a standardized message format:
|
||||
mimeType?: string
|
||||
}
|
||||
}
|
||||
|
||||
],
|
||||
modelPreferences?: {
|
||||
hints?: [{
|
||||
@ -786,7 +773,6 @@ metadata: Additional provider-specific parameters
|
||||
Response format
|
||||
The client returns a completion result:
|
||||
|
||||
|
||||
{
|
||||
model: string, // Name of the model used
|
||||
stopReason?: "endTurn" | "stopSequence" | "maxTokens" | string,
|
||||
@ -802,7 +788,6 @@ The client returns a completion result:
|
||||
Example request
|
||||
Here’s an example of requesting sampling from a client:
|
||||
|
||||
|
||||
{
|
||||
"method": "sampling/createMessage",
|
||||
"params": {
|
||||
@ -920,7 +905,6 @@ A root is a URI that a client suggests a server should focus on. When a client c
|
||||
|
||||
For example, roots could be:
|
||||
|
||||
|
||||
file:///home/user/projects/myapp
|
||||
https://api.example.com/v1
|
||||
|
||||
@ -963,7 +947,6 @@ Handle root changes gracefully
|
||||
Example
|
||||
Here’s how a typical MCP client might expose roots:
|
||||
|
||||
|
||||
{
|
||||
"roots": [
|
||||
{
|
||||
|
232
docs/mcp.md
232
docs/mcp.md
@ -1,10 +1,7 @@
|
||||
---
|
||||
description: When building MCP servers
|
||||
globs: *.ts
|
||||
---
|
||||
# MCP TypeScript SDK  
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Overview](mdc:#overview)
|
||||
- [Installation](mdc:#installation)
|
||||
- [Quickstart](mdc:#quickstart)
|
||||
@ -46,33 +43,35 @@ npm install @modelcontextprotocol/sdk
|
||||
Let's create a simple MCP server that exposes a calculator tool and some data:
|
||||
|
||||
```typescript
|
||||
import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
|
||||
import {
|
||||
McpServer,
|
||||
ResourceTemplate,
|
||||
} from "@modelcontextprotocol/sdk/server/mcp.js";
|
||||
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
||||
import { z } from "zod";
|
||||
|
||||
// Create an MCP server
|
||||
const server = new McpServer({
|
||||
name: "Demo",
|
||||
version: "1.0.0"
|
||||
version: "1.0.0",
|
||||
});
|
||||
|
||||
// Add an addition tool
|
||||
server.tool("add",
|
||||
{ a: z.number(), b: z.number() },
|
||||
async ({ a, b }) => ({
|
||||
content: [{ type: "text", text: String(a + b) }]
|
||||
})
|
||||
);
|
||||
server.tool("add", { a: z.number(), b: z.number() }, async ({ a, b }) => ({
|
||||
content: [{ type: "text", text: String(a + b) }],
|
||||
}));
|
||||
|
||||
// Add a dynamic greeting resource
|
||||
server.resource(
|
||||
"greeting",
|
||||
new ResourceTemplate("greeting://{name}", { list: undefined }),
|
||||
async (uri, { name }) => ({
|
||||
contents: [{
|
||||
contents: [
|
||||
{
|
||||
uri: uri.href,
|
||||
text: `Hello, ${name}!`
|
||||
}]
|
||||
text: `Hello, ${name}!`,
|
||||
},
|
||||
],
|
||||
})
|
||||
);
|
||||
|
||||
@ -99,7 +98,7 @@ The McpServer is your core interface to the MCP protocol. It handles connection
|
||||
```typescript
|
||||
const server = new McpServer({
|
||||
name: "My App",
|
||||
version: "1.0.0"
|
||||
version: "1.0.0",
|
||||
});
|
||||
```
|
||||
|
||||
@ -109,26 +108,26 @@ Resources are how you expose data to LLMs. They're similar to GET endpoints in a
|
||||
|
||||
```typescript
|
||||
// Static resource
|
||||
server.resource(
|
||||
"config",
|
||||
"config://app",
|
||||
async (uri) => ({
|
||||
contents: [{
|
||||
server.resource("config", "config://app", async (uri) => ({
|
||||
contents: [
|
||||
{
|
||||
uri: uri.href,
|
||||
text: "App configuration here"
|
||||
}]
|
||||
})
|
||||
);
|
||||
text: "App configuration here",
|
||||
},
|
||||
],
|
||||
}));
|
||||
|
||||
// Dynamic resource with parameters
|
||||
server.resource(
|
||||
"user-profile",
|
||||
new ResourceTemplate("users://{userId}/profile", { list: undefined }),
|
||||
async (uri, { userId }) => ({
|
||||
contents: [{
|
||||
contents: [
|
||||
{
|
||||
uri: uri.href,
|
||||
text: `Profile data for user ${userId}`
|
||||
}]
|
||||
text: `Profile data for user ${userId}`,
|
||||
},
|
||||
],
|
||||
})
|
||||
);
|
||||
```
|
||||
@ -143,28 +142,26 @@ server.tool(
|
||||
"calculate-bmi",
|
||||
{
|
||||
weightKg: z.number(),
|
||||
heightM: z.number()
|
||||
heightM: z.number(),
|
||||
},
|
||||
async ({ weightKg, heightM }) => ({
|
||||
content: [{
|
||||
content: [
|
||||
{
|
||||
type: "text",
|
||||
text: String(weightKg / (heightM * heightM))
|
||||
}]
|
||||
text: String(weightKg / (heightM * heightM)),
|
||||
},
|
||||
],
|
||||
})
|
||||
);
|
||||
|
||||
// Async tool with external API call
|
||||
server.tool(
|
||||
"fetch-weather",
|
||||
{ city: z.string() },
|
||||
async ({ city }) => {
|
||||
server.tool("fetch-weather", { city: z.string() }, async ({ city }) => {
|
||||
const response = await fetch(`https://api.weather.com/${city}`);
|
||||
const data = await response.text();
|
||||
return {
|
||||
content: [{ type: "text", text: data }]
|
||||
content: [{ type: "text", text: data }],
|
||||
};
|
||||
}
|
||||
);
|
||||
});
|
||||
```
|
||||
|
||||
### Prompts
|
||||
@ -172,19 +169,17 @@ server.tool(
|
||||
Prompts are reusable templates that help LLMs interact with your server effectively:
|
||||
|
||||
```typescript
|
||||
server.prompt(
|
||||
"review-code",
|
||||
{ code: z.string() },
|
||||
({ code }) => ({
|
||||
messages: [{
|
||||
server.prompt("review-code", { code: z.string() }, ({ code }) => ({
|
||||
messages: [
|
||||
{
|
||||
role: "user",
|
||||
content: {
|
||||
type: "text",
|
||||
text: `Please review this code:\n\n${code}`
|
||||
}
|
||||
}]
|
||||
})
|
||||
);
|
||||
text: `Please review this code:\n\n${code}`,
|
||||
},
|
||||
},
|
||||
],
|
||||
}));
|
||||
```
|
||||
|
||||
## Running Your Server
|
||||
@ -201,7 +196,7 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
|
||||
|
||||
const server = new McpServer({
|
||||
name: "example-server",
|
||||
version: "1.0.0"
|
||||
version: "1.0.0",
|
||||
});
|
||||
|
||||
// ... set up server resources, tools, and prompts ...
|
||||
@ -221,7 +216,7 @@ import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
|
||||
|
||||
const server = new McpServer({
|
||||
name: "example-server",
|
||||
version: "1.0.0"
|
||||
version: "1.0.0",
|
||||
});
|
||||
|
||||
// ... set up server resources, tools, and prompts ...
|
||||
@ -254,46 +249,45 @@ To test your server, you can use the [MCP Inspector](mdc:https:/github.com/model
|
||||
A simple server demonstrating resources, tools, and prompts:
|
||||
|
||||
```typescript
|
||||
import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
|
||||
import {
|
||||
McpServer,
|
||||
ResourceTemplate,
|
||||
} from "@modelcontextprotocol/sdk/server/mcp.js";
|
||||
import { z } from "zod";
|
||||
|
||||
const server = new McpServer({
|
||||
name: "Echo",
|
||||
version: "1.0.0"
|
||||
version: "1.0.0",
|
||||
});
|
||||
|
||||
server.resource(
|
||||
"echo",
|
||||
new ResourceTemplate("echo://{message}", { list: undefined }),
|
||||
async (uri, { message }) => ({
|
||||
contents: [{
|
||||
contents: [
|
||||
{
|
||||
uri: uri.href,
|
||||
text: `Resource echo: ${message}`
|
||||
}]
|
||||
text: `Resource echo: ${message}`,
|
||||
},
|
||||
],
|
||||
})
|
||||
);
|
||||
|
||||
server.tool(
|
||||
"echo",
|
||||
{ message: z.string() },
|
||||
async ({ message }) => ({
|
||||
content: [{ type: "text", text: `Tool echo: ${message}` }]
|
||||
})
|
||||
);
|
||||
server.tool("echo", { message: z.string() }, async ({ message }) => ({
|
||||
content: [{ type: "text", text: `Tool echo: ${message}` }],
|
||||
}));
|
||||
|
||||
server.prompt(
|
||||
"echo",
|
||||
{ message: z.string() },
|
||||
({ message }) => ({
|
||||
messages: [{
|
||||
server.prompt("echo", { message: z.string() }, ({ message }) => ({
|
||||
messages: [
|
||||
{
|
||||
role: "user",
|
||||
content: {
|
||||
type: "text",
|
||||
text: `Please process this message: ${message}`
|
||||
}
|
||||
}]
|
||||
})
|
||||
);
|
||||
text: `Please process this message: ${message}`,
|
||||
},
|
||||
},
|
||||
],
|
||||
}));
|
||||
```
|
||||
|
||||
### SQLite Explorer
|
||||
@ -308,7 +302,7 @@ import { z } from "zod";
|
||||
|
||||
const server = new McpServer({
|
||||
name: "SQLite Explorer",
|
||||
version: "1.0.0"
|
||||
version: "1.0.0",
|
||||
});
|
||||
|
||||
// Helper to create DB connection
|
||||
@ -316,58 +310,56 @@ const getDb = () => {
|
||||
const db = new sqlite3.Database("database.db");
|
||||
return {
|
||||
all: promisify<string, any[]>(db.all.bind(db)),
|
||||
close: promisify(db.close.bind(db))
|
||||
close: promisify(db.close.bind(db)),
|
||||
};
|
||||
};
|
||||
|
||||
server.resource(
|
||||
"schema",
|
||||
"schema://main",
|
||||
async (uri) => {
|
||||
server.resource("schema", "schema://main", async (uri) => {
|
||||
const db = getDb();
|
||||
try {
|
||||
const tables = await db.all(
|
||||
"SELECT sql FROM sqlite_master WHERE type='table'"
|
||||
);
|
||||
return {
|
||||
contents: [{
|
||||
contents: [
|
||||
{
|
||||
uri: uri.href,
|
||||
text: tables.map((t: {sql: string}) => t.sql).join("\n")
|
||||
}]
|
||||
text: tables.map((t: { sql: string }) => t.sql).join("\n"),
|
||||
},
|
||||
],
|
||||
};
|
||||
} finally {
|
||||
await db.close();
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
server.tool(
|
||||
"query",
|
||||
{ sql: z.string() },
|
||||
async ({ sql }) => {
|
||||
server.tool("query", { sql: z.string() }, async ({ sql }) => {
|
||||
const db = getDb();
|
||||
try {
|
||||
const results = await db.all(sql);
|
||||
return {
|
||||
content: [{
|
||||
content: [
|
||||
{
|
||||
type: "text",
|
||||
text: JSON.stringify(results, null, 2)
|
||||
}]
|
||||
text: JSON.stringify(results, null, 2),
|
||||
},
|
||||
],
|
||||
};
|
||||
} catch (err: unknown) {
|
||||
const error = err as Error;
|
||||
return {
|
||||
content: [{
|
||||
content: [
|
||||
{
|
||||
type: "text",
|
||||
text: `Error: ${error.message}`
|
||||
}],
|
||||
isError: true
|
||||
text: `Error: ${error.message}`,
|
||||
},
|
||||
],
|
||||
isError: true,
|
||||
};
|
||||
} finally {
|
||||
await db.close();
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
```
|
||||
|
||||
## Advanced Usage
|
||||
@ -381,32 +373,36 @@ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
||||
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
||||
import {
|
||||
ListPromptsRequestSchema,
|
||||
GetPromptRequestSchema
|
||||
GetPromptRequestSchema,
|
||||
} from "@modelcontextprotocol/sdk/types.js";
|
||||
|
||||
const server = new Server(
|
||||
{
|
||||
name: "example-server",
|
||||
version: "1.0.0"
|
||||
version: "1.0.0",
|
||||
},
|
||||
{
|
||||
capabilities: {
|
||||
prompts: {}
|
||||
}
|
||||
prompts: {},
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
server.setRequestHandler(ListPromptsRequestSchema, async () => {
|
||||
return {
|
||||
prompts: [{
|
||||
prompts: [
|
||||
{
|
||||
name: "example-prompt",
|
||||
description: "An example prompt template",
|
||||
arguments: [{
|
||||
arguments: [
|
||||
{
|
||||
name: "arg1",
|
||||
description: "Example argument",
|
||||
required: true
|
||||
}]
|
||||
}]
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
});
|
||||
|
||||
@ -416,13 +412,15 @@ server.setRequestHandler(GetPromptRequestSchema, async (request) => {
|
||||
}
|
||||
return {
|
||||
description: "Example prompt",
|
||||
messages: [{
|
||||
messages: [
|
||||
{
|
||||
role: "user",
|
||||
content: {
|
||||
type: "text",
|
||||
text: "Example prompt text"
|
||||
}
|
||||
}]
|
||||
text: "Example prompt text",
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
});
|
||||
|
||||
@ -440,20 +438,20 @@ import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js"
|
||||
|
||||
const transport = new StdioClientTransport({
|
||||
command: "node",
|
||||
args: ["server.js"]
|
||||
args: ["server.js"],
|
||||
});
|
||||
|
||||
const client = new Client(
|
||||
{
|
||||
name: "example-client",
|
||||
version: "1.0.0"
|
||||
version: "1.0.0",
|
||||
},
|
||||
{
|
||||
capabilities: {
|
||||
prompts: {},
|
||||
resources: {},
|
||||
tools: {}
|
||||
}
|
||||
tools: {},
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
@ -464,7 +462,7 @@ const prompts = await client.listPrompts();
|
||||
|
||||
// Get a prompt
|
||||
const prompt = await client.getPrompt("example-prompt", {
|
||||
arg1: "value"
|
||||
arg1: "value",
|
||||
});
|
||||
|
||||
// List resources
|
||||
@ -477,8 +475,8 @@ const resource = await client.readResource("file:///example.txt");
|
||||
const result = await client.callTool({
|
||||
name: "example-tool",
|
||||
arguments: {
|
||||
arg1: "value"
|
||||
}
|
||||
arg1: "value",
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user