feat(mcp): paginate record lists and describe document inputs
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import { limitFromArgs, offsetFromArgs, paginatedResult, paginationProperties } from "../pagination"
|
||||
import { and, desc, eq, ilike, or } from "drizzle-orm"
|
||||
import {
|
||||
branches,
|
||||
@@ -14,11 +15,6 @@ import {
|
||||
} from "../../../db/schema"
|
||||
import { McpTool } from "../types"
|
||||
|
||||
const limitFromArgs = (args: Record<string, unknown>, fallback = 25) => {
|
||||
const raw = Number(args.limit ?? fallback)
|
||||
if (!Number.isFinite(raw)) return fallback
|
||||
return Math.min(Math.max(Math.trunc(raw), 1), 100)
|
||||
}
|
||||
|
||||
const stringArg = (args: Record<string, unknown>, key: string) => {
|
||||
const value = args[key]
|
||||
@@ -71,7 +67,7 @@ export const masterdataTools: McpTool[] = [
|
||||
type: "object",
|
||||
properties: {
|
||||
query: { type: "string", description: "Suchtext für Name, Lieferantennummer oder Notizen." },
|
||||
limit: { type: "number", minimum: 1, maximum: 100 },
|
||||
...paginationProperties,
|
||||
},
|
||||
},
|
||||
async handler(context, args) {
|
||||
@@ -91,10 +87,11 @@ export const masterdataTools: McpTool[] = [
|
||||
.select()
|
||||
.from(vendors)
|
||||
.where(and(...conditions))
|
||||
.orderBy(vendors.name)
|
||||
.limit(limitFromArgs(args))
|
||||
.orderBy(vendors.name, vendors.id)
|
||||
.limit(limitFromArgs(args) + 1)
|
||||
.offset(offsetFromArgs(args))
|
||||
|
||||
return { rows }
|
||||
return paginatedResult(rows, args)
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -132,7 +129,7 @@ export const masterdataTools: McpTool[] = [
|
||||
query: { type: "string", description: "Suchtext für Name, E-Mail, Telefon, Rolle oder Notizen." },
|
||||
customer: { type: "number" },
|
||||
vendor: { type: "number" },
|
||||
limit: { type: "number", minimum: 1, maximum: 100 },
|
||||
...paginationProperties,
|
||||
},
|
||||
},
|
||||
async handler(context, args) {
|
||||
@@ -161,10 +158,11 @@ export const masterdataTools: McpTool[] = [
|
||||
.select()
|
||||
.from(contacts)
|
||||
.where(and(...conditions))
|
||||
.orderBy(contacts.fullName)
|
||||
.limit(limitFromArgs(args))
|
||||
.orderBy(contacts.fullName, contacts.id)
|
||||
.limit(limitFromArgs(args) + 1)
|
||||
.offset(offsetFromArgs(args))
|
||||
|
||||
return { rows }
|
||||
return paginatedResult(rows, args)
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -176,7 +174,7 @@ export const masterdataTools: McpTool[] = [
|
||||
type: "object",
|
||||
properties: {
|
||||
query: { type: "string", description: "Suchtext für Name, Artikelnummer, Hersteller, EAN, Barcode oder Beschreibung." },
|
||||
limit: { type: "number", minimum: 1, maximum: 100 },
|
||||
...paginationProperties,
|
||||
},
|
||||
},
|
||||
async handler(context, args) {
|
||||
@@ -200,10 +198,11 @@ export const masterdataTools: McpTool[] = [
|
||||
.select()
|
||||
.from(products)
|
||||
.where(and(...conditions))
|
||||
.orderBy(products.name)
|
||||
.limit(limitFromArgs(args))
|
||||
.orderBy(products.name, products.id)
|
||||
.limit(limitFromArgs(args) + 1)
|
||||
.offset(offsetFromArgs(args))
|
||||
|
||||
return { rows }
|
||||
return paginatedResult(rows, args)
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -239,7 +238,7 @@ export const masterdataTools: McpTool[] = [
|
||||
type: "object",
|
||||
properties: {
|
||||
query: { type: "string", description: "Suchtext für Name, Leistungsnummer oder Beschreibung." },
|
||||
limit: { type: "number", minimum: 1, maximum: 100 },
|
||||
...paginationProperties,
|
||||
},
|
||||
},
|
||||
async handler(context, args) {
|
||||
@@ -258,10 +257,11 @@ export const masterdataTools: McpTool[] = [
|
||||
.select()
|
||||
.from(services)
|
||||
.where(and(...conditions))
|
||||
.orderBy(services.name)
|
||||
.limit(limitFromArgs(args))
|
||||
.orderBy(services.name, services.id)
|
||||
.limit(limitFromArgs(args) + 1)
|
||||
.offset(offsetFromArgs(args))
|
||||
|
||||
return { rows }
|
||||
return paginatedResult(rows, args)
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -299,7 +299,7 @@ export const masterdataTools: McpTool[] = [
|
||||
query: { type: "string", description: "Suchtext für Nummer, Name oder Beschreibung." },
|
||||
branch: { type: "number" },
|
||||
project: { type: "number" },
|
||||
limit: { type: "number", minimum: 1, maximum: 100 },
|
||||
...paginationProperties,
|
||||
},
|
||||
},
|
||||
async handler(context, args) {
|
||||
@@ -323,10 +323,11 @@ export const masterdataTools: McpTool[] = [
|
||||
.select()
|
||||
.from(costcentres)
|
||||
.where(and(...conditions))
|
||||
.orderBy(costcentres.number)
|
||||
.limit(limitFromArgs(args))
|
||||
.orderBy(costcentres.number, costcentres.id)
|
||||
.limit(limitFromArgs(args) + 1)
|
||||
.offset(offsetFromArgs(args))
|
||||
|
||||
return { rows }
|
||||
return paginatedResult(rows, args)
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -362,7 +363,7 @@ export const masterdataTools: McpTool[] = [
|
||||
type: "object",
|
||||
properties: {
|
||||
query: { type: "string", description: "Suchtext für Nummer, Name oder Beschreibung." },
|
||||
limit: { type: "number", minimum: 1, maximum: 100 },
|
||||
...paginationProperties,
|
||||
},
|
||||
},
|
||||
async handler(context, args) {
|
||||
@@ -382,10 +383,11 @@ export const masterdataTools: McpTool[] = [
|
||||
.select()
|
||||
.from(branches)
|
||||
.where(and(...conditions))
|
||||
.orderBy(branches.name)
|
||||
.limit(limitFromArgs(args))
|
||||
.orderBy(branches.name, branches.id)
|
||||
.limit(limitFromArgs(args) + 1)
|
||||
.offset(offsetFromArgs(args))
|
||||
|
||||
return { rows }
|
||||
return paginatedResult(rows, args)
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -398,7 +400,7 @@ export const masterdataTools: McpTool[] = [
|
||||
properties: {
|
||||
query: { type: "string", description: "Suchtext für Name oder Beschreibung." },
|
||||
branch: { type: "number" },
|
||||
limit: { type: "number", minimum: 1, maximum: 100 },
|
||||
...paginationProperties,
|
||||
},
|
||||
},
|
||||
async handler(context, args) {
|
||||
@@ -419,10 +421,11 @@ export const masterdataTools: McpTool[] = [
|
||||
.select()
|
||||
.from(teams)
|
||||
.where(and(...conditions))
|
||||
.orderBy(teams.name)
|
||||
.limit(limitFromArgs(args))
|
||||
.orderBy(teams.name, teams.id)
|
||||
.limit(limitFromArgs(args) + 1)
|
||||
.offset(offsetFromArgs(args))
|
||||
|
||||
return { rows }
|
||||
return paginatedResult(rows, args)
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -434,7 +437,7 @@ export const masterdataTools: McpTool[] = [
|
||||
type: "object",
|
||||
properties: {
|
||||
query: { type: "string", description: "Suchtext für Name, Kennzeichen, FIN oder Farbe." },
|
||||
limit: { type: "number", minimum: 1, maximum: 100 },
|
||||
...paginationProperties,
|
||||
},
|
||||
},
|
||||
async handler(context, args) {
|
||||
@@ -455,10 +458,11 @@ export const masterdataTools: McpTool[] = [
|
||||
.select()
|
||||
.from(vehicles)
|
||||
.where(and(...conditions))
|
||||
.orderBy(vehicles.name)
|
||||
.limit(limitFromArgs(args))
|
||||
.orderBy(vehicles.name, vehicles.id)
|
||||
.limit(limitFromArgs(args) + 1)
|
||||
.offset(offsetFromArgs(args))
|
||||
|
||||
return { rows }
|
||||
return paginatedResult(rows, args)
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -471,7 +475,7 @@ export const masterdataTools: McpTool[] = [
|
||||
properties: {
|
||||
query: { type: "string", description: "Suchtext für Name, Artikelnummer, Seriennummer, Hersteller oder Beschreibung." },
|
||||
vendor: { type: "number" },
|
||||
limit: { type: "number", minimum: 1, maximum: 100 },
|
||||
...paginationProperties,
|
||||
},
|
||||
},
|
||||
async handler(context, args) {
|
||||
@@ -496,10 +500,11 @@ export const masterdataTools: McpTool[] = [
|
||||
.select()
|
||||
.from(inventoryitems)
|
||||
.where(and(...conditions))
|
||||
.orderBy(inventoryitems.name)
|
||||
.limit(limitFromArgs(args))
|
||||
.orderBy(inventoryitems.name, inventoryitems.id)
|
||||
.limit(limitFromArgs(args) + 1)
|
||||
.offset(offsetFromArgs(args))
|
||||
|
||||
return { rows }
|
||||
return paginatedResult(rows, args)
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -535,7 +540,7 @@ export const masterdataTools: McpTool[] = [
|
||||
type: "object",
|
||||
properties: {
|
||||
query: { type: "string", description: "Suchtext für Name, Singular, Plural oder Kürzel." },
|
||||
limit: { type: "number", minimum: 1, maximum: 100 },
|
||||
...paginationProperties,
|
||||
},
|
||||
},
|
||||
async handler(context, args) {
|
||||
@@ -552,10 +557,11 @@ export const masterdataTools: McpTool[] = [
|
||||
ilike(units.short, `%${query}%`)
|
||||
)
|
||||
: undefined)
|
||||
.orderBy(units.name)
|
||||
.limit(limitFromArgs(args))
|
||||
.orderBy(units.name, units.id)
|
||||
.limit(limitFromArgs(args) + 1)
|
||||
.offset(offsetFromArgs(args))
|
||||
|
||||
return { rows }
|
||||
return paginatedResult(rows, args)
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user