u
This commit is contained in:
53
mcp.md
53
mcp.md
@@ -6,12 +6,12 @@ This document explains the architecture, database schema, OAuth 2.1 authenticati
|
||||
|
||||
## 1. Overview & Purpose
|
||||
|
||||
The Dashback backend provides an MCP server running over **Streamable HTTP** at `/mcp`. It exposes the internal **`dashback_request`** tool (the same tool provided to the local agent via `src/tools/dashback-request.js`) to external MCP clients such as:
|
||||
The Dashback backend provides an MCP server running over **Streamable HTTP** at `/mcp`. It exposes internal tools (`dashback_request`, `dash-subagent`, and `search-articles`) to external MCP clients such as:
|
||||
- Visual Studio Code / GitHub Copilot
|
||||
- Claude Desktop
|
||||
- Cursor / Windsurf
|
||||
|
||||
All operations executed via `dashback_request` are cryptographically authenticated and scoped to the authorizing Dashback user (`google_auth_id`) and their selected company.
|
||||
All operations executed via these tools are cryptographically authenticated and scoped to the authorizing Dashback user (`google_auth_id`) and their selected company.
|
||||
|
||||
---
|
||||
|
||||
@@ -176,9 +176,12 @@ The client connects to `/mcp` with `Authorization: Bearer <access_token>`.
|
||||
|
||||
---
|
||||
|
||||
## 5. The Exposed Tool: `dashback_request`
|
||||
## 5. The Exposed Tools
|
||||
|
||||
The MCP server registers the exact same tool exposed to the internal local agent (`src/tools/dashback-request.js`):
|
||||
The MCP server exposes three tools to external clients:
|
||||
|
||||
### 1. `dashback_request`
|
||||
Performs HTTP requests against the Dashback API:
|
||||
|
||||
```javascript
|
||||
server.registerTool('dashback_request', {
|
||||
@@ -191,14 +194,44 @@ server.registerTool('dashback_request', {
|
||||
body: z.union([z.string(), z.record(z.string(), z.any())]).nullable().optional(),
|
||||
note: z.string().nullable().optional(),
|
||||
},
|
||||
}, async ({ method = 'GET', path, query = null, body = null, note }) => {
|
||||
// Generates a 5-minute JWT signed with env.jwtSecret scoped to the authenticated user's ID
|
||||
// Performs fetch against http://127.0.0.1:<port>/api<path>
|
||||
// Returns status and truncated body (up to 20,000 characters)
|
||||
});
|
||||
}, async ({ method = 'GET', path, query = null, body = null, note }) => { ... });
|
||||
```
|
||||
|
||||
Because the internal fetch uses a JWT containing the user's `google_auth_id`, all Dashback route-level permissions, company isolation (`req.user.selectedCompanyId`), audit logging, and data scoping apply automatically.
|
||||
### 2. `dash-subagent`
|
||||
Delegates a self-contained task to an isolated subagent with access to Dashback tools and VFS:
|
||||
|
||||
```javascript
|
||||
server.registerTool('dash-subagent', {
|
||||
title: 'Dashback Subagent',
|
||||
description: 'Delegate a task to an isolated subagent with access to Dashback tools and VFS.',
|
||||
inputSchema: {
|
||||
task: z.string().describe('Specific instructions and goal for the subagent.'),
|
||||
skills: z.array(z.string()).nullable().optional().describe('Array of SKILL names or slugs to inject.'),
|
||||
conversation_id: z.number().int().positive().nullable().optional().describe('Existing subagent conversation ID to follow up on, or null to create a new one.'),
|
||||
max_iterations: z.number().int().min(1).max(30).nullable().optional().describe('Safety bound on tool loops (default 15, max 30).'),
|
||||
model: z.string().nullable().optional().describe('Optional OpenRouter model override.'),
|
||||
note: z.string().nullable().optional(),
|
||||
},
|
||||
}, async ({ task, skills, conversation_id, max_iterations, model, note }, extra) => { ... });
|
||||
```
|
||||
|
||||
### 3. `search-articles`
|
||||
Searches articles across name, brand, EAN, SKU, and supplier SKU (AND logic, ordered by name):
|
||||
|
||||
```javascript
|
||||
server.registerTool('search-articles', {
|
||||
title: 'Search Articles',
|
||||
description: 'Search articles by name, brand, EAN, SKU, or supplier SKU (AND logic, ordered by name).',
|
||||
inputSchema: {
|
||||
searchquery: z.string().nullable().optional().describe('Keywords matching name, brand, EAN, SKU, or supplier SKU (AND logic).'),
|
||||
excludewords: z.string().nullable().optional().describe('Keywords to exclude (AND logic).'),
|
||||
offset: z.number().int().min(0).nullable().optional().describe('Pagination offset (default 0).'),
|
||||
limit: z.number().int().min(1).max(20).nullable().optional().describe('Window size 1–20 (default 3).'),
|
||||
},
|
||||
}, async ({ searchquery, excludewords, offset, limit }) => { ... });
|
||||
```
|
||||
|
||||
Because all tool executions use credentials scoped to the authenticated user's `google_auth_id`, all Dashback route-level permissions, company isolation (`req.user.selectedCompanyId`), audit logging, and data scoping apply automatically.
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user