
Fdcnal Usda Fooddata Central Agent
- 1 installs
- 48 repo stars
- Updated April 10, 2026
- aiagenta2z/onekey-gateway
fdcnal-usda-fooddata-central-agent is a Claude Code skill that wraps the USDA FoodData Central REST API through the OneKey Agent Gateway to fetch nutrient data.
About
fdcnal-usda-fooddata-central-agent is a Claude Code skill that wraps the USDA FoodData Central (FDC) REST API through the OneKey Agent Gateway. It provides scripts to search foods, list foods, and fetch nutrient details by FDC ID. A developer uses it when integrating USDA nutrient data into an application.
- Wraps the USDA FoodData Central REST API via the OneKey Agent Gateway
- Ships Node, Python, and TypeScript scripts for search, list, and fetch-by-ID
- Exposes get_foods_multiple, get_food_by_id, list_foods, and search_foods
Fdcnal Usda Fooddata Central Agent by the numbers
- 1 all-time installs (skills.sh)
- Ranked #3,836 of 4,347 Backend & APIs skills by installs in the Skillselion catalog
- Data as of Jul 7, 2026 (Skillselion catalog sync)
fdcnal-usda-fooddata-central-agent capabilities & compatibility
Requires a USDA FDC or OneKey Gateway (DEEPNLP_ONEKEY_ROUTER_ACCESS) access key
- Capabilities
- api integration · food data lookup · nutrient search
- Use cases
- api development · research
- Pricing
- Bring your own API key
What fdcnal-usda-fooddata-central-agent says it does
The FoodData Central API provides REST access to FoodData Central (FDC), assisting developers in incorporating nutrient data into their applications.
Auto-generated skill for OneKey Agent Gateway registered agent `fdcnal/usda-fooddata-central-agent` based on its `api_list` from registered API metas.
Returns a list of foods that matched search (query) keywords
npx skills add https://github.com/aiagenta2z/onekey-gateway --skill fdcnal-usda-fooddata-central-agentAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 1 |
|---|---|
| repo stars | ★ 48 |
| Last updated | April 10, 2026 |
| Repository | aiagenta2z/onekey-gateway ↗ |
What it does
Integrate USDA FoodData Central nutrient data into an application via search and fetch calls.
Who is it for?
Pulling USDA nutrient and branded-food data into an app
When should I use this skill?
Incorporating USDA FoodData Central nutrient data into an application
What you get
App code that queries and retrieves USDA nutrient data by search or FDC ID
- API call scripts (JS/Python/TS)
By the numbers
- 4 exposed APIs (get_foods_multiple, get_food_by_id, list_foods, search_foods)
- scripts in 3 languages (JS, Python, TS)
Files
fdcnal-usda-fooddata-central-agent
Auto-generated skill for OneKey Agent Gateway registered agent fdcnal/usda-fooddata-central-agent based on its api_list from registered API metas. Available to use in CLIs, Skills, Rest APIs, and more agent preferred formats.
Quick Start
Set the API providers access key `` or the registered OneKey Gateway access key DEEPNLP_ONEKEY_ROUTER_ACCESS from AI Agent Marketplace.
export DEEPNLP_ONEKEY_ROUTER_ACCESS=YOUR_REGISTRY_KEYRun an API via scripts:
- Node (JS):
node scripts/<api_name>.js --data '{"key":"value"}' - Python:
python3 scripts/<api_name>.py --data '{"key":"value"}'
APIs
get_foods_multiple
Fetches details for multiple food items using input FDC IDs
- Method:
GET,POST - Endpoint:
https://api.nal.usda.gov/fdc/v1/foods
Parameters:
fdcIds:array[string]format:string=fullnutrients:array[integer]
Curl
curl -X GET,POST "https://api.nal.usda.gov/fdc/v1/foods" \
-H "Content-Type: application/json" \
-d '{}'Scripts
node scripts/get_foods_multiple.js --data '{}'
python3 scripts/get_foods_multiple.py --data '{}'get_food_by_id
Fetches details for one food item by FDC ID
- Method:
GET - Endpoint:
https://api.nal.usda.gov/fdc/v1/food/{fdcId}
Parameters:
fdcId:stringformat:string=fullnutrients:array[integer]
Curl
curl -X GET "https://api.nal.usda.gov/fdc/v1/food/{fdcId}"Scripts
node scripts/get_food_by_id.js --data '{}'
python3 scripts/get_food_by_id.py --data '{}'list_foods
Returns a paged list of foods, in the 'abridged' format
- Method:
GET,POST - Endpoint:
https://api.nal.usda.gov/fdc/v1/foods/list
Parameters:
dataType:array[string]pageSize:integer=50pageNumber:integer=1sortBy:stringsortOrder:string
Curl
curl -X GET,POST "https://api.nal.usda.gov/fdc/v1/foods/list" \
-H "Content-Type: application/json" \
-d '{}'Scripts
node scripts/list_foods.js --data '{}'
python3 scripts/list_foods.py --data '{}'search_foods
Returns a list of foods that matched search (query) keywords
- Method:
GET,POST - Endpoint:
https://api.nal.usda.gov/fdc/v1/foods/search
Parameters:
query:stringdataType:array[string]pageSize:integer=50pageNumber:integer=1sortBy:stringsortOrder:stringbrandOwner:string
Curl
curl -X GET,POST "https://api.nal.usda.gov/fdc/v1/foods/search" \
-H "Content-Type: application/json" \
-d '{}'Scripts
node scripts/search_foods.js --data '{}'
python3 scripts/search_foods.py --data '{}'Scripts
Each API has a dedicated script in scripts/:
node scripts/<api_name>.js --data '{"key":"value"}'
python3 scripts/<api_name>.py --data '{"key":"value"}'CLIs
npx onekey agent fdcnal/usda-fooddata-central-agent get_foods_multiple '{"fdcIds":[],"format":"value","nutrients":0}'
npx onekey agent fdcnal/usda-fooddata-central-agent get_food_by_id '{"fdcId":"value","format":"value","nutrients":0}'
npx onekey agent fdcnal/usda-fooddata-central-agent list_foods '{"dataType":[],"pageNumber":0,"pageSize":0,"sortBy":"value","sortOrder":"value"}'
npx onekey agent fdcnal/usda-fooddata-central-agent search_foods '{"brandOwner":"value","dataType":[],"pageNumber":0,"pageSize":0,"query":"value","sortBy":"value"}'References
reference/api_list.json: originalapi_listpayloadreference/api_meta.json: normalized API metadata used by scripts
[
{
"api_id": "agent.deepnlp.org/api/agent/fdcnal/usda-fooddata-central-agent",
"endpoint": "",
"method": "",
"api_type": "AGENT",
"auth": {},
"description": "",
"params": {}
},
{
"api_id": "agent.deepnlp.org/api/agent/fdcnal/usda-fooddata-central-agent/get_foods_multiple",
"endpoint": "https://api.nal.usda.gov/fdc/v1/foods",
"method": "GET,POST",
"api_type": "AGENT",
"auth": {
"type": "API_KEY",
"header": "X-Api-Key",
"value_encode": "Nrc9beuTOg2fU8wX10VF8pDCsiYL5JdODn9r/y6vdBrubsFb4q4bU2qGKN1mOv7qju7hfSwELlRHFs0rEDiimnwuvPY="
},
"description": "Fetches details for multiple food items using input FDC IDs",
"params": {
"fdcIds": "array[string]",
"format": "string=full",
"nutrients": "array[integer]"
}
},
{
"api_id": "agent.deepnlp.org/api/agent/fdcnal/usda-fooddata-central-agent/get_food_by_id",
"endpoint": "https://api.nal.usda.gov/fdc/v1/food/{fdcId}",
"method": "GET",
"api_type": "AGENT",
"auth": {
"type": "API_KEY",
"header": "X-Api-Key",
"value_encode": "uldi1u60/qLyY5IxiFHhhIJPnutIdiogOusvM936LkqDM+wweer2h+nWzYDNBs0zSCkP+pMor+EvrHZMGejro1K8/Ds="
},
"description": "Fetches details for one food item by FDC ID",
"params": {
"fdcId": "string",
"format": "string=full",
"nutrients": "array[integer]"
}
},
{
"api_id": "agent.deepnlp.org/api/agent/fdcnal/usda-fooddata-central-agent/list_foods",
"endpoint": "https://api.nal.usda.gov/fdc/v1/foods/list",
"method": "GET,POST",
"api_type": "AGENT",
"auth": {
"type": "API_KEY",
"header": "X-Api-Key",
"value_encode": "ySDhZe/M7ZAaGuVXPFs0Vhc/0QPxALStuukDzy9gEsn9/44uy7v2u3jObzEbz6apg9T1VIL+U4cQk85nE/JH2GxMVsc="
},
"description": "Returns a paged list of foods, in the 'abridged' format",
"params": {
"dataType": "array[string]",
"pageSize": "integer=50",
"pageNumber": "integer=1",
"sortBy": "string",
"sortOrder": "string"
}
},
{
"api_id": "agent.deepnlp.org/api/agent/fdcnal/usda-fooddata-central-agent/search_foods",
"endpoint": "https://api.nal.usda.gov/fdc/v1/foods/search",
"method": "GET,POST",
"api_type": "AGENT",
"auth": {
"type": "API_KEY",
"header": "X-Api-Key",
"value_encode": "yg++JRa/DykHm2NW4rGmqz8oEnT+muHGnRc+zvvyY9xTC+6ZC/O7EIlWqDTodEjAVbXxLL4ZmAuAL7YDE1nzcH4M878="
},
"description": "Returns a list of foods that matched search (query) keywords",
"params": {
"query": "string",
"dataType": "array[string]",
"pageSize": "integer=50",
"pageNumber": "integer=1",
"sortBy": "string",
"sortOrder": "string",
"brandOwner": "string"
}
}
]
{
"unique_id": "fdcnal/usda-fooddata-central-agent",
"generated_at": "2026-04-07T09:09:56.078Z",
"apis": {
"get_foods_multiple": {
"api_id": "agent.deepnlp.org/api/agent/fdcnal/usda-fooddata-central-agent/get_foods_multiple",
"endpoint": "https://api.nal.usda.gov/fdc/v1/foods",
"method": "GET,POST",
"description": "Fetches details for multiple food items using input FDC IDs",
"params": {
"fdcIds": "array[string]",
"format": "string=full",
"nutrients": "array[integer]"
},
"headers": {},
"auth": {
"header": "X-Api-Key",
"type": "API_KEY"
}
},
"get_food_by_id": {
"api_id": "agent.deepnlp.org/api/agent/fdcnal/usda-fooddata-central-agent/get_food_by_id",
"endpoint": "https://api.nal.usda.gov/fdc/v1/food/{fdcId}",
"method": "GET",
"description": "Fetches details for one food item by FDC ID",
"params": {
"fdcId": "string",
"format": "string=full",
"nutrients": "array[integer]"
},
"headers": {},
"auth": {
"header": "X-Api-Key",
"type": "API_KEY"
}
},
"list_foods": {
"api_id": "agent.deepnlp.org/api/agent/fdcnal/usda-fooddata-central-agent/list_foods",
"endpoint": "https://api.nal.usda.gov/fdc/v1/foods/list",
"method": "GET,POST",
"description": "Returns a paged list of foods, in the 'abridged' format",
"params": {
"dataType": "array[string]",
"pageSize": "integer=50",
"pageNumber": "integer=1",
"sortBy": "string",
"sortOrder": "string"
},
"headers": {},
"auth": {
"header": "X-Api-Key",
"type": "API_KEY"
}
},
"search_foods": {
"api_id": "agent.deepnlp.org/api/agent/fdcnal/usda-fooddata-central-agent/search_foods",
"endpoint": "https://api.nal.usda.gov/fdc/v1/foods/search",
"method": "GET,POST",
"description": "Returns a list of foods that matched search (query) keywords",
"params": {
"query": "string",
"dataType": "array[string]",
"pageSize": "integer=50",
"pageNumber": "integer=1",
"sortBy": "string",
"sortOrder": "string",
"brandOwner": "string"
},
"headers": {},
"auth": {
"header": "X-Api-Key",
"type": "API_KEY"
}
}
}
}
{
"content_name": "USDA FoodData Central Agent",
"publisher_id": "pub-fdcnal",
"detail_url": "https://www.deepnlp.org/store/ai-agent/skills/pub-fdcnal/usda-fooddata-central-agent",
"website": "https://fdc.nal.usda.gov/",
"github": "https://github.com/fdc-nal-usda/fdc-api",
"review_cnt": "1",
"api_list": [
{
"api_id": "agent.deepnlp.org/api/agent/fdcnal/usda-fooddata-central-agent",
"endpoint": "",
"method": "",
"api_type": "AGENT",
"auth": {},
"description": "",
"params": {}
},
{
"api_id": "agent.deepnlp.org/api/agent/fdcnal/usda-fooddata-central-agent/get_foods_multiple",
"endpoint": "https://api.nal.usda.gov/fdc/v1/foods",
"method": "GET,POST",
"api_type": "AGENT",
"auth": {
"type": "API_KEY",
"header": "X-Api-Key",
"value_encode": "Nrc9beuTOg2fU8wX10VF8pDCsiYL5JdODn9r/y6vdBrubsFb4q4bU2qGKN1mOv7qju7hfSwELlRHFs0rEDiimnwuvPY="
},
"description": "Fetches details for multiple food items using input FDC IDs",
"params": {
"fdcIds": "array[string]",
"format": "string=full",
"nutrients": "array[integer]"
}
},
{
"api_id": "agent.deepnlp.org/api/agent/fdcnal/usda-fooddata-central-agent/get_food_by_id",
"endpoint": "https://api.nal.usda.gov/fdc/v1/food/{fdcId}",
"method": "GET",
"api_type": "AGENT",
"auth": {
"type": "API_KEY",
"header": "X-Api-Key",
"value_encode": "uldi1u60/qLyY5IxiFHhhIJPnutIdiogOusvM936LkqDM+wweer2h+nWzYDNBs0zSCkP+pMor+EvrHZMGejro1K8/Ds="
},
"description": "Fetches details for one food item by FDC ID",
"params": {
"fdcId": "string",
"format": "string=full",
"nutrients": "array[integer]"
}
},
{
"api_id": "agent.deepnlp.org/api/agent/fdcnal/usda-fooddata-central-agent/list_foods",
"endpoint": "https://api.nal.usda.gov/fdc/v1/foods/list",
"method": "GET,POST",
"api_type": "AGENT",
"auth": {
"type": "API_KEY",
"header": "X-Api-Key",
"value_encode": "ySDhZe/M7ZAaGuVXPFs0Vhc/0QPxALStuukDzy9gEsn9/44uy7v2u3jObzEbz6apg9T1VIL+U4cQk85nE/JH2GxMVsc="
},
"description": "Returns a paged list of foods, in the 'abridged' format",
"params": {
"dataType": "array[string]",
"pageSize": "integer=50",
"pageNumber": "integer=1",
"sortBy": "string",
"sortOrder": "string"
}
},
{
"api_id": "agent.deepnlp.org/api/agent/fdcnal/usda-fooddata-central-agent/search_foods",
"endpoint": "https://api.nal.usda.gov/fdc/v1/foods/search",
"method": "GET,POST",
"api_type": "AGENT",
"auth": {
"type": "API_KEY",
"header": "X-Api-Key",
"value_encode": "yg++JRa/DykHm2NW4rGmqz8oEnT+muHGnRc+zvvyY9xTC+6ZC/O7EIlWqDTodEjAVbXxLL4ZmAuAL7YDE1nzcH4M878="
},
"description": "Returns a list of foods that matched search (query) keywords",
"params": {
"query": "string",
"dataType": "array[string]",
"pageSize": "integer=50",
"pageNumber": "integer=1",
"sortBy": "string",
"sortOrder": "string",
"brandOwner": "string"
}
}
],
"rating": "5.0",
"description": "The FoodData Central API provides REST access to FoodData Central (FDC), assisting developers in incorporating nutrient data into their applications. It provides access to Standard Reference (SR) Legacy data, USDA Global Branded Foods Database, Foundation Foods, and FNDDS.",
"ext_info": "{\"publisher_id\":\"pub-fdcnal\",\"content_name\":\"USDA FoodData Central Agent\",\"price_subscription_free_quota\":\"\",\"price_fixed_credit\":\"0\",\"final_thumbnail_files\":\"\",\"visible_to_paid_only\":\"off\",\"content\":\"The FoodData Central API provides REST access to FoodData Central (FDC), assisting developers in incorporating nutrient data into their applications. It provides access to Standard Reference (SR) Legacy data, USDA Global Branded Foods Database, Foundation Foods, and FNDDS.\",\"price_per_call_credit\":\"1\",\"final_background_files\":\"\",\"price_per_call_unit_orig\":\"USD\",\"subfield\":\"Skills\",\"price_per_call_value_orig\":\"\",\"price_per_call_method_orig\":\"/1k calls\",\"price_fixed_unit_orig\":\"USD\",\"api\":\"\",\"content_tag_list\":\"food,nutrition,usda,fdc,nutrients\",\"price_subscription_yearly_credit\":\"25000\",\"website\":\"https://fdc.nal.usda.gov/\",\"github\":\"https://github.com/fdc-nal-usda/fdc-api\",\"content_id\":\"faee8b97e2fd4b7a8dd663c97a667724\",\"price_subscription_monthly_quota\":\"\",\"final_system_files\":\"\",\"upload_files_system\":\"\",\"field\":\"AI AGENT\",\"price_subscription_monthly_credit\":\"25000\",\"price_type\":\"PER_CALL\",\"price_subscription_yearly_quota\":\"\",\"price_fixed_value_orig\":\"\",\"price_fixed_method_orig\":\"each\"}",
"subfield": "Skills",
"field": "AI AGENT",
"id": "fdcnal/usda-fooddata-central-agent",
"content_tag_list": "food,nutrition,usda,fdc,nutrients",
"thumbnail_picture": "https://fdc.nal.usda.gov/img/logo.png"
}
References
This folder is generated by agtm skills build.
api_list.json: Rawapi_listfetched from the marketplace (or loaded fromagent.yaml/agent.json).api_meta.json: Normalized API metadata used by the scripts inscripts/.
#!/usr/bin/env node
const { spawnSync } = require("node:child_process");
const path = require("node:path");
const script = path.join(__dirname, "run_api.js");
const args = process.argv.slice(2);
const res = spawnSync(process.execPath, [script, "--api", "get_food_by_id", ...args], { stdio: "inherit" });
process.exit(typeof res.status === "number" ? res.status : 1);
#!/usr/bin/env python3
import os
import subprocess
import sys
def main():
script = os.path.join(os.path.dirname(__file__), "run_api.py")
args = [sys.executable, script, "--api", "get_food_by_id"] + sys.argv[1:]
res = subprocess.run(args)
raise SystemExit(res.returncode)
if __name__ == "__main__":
main()
/* eslint-disable */
import { spawnSync } from "node:child_process";
import * as path from "node:path";
const script = path.join(__dirname, "run_api.js");
const args = process.argv.slice(2);
const res = spawnSync(process.execPath, [script, "--api", "get_food_by_id", ...args], { stdio: "inherit" });
process.exit(typeof res.status === "number" ? res.status : 1);
#!/usr/bin/env node
const { spawnSync } = require("node:child_process");
const path = require("node:path");
const script = path.join(__dirname, "run_api.js");
const args = process.argv.slice(2);
const res = spawnSync(process.execPath, [script, "--api", "get_foods_multiple", ...args], { stdio: "inherit" });
process.exit(typeof res.status === "number" ? res.status : 1);
#!/usr/bin/env python3
import os
import subprocess
import sys
def main():
script = os.path.join(os.path.dirname(__file__), "run_api.py")
args = [sys.executable, script, "--api", "get_foods_multiple"] + sys.argv[1:]
res = subprocess.run(args)
raise SystemExit(res.returncode)
if __name__ == "__main__":
main()
/* eslint-disable */
import { spawnSync } from "node:child_process";
import * as path from "node:path";
const script = path.join(__dirname, "run_api.js");
const args = process.argv.slice(2);
const res = spawnSync(process.execPath, [script, "--api", "get_foods_multiple", ...args], { stdio: "inherit" });
process.exit(typeof res.status === "number" ? res.status : 1);
#!/usr/bin/env node
const { spawnSync } = require("node:child_process");
const path = require("node:path");
const script = path.join(__dirname, "run_api.js");
const args = process.argv.slice(2);
const res = spawnSync(process.execPath, [script, "--api", "list_foods", ...args], { stdio: "inherit" });
process.exit(typeof res.status === "number" ? res.status : 1);
#!/usr/bin/env python3
import os
import subprocess
import sys
def main():
script = os.path.join(os.path.dirname(__file__), "run_api.py")
args = [sys.executable, script, "--api", "list_foods"] + sys.argv[1:]
res = subprocess.run(args)
raise SystemExit(res.returncode)
if __name__ == "__main__":
main()
/* eslint-disable */
import { spawnSync } from "node:child_process";
import * as path from "node:path";
const script = path.join(__dirname, "run_api.js");
const args = process.argv.slice(2);
const res = spawnSync(process.execPath, [script, "--api", "list_foods", ...args], { stdio: "inherit" });
process.exit(typeof res.status === "number" ? res.status : 1);
#!/usr/bin/env node
const fs = require("node:fs");
const path = require("node:path");
function readJson(filePath) {
return JSON.parse(fs.readFileSync(filePath, "utf8"));
}
function loadPayload(args) {
const dataIndex = args.indexOf("--data");
const dataFileIndex = args.indexOf("--data-file");
if (dataIndex !== -1 && dataFileIndex !== -1) {
throw new Error("Use only one of --data or --data-file.");
}
if (dataIndex !== -1) {
return JSON.parse(args[dataIndex + 1] || "{}");
}
if (dataFileIndex !== -1) {
const filePath = args[dataFileIndex + 1];
return readJson(filePath);
}
return {};
}
function loadApiMeta() {
const referenceDir = path.join(__dirname, "..", "reference");
const metaPath = path.join(referenceDir, "api_meta.json");
return readJson(metaPath);
}
function normalizeHeaders(meta) {
const headers = Object.assign({}, meta.headers || {});
if (meta.auth && meta.auth.header) {
const envName = meta.auth.env || meta.auth.value;
const envValue = envName ? process.env[envName] : undefined;
if (envValue) {
headers[meta.auth.header] = envValue;
}
}
return headers;
}
function applyQueryParams(url, payload) {
const u = new URL(url);
if (!payload || typeof payload !== "object") return u;
for (const [key, value] of Object.entries(payload)) {
if (value === undefined || value === null) continue;
if (Array.isArray(value)) {
for (const item of value) {
u.searchParams.append(key, String(item));
}
} else {
u.searchParams.set(key, String(value));
}
}
return u;
}
async function main() {
const args = process.argv.slice(2);
const apiIndex = args.indexOf("--api");
const api = apiIndex === -1 ? null : args[apiIndex + 1];
if (!api) {
console.error("Missing --api <api_id>.");
process.exit(1);
}
const meta = loadApiMeta();
const apiInfo = meta.apis && meta.apis[api];
if (!apiInfo) {
console.error(`Unknown api_id: ${api}`);
console.error(`Known: ${Object.keys(meta.apis || {}).join(", ")}`);
process.exit(1);
}
const payload = loadPayload(args);
const method = String(apiInfo.method || "GET").toUpperCase();
const headers = normalizeHeaders(apiInfo);
let url = apiInfo.endpoint;
const init = { method, headers };
if (method === "GET" || method === "DELETE") {
url = applyQueryParams(url, payload).toString();
} else {
headers["Content-Type"] = headers["Content-Type"] || "application/json";
init.body = JSON.stringify(payload || {});
}
const res = await fetch(url, init);
const text = await res.text();
let body = text;
try {
body = JSON.parse(text);
} catch {}
if (!res.ok) {
console.error(JSON.stringify({ status: res.status, body }, null, 2));
process.exit(1);
}
process.stdout.write(
typeof body === "string" ? body : JSON.stringify(body, null, 2)
);
process.stdout.write("\n");
}
main().catch((err) => {
console.error(String(err && err.stack ? err.stack : err));
process.exit(1);
});
#!/usr/bin/env python3
import argparse
import json
import os
import sys
import urllib.parse
import urllib.request
def read_json(path):
with open(path, "r", encoding="utf-8") as f:
return json.load(f)
def load_payload(args):
if args.data and args.data_file:
raise SystemExit("Use only one of --data or --data-file.")
if args.data:
return json.loads(args.data)
if args.data_file:
return read_json(args.data_file)
return {}
def apply_query_params(url, payload):
if not payload or not isinstance(payload, dict):
return url
parsed = urllib.parse.urlsplit(url)
query = urllib.parse.parse_qsl(parsed.query, keep_blank_values=True)
for k, v in payload.items():
if v is None:
continue
if isinstance(v, list):
for item in v:
query.append((k, str(item)))
else:
query.append((k, str(v)))
new_query = urllib.parse.urlencode(query, doseq=True)
return urllib.parse.urlunsplit(
(parsed.scheme, parsed.netloc, parsed.path, new_query, parsed.fragment)
)
def main():
parser = argparse.ArgumentParser(description="Run one API from reference/api_meta.json")
parser.add_argument("--api", required=True, help="api_id to run")
parser.add_argument("--data", help="JSON string payload")
parser.add_argument("--data-file", help="Path to JSON file payload")
args = parser.parse_args()
meta_path = os.path.join(os.path.dirname(__file__), "..", "reference", "api_meta.json")
meta = read_json(meta_path)
apis = meta.get("apis", {})
api_info = apis.get(args.api)
if not api_info:
raise SystemExit(f"Unknown api_id: {args.api}. Known: {', '.join(apis.keys())}")
payload = load_payload(args)
method = str(api_info.get("method", "GET")).upper()
endpoint = api_info.get("endpoint")
if not endpoint:
raise SystemExit("Missing endpoint in api_meta.json")
headers = dict(api_info.get("headers") or {})
auth = api_info.get("auth") or {}
auth_header = auth.get("header")
auth_env = auth.get("env") or auth.get("value")
if auth_header and auth_env and os.getenv(auth_env):
headers[auth_header] = os.getenv(auth_env)
data_bytes = None
url = endpoint
if method in ("GET", "DELETE"):
url = apply_query_params(endpoint, payload)
else:
headers.setdefault("Content-Type", "application/json")
data_bytes = json.dumps(payload or {}).encode("utf-8")
req = urllib.request.Request(url=url, method=method, headers=headers, data=data_bytes)
try:
with urllib.request.urlopen(req, timeout=30) as resp:
body = resp.read().decode("utf-8")
print(body)
except urllib.error.HTTPError as e:
body = e.read().decode("utf-8", errors="replace")
sys.stderr.write(json.dumps({"status": e.code, "body": body}, indent=2, ensure_ascii=False) + "\n")
raise SystemExit(1)
if __name__ == "__main__":
main()
/* eslint-disable */
// TypeScript version of scripts/run_api.js (generated skills also include runnable .js).
import * as fs from "node:fs";
import * as path from "node:path";
type ApiMeta = {
apis: Record<
string,
{
endpoint: string;
method?: string;
headers?: Record<string, string>;
auth?: { header?: string; env?: string; value?: string };
}
>;
};
function readJson<T>(filePath: string): T {
return JSON.parse(fs.readFileSync(filePath, "utf8"));
}
function loadPayload(args: string[]): any {
const dataIndex = args.indexOf("--data");
const dataFileIndex = args.indexOf("--data-file");
if (dataIndex !== -1 && dataFileIndex !== -1) {
throw new Error("Use only one of --data or --data-file.");
}
if (dataIndex !== -1) return JSON.parse(args[dataIndex + 1] || "{}");
if (dataFileIndex !== -1) return readJson(args[dataFileIndex + 1]);
return {};
}
function loadApiMeta(): ApiMeta {
const referenceDir = path.join(__dirname, "..", "reference");
const metaPath = path.join(referenceDir, "api_meta.json");
return readJson<ApiMeta>(metaPath);
}
function normalizeHeaders(meta: any): Record<string, string> {
const headers: Record<string, string> = { ...(meta.headers || {}) };
if (meta.auth?.header) {
const envName = meta.auth.env || meta.auth.value;
const envValue = envName ? process.env[envName] : undefined;
if (envValue) headers[meta.auth.header] = envValue;
}
return headers;
}
function applyQueryParams(url: string, payload: any): URL {
const u = new URL(url);
if (!payload || typeof payload !== "object") return u;
for (const [key, value] of Object.entries(payload)) {
if (value === undefined || value === null) continue;
if (Array.isArray(value)) {
for (const item of value) u.searchParams.append(key, String(item));
} else {
u.searchParams.set(key, String(value));
}
}
return u;
}
async function main() {
const args = process.argv.slice(2);
const apiIndex = args.indexOf("--api");
const api = apiIndex === -1 ? null : args[apiIndex + 1];
if (!api) throw new Error("Missing --api <api_id>.");
const meta = loadApiMeta();
const apiInfo = meta.apis?.[api];
if (!apiInfo) throw new Error(`Unknown api_id: ${api}`);
const payload = loadPayload(args);
const method = String(apiInfo.method || "GET").toUpperCase();
const headers = normalizeHeaders(apiInfo);
let url = apiInfo.endpoint;
const init: RequestInit = { method, headers };
if (method === "GET" || method === "DELETE") {
url = applyQueryParams(url, payload).toString();
} else {
headers["Content-Type"] = headers["Content-Type"] || "application/json";
init.body = JSON.stringify(payload || {});
}
const res = await fetch(url, init);
const text = await res.text();
let body: any = text;
try {
body = JSON.parse(text);
} catch {}
if (!res.ok) {
console.error(JSON.stringify({ status: res.status, body }, null, 2));
process.exit(1);
}
process.stdout.write(typeof body === "string" ? body : JSON.stringify(body, null, 2));
process.stdout.write("\n");
}
main().catch((err) => {
console.error(String((err as any)?.stack || err));
process.exit(1);
});
#!/usr/bin/env node
const { spawnSync } = require("node:child_process");
const path = require("node:path");
const script = path.join(__dirname, "run_api.js");
const args = process.argv.slice(2);
const res = spawnSync(process.execPath, [script, "--api", "search_foods", ...args], { stdio: "inherit" });
process.exit(typeof res.status === "number" ? res.status : 1);
#!/usr/bin/env python3
import os
import subprocess
import sys
def main():
script = os.path.join(os.path.dirname(__file__), "run_api.py")
args = [sys.executable, script, "--api", "search_foods"] + sys.argv[1:]
res = subprocess.run(args)
raise SystemExit(res.returncode)
if __name__ == "__main__":
main()
/* eslint-disable */
import { spawnSync } from "node:child_process";
import * as path from "node:path";
const script = path.join(__dirname, "run_api.js");
const args = process.argv.slice(2);
const res = spawnSync(process.execPath, [script, "--api", "search_foods", ...args], { stdio: "inherit" });
process.exit(typeof res.status === "number" ? res.status : 1);