u
This commit is contained in:
@@ -240,7 +240,7 @@ export function createBashTool(googleAuthId) {
|
||||
|
||||
| Consideration | Ephemeral (`docker run --rm`) | Persistent Container (`docker exec`) |
|
||||
| :--- | :--- | :--- |
|
||||
| **Startup Overhead** | ~200–400ms per command | ~20–50ms per command |
|
||||
| **Startup Overhead** | ~200-400ms per command | ~20-50ms per command |
|
||||
| **State Cleanliness** | Completely fresh OS environment every call | Processes/background jobs remain running |
|
||||
| **Lifecycle Complexity** | None. Docker handles lifecycle and cleanup | Requires container pool management and reaper |
|
||||
| **Failure Recovery** | Automatic | If container crashes, must be recreated |
|
||||
|
||||
@@ -5,7 +5,7 @@ Public. No cookie required.
|
||||
POS discovery and pairing
|
||||
|
||||
Special API for POS bind and sync.
|
||||
- Step 1 (Discovery): `authCode` length 1–4. Returns certificate fingerprints, serial number, and mandantId.
|
||||
- Step 1 (Discovery): `authCode` length 1-4. Returns certificate fingerprints, serial number, and mandantId.
|
||||
- Step 2 (Pairing): `authCode` length 6 (pairingpin from posterminal). Verifies the pairingpin, sets token, paired_at, and clientserial, revokes the pairingpin, and returns device credentials and company metadata.
|
||||
|
||||
|
||||
|
||||
2
mcp.md
2
mcp.md
@@ -226,7 +226,7 @@ server.registerTool('search-articles', {
|
||||
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).'),
|
||||
limit: z.number().int().min(1).max(20).nullable().optional().describe('Window size 1-20 (default 3).'),
|
||||
},
|
||||
}, async ({ searchquery, excludewords, offset, limit }) => { ... });
|
||||
```
|
||||
|
||||
@@ -115,8 +115,8 @@ const tokenVerifier = {
|
||||
const scopes = typeof decoded.scope === 'string'
|
||||
? decoded.scope.split(' ')
|
||||
: Array.isArray(decoded.scope)
|
||||
? decoded.scope
|
||||
: ['mcp:tools'];
|
||||
? decoded.scope
|
||||
: ['mcp:tools'];
|
||||
|
||||
return {
|
||||
token,
|
||||
@@ -237,7 +237,7 @@ function createDashbackMcpServer({ user }) {
|
||||
searchquery: z.string().nullable().optional().describe(TOOL_PARAMETER_DESCRIPTIONS.search_articles?.searchquery || 'Keywords matching name, brand, EAN, SKU, or supplier SKU (AND logic).'),
|
||||
excludewords: z.string().nullable().optional().describe(TOOL_PARAMETER_DESCRIPTIONS.search_articles?.excludewords || 'Keywords to exclude (AND logic).'),
|
||||
offset: z.number().int().min(0).nullable().optional().describe(TOOL_PARAMETER_DESCRIPTIONS.search_articles?.offset || 'Pagination offset (default 0).'),
|
||||
limit: z.number().int().min(1).max(20).nullable().optional().describe(TOOL_PARAMETER_DESCRIPTIONS.search_articles?.limit || 'Window size 1–20 (default 3).'),
|
||||
limit: z.number().int().min(1).max(20).nullable().optional().describe(TOOL_PARAMETER_DESCRIPTIONS.search_articles?.limit || 'Window size 1-20 (default 3).'),
|
||||
},
|
||||
},
|
||||
async ({ searchquery = '', excludewords = '', offset = 0, limit = 3 } = {}) => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// @applet-input-schema {"type":"object","properties":{"query":{"type":"string","title":"Category name contains","default":"","description":"Case-insensitive substring match on the category name. Leave empty to include every category."},"limit":{"type":"integer","title":"Max rows","default":100,"minimum":1,"maximum":500},"sortBy":{"type":"string","title":"Sort by","default":"articles","enum":["articles","name","depth"],"description":"articles = most articles first, name = A–Z, depth = tree depth then name."}}}
|
||||
// @applet-input-schema {"type":"object","properties":{"query":{"type":"string","title":"Category name contains","default":"","description":"Case-insensitive substring match on the category name. Leave empty to include every category."},"limit":{"type":"integer","title":"Max rows","default":100,"minimum":1,"maximum":500},"sortBy":{"type":"string","title":"Sort by","default":"articles","enum":["articles","name","depth"],"description":"articles = most articles first, name = A-Z, depth = tree depth then name."}}}
|
||||
// @applet-output-schema id:integer;name:string;depth:integer;articles:integer;children:integer
|
||||
// @applet-description "Category inventory — every category with its article count and child count."
|
||||
//
|
||||
|
||||
@@ -21,7 +21,7 @@ import {
|
||||
* call with the image attached. This tool is that bridge:
|
||||
*
|
||||
* - 1 image → resized to fit 400×400 and sent as a single WebP.
|
||||
* - 2–9 → composited into a labelled grid (2x1/3x1/2x2/3x2/3x3) with the file name
|
||||
* - 2-9 → composited into a labelled grid (2x1/3x1/2x2/3x2/3x3) with the file name
|
||||
* printed under each cell, so one cheap call can compare many candidates.
|
||||
* - Database images are addressed as `image/<fullHash>` and fetched from `/image/:hash`.
|
||||
*
|
||||
@@ -314,7 +314,7 @@ export function createAnalyzeImageTool({ googleAuthId, model }) {
|
||||
const inputs = extractImageInputs({ paths });
|
||||
if (inputs.length === 0) {
|
||||
throw new ToolError(
|
||||
'analyze_image requires "paths": an array of 1–9 VFS paths (e.g. ["images/a-1.avif"]) ' +
|
||||
'analyze_image requires "paths": an array of 1-9 VFS paths (e.g. ["images/a-1.avif"]) ' +
|
||||
'or database paths (e.g. ["image/<fullHash>"]). Get candidates from search_images first.'
|
||||
);
|
||||
}
|
||||
|
||||
@@ -173,7 +173,7 @@ export const TOOL_PARAMETER_DESCRIPTIONS = {
|
||||
|
||||
analyze_image: {
|
||||
note: NOTE_DESC,
|
||||
paths: '1–9 VFS paths or DB paths ("image/<hash>").',
|
||||
paths: '1-9 VFS paths or DB paths ("image/<hash>").',
|
||||
prompt: 'Inspection criteria or question.',
|
||||
grid: 'Grid layout or null for auto.',
|
||||
},
|
||||
@@ -216,7 +216,7 @@ export const TOOL_PARAMETER_DESCRIPTIONS = {
|
||||
searchquery: 'Keywords matching name, brand, EAN, SKU, or supplier SKU (AND logic).',
|
||||
excludewords: 'Keywords to exclude (AND logic).',
|
||||
offset: 'Pagination offset (default 0).',
|
||||
limit: 'Window size 1–20 (default 3).',
|
||||
limit: 'Window size 1-20 (default 3).',
|
||||
},
|
||||
|
||||
edit_image: {
|
||||
@@ -243,7 +243,7 @@ export const TOOL_PARAMETER_DESCRIPTIONS = {
|
||||
taxRate: 'VAT percentage (default 19).',
|
||||
amount: 'Price amount when paired with "from".',
|
||||
from: '"gross" (default) or "net".',
|
||||
precision: 'Net price API decimal precision 2–8 (default 6).',
|
||||
precision: 'Net price API decimal precision 2-8 (default 6).',
|
||||
items: 'Array of prices or calculation objects for batch processing.',
|
||||
},
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ export function buildClientStep2(authCode, config) {
|
||||
* summary: POS discovery and pairing
|
||||
* description: |
|
||||
* Special API for POS bind and sync.
|
||||
* - Step 1 (Discovery): `authCode` length 1–4. Returns certificate fingerprints, serial number, and mandantId.
|
||||
* - Step 1 (Discovery): `authCode` length 1-4. Returns certificate fingerprints, serial number, and mandantId.
|
||||
* - Step 2 (Pairing): `authCode` length 6 (pairingpin from posterminal). Verifies the pairingpin, sets token, paired_at, and clientserial, revokes the pairingpin, and returns device credentials and company metadata.
|
||||
* security: []
|
||||
* x-markdown: pos/client.md
|
||||
|
||||
Reference in New Issue
Block a user