Zum Inhalt springen

Resources

Resources liefern lokale, deterministische Daten via SQLite. Im Gegensatz zu Tools (die Remote-REST-APIs aufrufen) fragen Resources lokale Datenbanken ab. Sie sind ideal fuer per Bulk-Download bezogene Open Data wie Handelsregister, Fahrplaene und Sanktionslisten.

Eine Resource ist eine SQLite-Datenbank, die mit einem Schema gebuendelt wird. Die FlowMCP Runtime laedt die .db-Datei via sql.js (eine reine JavaScript/WASM SQLite-Implementierung) und stellt jede definierte Abfrage als MCP Resource bereit. Keine Netzwerkaufrufe, keine API-Keys, keine Rate Limits.

Resources sind ideal wenn:

  • Daten gross sind und sich selten aendern (Handelsregister, Geodaten)
  • Offline-Zugriff erforderlich ist
  • Latenz nahe null sein muss
  • Der Datensatz oeffentlich als Bulk-Download verfuegbar ist
AspektToolsResources
DatenquelleRemote REST APILokale SQLite-Datenbank
LatenzNetzwerkabhaengigSofort
VerfuegbarkeitErfordert InternetImmer verfuegbar
DatenaktualitaetEchtzeitSnapshot (periodische Aktualisierung)
API-Key erforderlichMeist jaNein
AnwendungsfallLive-Preise, On-Chain-DatenHandelsregister, Fahrplandaten

Resources werden in main.resources deklariert. Jede Resource zeigt auf eine SQLite-Datenbank und definiert benannte Abfragen mit SQL und Parametern:

export const main = {
namespace: 'offeneregister',
name: 'OffeneRegister',
version: '3.0.0',
root: '',
tools: {},
resources: {
companiesDb: {
source: 'sqlite',
database: 'companies.db',
origin: 'global',
description: 'German company register (OffeneRegister)',
queries: {
searchCompanies: {
sql: "SELECT * FROM companies WHERE name LIKE ? LIMIT ?",
description: 'Search companies by name',
parameters: {
searchTerm: { type: 'string', required: true },
limit: { type: 'number', required: false, default: 10 }
},
output: { columns: ['company_number', 'name', 'registered_address', 'status'] }
}
}
}
}
}

Das origin-Feld bestimmt, wo die Runtime nach der .db-Datei sucht:

OriginPfadaufloesungIdeal fuer
global~/.flowmcp/data/{database}Geteilte Datensaetze, die projektuebergreifend genutzt werden
project.flowmcp/data/{database}Projektspezifische Daten
inlineRelativ zur Schema-DateiEigenstaendige Schemas mit kleinen Datenbanken

Komplexe Abfragen koennen Common Table Expressions (CTEs) fuer mehrstufige Filterung verwenden:

WITH recent AS (
SELECT * FROM companies WHERE registered_date > ?
)
SELECT * FROM recent WHERE status = 'active' LIMIT ?

CTEs muessen immer noch mit einer schreibgeschuetzten Anweisung beginnen. Die gleichen SQL-Sicherheitsregeln gelten: kein INSERT, UPDATE, DELETE oder andere Schreiboperationen irgendwo in der CTE-Kette.

EinschraenkungWertBegruendung
Max Resources pro Schema2Resources sind ergaenzend, nicht primaerer Output
Max Abfragen pro Resource87 definierte + 1 automatisch injizierte freeQuery
getSchema-AbfrageErforderlichMuss die Datenbank-Tabellenstruktur zurueckgeben
SQL-OperationenNur SELECTSchreibschutz-Durchsetzung — kein INSERT/UPDATE/DELETE
Parameter-PlatzhalterNur ?Verhindert SQL-Injection
QuelltypNur sqliteZukuenftige Versionen koennten andere Quellen hinzufuegen
Datenbank-Dateiendung.dbStandard SQLite-Endung

Zwei Abfragen werden automatisch von der Runtime behandelt:

  • getSchema — Du musst diese Abfrage definieren. Sie gibt die Datenbankstruktur zurueck, damit KI-Agenten verfuegbare Tabellen und Spalten verstehen koennen.
  • freeQuery — Automatisch von der Runtime injiziert. Erlaubt KI-Agenten, beliebige SELECT-Abfragen innerhalb der schreibgeschuetzten Sandbox auszufuehren. Dies zaehlt zum 8-Abfragen-Limit.

Ein OffeneRegister-Schema mit einer SQLite Resource zur Abfrage des deutschen Handelsregisters:

export const main = {
namespace: 'offeneregister',
name: 'OffeneRegister',
description: 'German company register — local SQLite database',
version: '3.0.0',
tags: ['open-data', 'germany', 'companies'],
root: '',
tools: {},
resources: {
companiesDb: {
source: 'sqlite',
database: 'openregister.db',
origin: 'global',
description: 'OffeneRegister company database (2.5 GB)',
queries: {
getSchema: {
sql: "SELECT sql FROM sqlite_master WHERE type='table'",
description: 'Get database schema',
parameters: {},
output: { columns: ['sql'] }
},
searchCompanies: {
sql: "SELECT company_number, name, registered_address, status FROM companies WHERE name LIKE ? LIMIT ?",
description: 'Full-text search for companies by name',
parameters: {
searchTerm: { type: 'string', required: true, description: 'Company name (use % for wildcards)' },
limit: { type: 'number', required: false, default: 10, description: 'Max results' }
},
output: { columns: ['company_number', 'name', 'registered_address', 'status'] }
},
getByNumber: {
sql: "SELECT * FROM companies WHERE company_number = ?",
description: 'Look up a company by its registration number',
parameters: {
companyNumber: { type: 'string', required: true, description: 'Company registration number' }
},
output: { columns: ['company_number', 'name', 'registered_address', 'status', 'registered_date'] }
},
recentRegistrations: {
sql: "SELECT company_number, name, registered_date FROM companies ORDER BY registered_date DESC LIMIT ?",
description: 'List the most recently registered companies',
parameters: {
limit: { type: 'number', required: false, default: 20, description: 'Max results' }
},
output: { columns: ['company_number', 'name', 'registered_date'] }
}
}
}
}
}

Dieses Schema hat keine Tools und keine root-URL — es arbeitet vollstaendig mit lokalen Daten. Der KI-Agent kann Unternehmen suchen, nach Nummer nachschlagen oder kuerzliche Registrierungen durchblaettern, ohne jeglichen Netzwerkzugriff.

Resources werden durch die Regeln RES001-RES023 validiert. Wichtige Regeln:

CodeRegel
RES003Maximal 2 Resources pro Schema
RES005Source muss 'sqlite' sein
RES006Datenbankpfad muss auf .db enden
RES008Maximal 8 Abfragen pro Resource (7 + freeQuery)
RES012SQL muss mit SELECT beginnen (oder WITH fuer CTEs)
RES013SQL darf keine blockierten Muster enthalten
RES014SQL muss ?-Platzhalter verwenden
RES015Platzhalter-Anzahl muss mit Parameter-Anzahl uebereinstimmen

Siehe Validierungsregeln fuer die vollstaendige Liste.