@bixbd/utils-mcp 0.1.0-beta.5 → 0.1.0-beta.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +337 -117
- package/package.json +3 -3
package/dist/cli.js
CHANGED
|
@@ -4504,44 +4504,10 @@ var init_src = __esm(() => {
|
|
|
4504
4504
|
init_registry();
|
|
4505
4505
|
});
|
|
4506
4506
|
|
|
4507
|
-
// ../../connectors/desco/src/schemas.ts
|
|
4508
|
-
var
|
|
4509
|
-
var
|
|
4507
|
+
// ../../connectors/desco/src/schemas/out.ts
|
|
4508
|
+
var AccountsOut, BalanceOut, RealtimeOut, DataOut;
|
|
4509
|
+
var init_out = __esm(() => {
|
|
4510
4510
|
init_src();
|
|
4511
|
-
RawAccounts = object({
|
|
4512
|
-
accounts: array(object({
|
|
4513
|
-
accountId: number2(),
|
|
4514
|
-
accountNo: string2().nullish(),
|
|
4515
|
-
meterNo: string2().nullish(),
|
|
4516
|
-
status: string2().nullish(),
|
|
4517
|
-
linkStatus: string2().nullish()
|
|
4518
|
-
}))
|
|
4519
|
-
});
|
|
4520
|
-
RawBalance = object({
|
|
4521
|
-
balance: number2().nullish(),
|
|
4522
|
-
currency: string2().nullish(),
|
|
4523
|
-
balanceSnapshotAt: string2().nullish(),
|
|
4524
|
-
timestampAvailable: boolean2().optional(),
|
|
4525
|
-
stale: boolean2().optional(),
|
|
4526
|
-
currentMonthConsumedTaka: number2().nullish(),
|
|
4527
|
-
readingTime: string2().nullish(),
|
|
4528
|
-
consumerMessages: array(unknown()).optional()
|
|
4529
|
-
});
|
|
4530
|
-
RawRealtime = object({
|
|
4531
|
-
enabled: boolean2().optional(),
|
|
4532
|
-
meters: array(object({
|
|
4533
|
-
accountId: number2().nullish(),
|
|
4534
|
-
meterNo: string2().nullish(),
|
|
4535
|
-
meterType: string2().nullish(),
|
|
4536
|
-
status: string2().nullish(),
|
|
4537
|
-
message: string2().nullish(),
|
|
4538
|
-
lastRealtimeBalance: number2().nullish(),
|
|
4539
|
-
lastRealtimeReceivedAt: string2().nullish(),
|
|
4540
|
-
nextEligibleAt: string2().nullish(),
|
|
4541
|
-
attemptsToday: number2().nullish(),
|
|
4542
|
-
remainingAttempts: number2().nullish()
|
|
4543
|
-
}))
|
|
4544
|
-
});
|
|
4545
4511
|
AccountsOut = object({
|
|
4546
4512
|
accounts: array(object({
|
|
4547
4513
|
accountId: number2(),
|
|
@@ -4577,14 +4543,66 @@ var init_schemas3 = __esm(() => {
|
|
|
4577
4543
|
remainingAttempts: number2().nullable()
|
|
4578
4544
|
}))
|
|
4579
4545
|
});
|
|
4546
|
+
DataOut = object({ data: unknown() });
|
|
4580
4547
|
});
|
|
4581
4548
|
|
|
4582
|
-
// ../../connectors/desco/src/
|
|
4583
|
-
var
|
|
4584
|
-
|
|
4585
|
-
|
|
4586
|
-
|
|
4549
|
+
// ../../connectors/desco/src/schemas/raw.ts
|
|
4550
|
+
var RawAccounts, RawBalance, RawRealtime;
|
|
4551
|
+
var init_raw = __esm(() => {
|
|
4552
|
+
init_src();
|
|
4553
|
+
RawAccounts = object({
|
|
4554
|
+
accounts: array(object({
|
|
4555
|
+
accountId: number2(),
|
|
4556
|
+
accountNo: string2().nullish(),
|
|
4557
|
+
meterNo: string2().nullish(),
|
|
4558
|
+
status: string2().nullish(),
|
|
4559
|
+
linkStatus: string2().nullish()
|
|
4560
|
+
}))
|
|
4561
|
+
});
|
|
4562
|
+
RawBalance = object({
|
|
4563
|
+
balance: number2().nullish(),
|
|
4564
|
+
currency: string2().nullish(),
|
|
4565
|
+
balanceSnapshotAt: string2().nullish(),
|
|
4566
|
+
timestampAvailable: boolean2().optional(),
|
|
4567
|
+
stale: boolean2().optional(),
|
|
4568
|
+
currentMonthConsumedTaka: number2().nullish(),
|
|
4569
|
+
readingTime: string2().nullish(),
|
|
4570
|
+
consumerMessages: array(unknown()).optional()
|
|
4571
|
+
});
|
|
4572
|
+
RawRealtime = object({
|
|
4573
|
+
enabled: boolean2().optional(),
|
|
4574
|
+
meters: array(object({
|
|
4575
|
+
accountId: number2().nullish(),
|
|
4576
|
+
meterNo: string2().nullish(),
|
|
4577
|
+
meterType: string2().nullish(),
|
|
4578
|
+
status: string2().nullish(),
|
|
4579
|
+
message: string2().nullish(),
|
|
4580
|
+
lastRealtimeBalance: number2().nullish(),
|
|
4581
|
+
lastRealtimeReceivedAt: string2().nullish(),
|
|
4582
|
+
nextEligibleAt: string2().nullish(),
|
|
4583
|
+
attemptsToday: number2().nullish(),
|
|
4584
|
+
remainingAttempts: number2().nullish()
|
|
4585
|
+
}))
|
|
4586
|
+
});
|
|
4587
|
+
});
|
|
4588
|
+
|
|
4589
|
+
// ../../connectors/desco/src/schemas/index.ts
|
|
4590
|
+
var init_schemas3 = __esm(() => {
|
|
4591
|
+
init_out();
|
|
4592
|
+
init_raw();
|
|
4587
4593
|
});
|
|
4594
|
+
|
|
4595
|
+
// ../../connectors/desco/src/client/accounts.ts
|
|
4596
|
+
async function listAccounts(ctx) {
|
|
4597
|
+
const raw = await ctx.http.json("/accounts", RawAccounts);
|
|
4598
|
+
return raw.accounts.map((account) => ({
|
|
4599
|
+
accountId: account.accountId,
|
|
4600
|
+
accountNoLast4: maskLast4(account.accountNo),
|
|
4601
|
+
meterNoLast4: maskLast4(account.meterNo),
|
|
4602
|
+
status: account.status ?? null,
|
|
4603
|
+
linkStatus: account.linkStatus ?? null
|
|
4604
|
+
}));
|
|
4605
|
+
}
|
|
4588
4606
|
async function resolveAccountId(ctx) {
|
|
4589
4607
|
const accounts = await listAccounts(ctx);
|
|
4590
4608
|
const only = accounts[0];
|
|
@@ -4597,92 +4615,294 @@ async function resolveAccountId(ctx) {
|
|
|
4597
4615
|
}
|
|
4598
4616
|
return only.accountId;
|
|
4599
4617
|
}
|
|
4600
|
-
var
|
|
4601
|
-
|
|
4602
|
-
|
|
4603
|
-
|
|
4604
|
-
|
|
4605
|
-
|
|
4606
|
-
|
|
4607
|
-
|
|
4608
|
-
|
|
4609
|
-
|
|
4610
|
-
|
|
4618
|
+
var init_accounts = __esm(() => {
|
|
4619
|
+
init_src();
|
|
4620
|
+
init_schemas3();
|
|
4621
|
+
});
|
|
4622
|
+
|
|
4623
|
+
// ../../connectors/desco/src/client/query.ts
|
|
4624
|
+
function withQuery(path, query) {
|
|
4625
|
+
const params = new URLSearchParams;
|
|
4626
|
+
for (const [key, value] of Object.entries(query)) {
|
|
4627
|
+
if (value !== undefined && value !== "") {
|
|
4628
|
+
params.set(key, String(value));
|
|
4629
|
+
}
|
|
4630
|
+
}
|
|
4631
|
+
const text = params.toString();
|
|
4632
|
+
return text ? `${path}?${text}` : path;
|
|
4633
|
+
}
|
|
4634
|
+
|
|
4635
|
+
// ../../connectors/desco/src/client/redact.ts
|
|
4636
|
+
function redact(value) {
|
|
4637
|
+
if (Array.isArray(value)) {
|
|
4638
|
+
return value.map(redact);
|
|
4639
|
+
}
|
|
4640
|
+
if (value !== null && typeof value === "object") {
|
|
4641
|
+
return Object.fromEntries(Object.entries(value).map(([key, v]) => [
|
|
4642
|
+
key,
|
|
4643
|
+
MASKED_KEYS.has(key) && typeof v === "string" ? maskLast4(v) : redact(v)
|
|
4644
|
+
]));
|
|
4645
|
+
}
|
|
4646
|
+
return value;
|
|
4647
|
+
}
|
|
4648
|
+
var MASKED_KEYS;
|
|
4649
|
+
var init_redact = __esm(() => {
|
|
4650
|
+
init_src();
|
|
4651
|
+
MASKED_KEYS = new Set(["accountNo", "meterNo", "consumerNo"]);
|
|
4652
|
+
});
|
|
4653
|
+
|
|
4654
|
+
// ../../connectors/desco/src/client/index.ts
|
|
4655
|
+
var init_client = __esm(() => {
|
|
4656
|
+
init_accounts();
|
|
4657
|
+
init_redact();
|
|
4658
|
+
});
|
|
4659
|
+
|
|
4660
|
+
// ../../connectors/desco/src/tools/factories.ts
|
|
4661
|
+
var Loose, accountIdInput, dateInput, monthInput, publicGet = (name, description, path) => defineTool({
|
|
4662
|
+
name,
|
|
4663
|
+
description,
|
|
4664
|
+
access: "read",
|
|
4665
|
+
input: object({}),
|
|
4666
|
+
output: DataOut,
|
|
4667
|
+
handler: async (_input, ctx) => ({ data: await ctx.http.json(path, Loose) })
|
|
4668
|
+
}), publicSearch = (name, description, path, shape) => defineTool({
|
|
4669
|
+
name,
|
|
4670
|
+
description,
|
|
4671
|
+
access: "read",
|
|
4672
|
+
input: object({
|
|
4673
|
+
...shape,
|
|
4674
|
+
page: number2().int().min(0).optional().describe("Zero-based page number."),
|
|
4675
|
+
size: number2().int().min(1).max(50).optional().describe("Results per page.")
|
|
4676
|
+
}),
|
|
4677
|
+
output: DataOut,
|
|
4678
|
+
handler: async (input, ctx) => ({
|
|
4679
|
+
data: await ctx.http.json(withQuery(path, input), Loose)
|
|
4680
|
+
})
|
|
4681
|
+
}), accountGet = (name, description, suffix, shape = {}) => defineTool({
|
|
4682
|
+
name,
|
|
4683
|
+
description,
|
|
4684
|
+
access: "read",
|
|
4685
|
+
input: object({ accountId: accountIdInput, ...shape }),
|
|
4686
|
+
output: DataOut,
|
|
4687
|
+
handler: async (input, ctx) => {
|
|
4688
|
+
const { accountId: given, ...query } = input;
|
|
4689
|
+
const accountId = given ?? await resolveAccountId(ctx);
|
|
4690
|
+
const path = withQuery(`/accounts/${accountId}${suffix}`, query);
|
|
4691
|
+
return { data: redact(await ctx.http.json(path, Loose)) };
|
|
4692
|
+
}
|
|
4693
|
+
});
|
|
4694
|
+
var init_factories = __esm(() => {
|
|
4611
4695
|
init_src();
|
|
4696
|
+
init_client();
|
|
4612
4697
|
init_schemas3();
|
|
4698
|
+
Loose = unknown();
|
|
4699
|
+
accountIdInput = number2().int().positive().optional().describe("Internal accountId from desco_list_accounts. Omit if only one account is linked.");
|
|
4700
|
+
dateInput = string2().regex(/^\d{4}-\d{2}-\d{2}$/, "Use YYYY-MM-DD").optional();
|
|
4701
|
+
monthInput = string2().regex(/^\d{4}-\d{2}$/, "Use YYYY-MM").optional();
|
|
4702
|
+
});
|
|
4703
|
+
|
|
4704
|
+
// ../../connectors/desco/src/tools/accounts.ts
|
|
4705
|
+
var listAccountsTool, getBalance, getRealtimeStatus, accountTools;
|
|
4706
|
+
var init_accounts2 = __esm(() => {
|
|
4707
|
+
init_src();
|
|
4708
|
+
init_client();
|
|
4709
|
+
init_schemas3();
|
|
4710
|
+
init_factories();
|
|
4711
|
+
listAccountsTool = defineTool({
|
|
4712
|
+
name: "list_accounts",
|
|
4713
|
+
description: "List the DESCO prepaid accounts linked to the signed-in user, with account IDs. Use first when the user has not given an accountId.",
|
|
4714
|
+
access: "read",
|
|
4715
|
+
input: object({}),
|
|
4716
|
+
output: AccountsOut,
|
|
4717
|
+
handler: async (_input, ctx) => ({ accounts: await listAccounts(ctx) })
|
|
4718
|
+
});
|
|
4719
|
+
getBalance = defineTool({
|
|
4720
|
+
name: "get_balance",
|
|
4721
|
+
description: "Get the daily prepaid electricity balance in BDT for a DESCO account. Use when asked about meter balance or remaining credit. Omit accountId if only one account is linked.",
|
|
4722
|
+
access: "read",
|
|
4723
|
+
input: object({ accountId: accountIdInput }),
|
|
4724
|
+
output: BalanceOut,
|
|
4725
|
+
handler: async (input, ctx) => {
|
|
4726
|
+
const accountId = input.accountId ?? await resolveAccountId(ctx);
|
|
4727
|
+
const raw = await ctx.http.json(`/accounts/${accountId}/balance`, RawBalance);
|
|
4728
|
+
const balance = raw.balance ?? null;
|
|
4729
|
+
const timestampAvailable = raw.timestampAvailable !== false;
|
|
4730
|
+
const unavailable = balance === null || !timestampAvailable;
|
|
4731
|
+
return {
|
|
4732
|
+
balance,
|
|
4733
|
+
currency: raw.currency ?? null,
|
|
4734
|
+
balanceSnapshotAt: raw.balanceSnapshotAt ?? null,
|
|
4735
|
+
timestampAvailable,
|
|
4736
|
+
stale: raw.stale === true,
|
|
4737
|
+
currentMonthConsumedTaka: raw.currentMonthConsumedTaka ?? null,
|
|
4738
|
+
readingTime: raw.readingTime ?? null,
|
|
4739
|
+
consumerMessages: raw.consumerMessages ?? [],
|
|
4740
|
+
note: unavailable ? "The balance is unavailable right now. Do not treat it as zero." : "This is a daily snapshot, not a live meter reading. A recent recharge may not appear until the next update."
|
|
4741
|
+
};
|
|
4742
|
+
}
|
|
4743
|
+
});
|
|
4744
|
+
getRealtimeStatus = defineTool({
|
|
4745
|
+
name: "get_realtime_status",
|
|
4746
|
+
description: "Read the last realtime-reading result and whether a new reading is allowed, per meter. Use to explain realtime limits. It does not request a new reading.",
|
|
4747
|
+
access: "read",
|
|
4748
|
+
input: object({}),
|
|
4749
|
+
output: RealtimeOut,
|
|
4750
|
+
handler: async (_input, ctx) => {
|
|
4751
|
+
const raw = await ctx.http.json("/accounts/realtime-balance", RawRealtime);
|
|
4752
|
+
return {
|
|
4753
|
+
enabled: raw.enabled === true,
|
|
4754
|
+
meters: raw.meters.map((meter) => ({
|
|
4755
|
+
accountId: meter.accountId ?? null,
|
|
4756
|
+
meterNoLast4: maskLast4(meter.meterNo),
|
|
4757
|
+
meterType: meter.meterType ?? null,
|
|
4758
|
+
status: meter.status ?? null,
|
|
4759
|
+
message: meter.message ?? null,
|
|
4760
|
+
lastRealtimeBalance: meter.lastRealtimeBalance ?? null,
|
|
4761
|
+
lastRealtimeReceivedAt: meter.lastRealtimeReceivedAt ?? null,
|
|
4762
|
+
nextEligibleAt: meter.nextEligibleAt ?? null,
|
|
4763
|
+
attemptsToday: meter.attemptsToday ?? null,
|
|
4764
|
+
remainingAttempts: meter.remainingAttempts ?? null
|
|
4765
|
+
}))
|
|
4766
|
+
};
|
|
4767
|
+
}
|
|
4768
|
+
});
|
|
4769
|
+
accountTools = [listAccountsTool, getBalance, getRealtimeStatus];
|
|
4770
|
+
});
|
|
4771
|
+
|
|
4772
|
+
// ../../connectors/desco/src/tools/billing.ts
|
|
4773
|
+
var billingTools;
|
|
4774
|
+
var init_billing = __esm(() => {
|
|
4775
|
+
init_factories();
|
|
4776
|
+
billingTools = [
|
|
4777
|
+
accountGet("get_recharge_history", "Recharge transactions for a date range (YYYY-MM-DD).", "/transactions", {
|
|
4778
|
+
dateFrom: dateInput,
|
|
4779
|
+
dateTo: dateInput
|
|
4780
|
+
}),
|
|
4781
|
+
accountGet("get_token_history", "Recharge tokens issued for a date range (YYYY-MM-DD). Tokens are credentials for the meter, so share them only with the account owner.", "/tokens", { dateFrom: dateInput, dateTo: dateInput }),
|
|
4782
|
+
accountGet("get_token_resend_eligibility", "Whether a recharge token can be re-sent for this account. Does not send anything.", "/token-resend/eligibility")
|
|
4783
|
+
];
|
|
4784
|
+
});
|
|
4785
|
+
|
|
4786
|
+
// ../../connectors/desco/src/tools/directory.ts
|
|
4787
|
+
var directoryTools;
|
|
4788
|
+
var init_directory = __esm(() => {
|
|
4789
|
+
init_src();
|
|
4790
|
+
init_factories();
|
|
4791
|
+
directoryTools = [
|
|
4792
|
+
publicSearch("find_recharge_points", "Search DESCO prepaid recharge points (POS shops) by text, bank or area. Bank and area values must match the portal exactly, for example bank 'MYCash', area 'Mirpur'.", "/public/pos-locations", {
|
|
4793
|
+
q: string2().optional().describe("Free-text search on shop name or address."),
|
|
4794
|
+
bank: string2().optional(),
|
|
4795
|
+
area: string2().optional()
|
|
4796
|
+
}),
|
|
4797
|
+
publicGet("list_recharge_point_filters", "Valid bank and area values for find_recharge_points.", "/public/pos-locations/filters"),
|
|
4798
|
+
publicSearch("find_meter_manuals", "Search prepaid meter user manuals (PDF) by manufacturer, phase (SINGLE or THREE) and language.", "/public/meter-manuals", {
|
|
4799
|
+
q: string2().optional(),
|
|
4800
|
+
manufacturer: string2().optional(),
|
|
4801
|
+
phase: _enum(["SINGLE", "THREE"]).optional(),
|
|
4802
|
+
locale: string2().optional()
|
|
4803
|
+
}),
|
|
4804
|
+
publicSearch("find_tutorials", "Search DESCO prepaid video tutorials by text, category and language.", "/public/tutorials", {
|
|
4805
|
+
q: string2().optional(),
|
|
4806
|
+
category: string2().optional(),
|
|
4807
|
+
locale: string2().optional()
|
|
4808
|
+
})
|
|
4809
|
+
];
|
|
4810
|
+
});
|
|
4811
|
+
|
|
4812
|
+
// ../../connectors/desco/src/tools/info.ts
|
|
4813
|
+
var listNotices, infoTools;
|
|
4814
|
+
var init_info = __esm(() => {
|
|
4815
|
+
init_src();
|
|
4816
|
+
init_schemas3();
|
|
4817
|
+
init_factories();
|
|
4818
|
+
listNotices = defineTool({
|
|
4819
|
+
name: "list_notices",
|
|
4820
|
+
description: "Active DESCO portal notices, or the important homepage notices (monthly charges, recharge deductions).",
|
|
4821
|
+
access: "read",
|
|
4822
|
+
input: object({ kind: _enum(["active", "homepage"]).default("active") }),
|
|
4823
|
+
output: DataOut,
|
|
4824
|
+
handler: async (input, ctx) => ({ data: await ctx.http.json(`/public/notices/${input.kind}`, unknown()) })
|
|
4825
|
+
});
|
|
4826
|
+
infoTools = [
|
|
4827
|
+
publicGet("get_tariff", "Current DESCO retail electricity tariff: unit slabs, rates per kWh and demand charges by customer class. Use for price-per-unit questions.", "/public/tariff-schedules/current"),
|
|
4828
|
+
listNotices,
|
|
4829
|
+
publicGet("list_faqs", "DESCO prepaid FAQ in Bangla and English.", "/public/faqs"),
|
|
4830
|
+
publicGet("list_short_codes", "Prepaid meter keypad short codes (e.g. 801 shows balance), grouped by purpose, with meter and phase applicability.", "/public/prepaid-short-codes"),
|
|
4831
|
+
publicGet("list_tariff_documents", "Current tariff orders and circulars published by DESCO, with titles and summaries.", "/public/documents/tariffs/current"),
|
|
4832
|
+
publicGet("list_documents", "All published DESCO tariff documents, forms, circulars and policies.", "/public/documents")
|
|
4833
|
+
];
|
|
4834
|
+
});
|
|
4835
|
+
|
|
4836
|
+
// ../../connectors/desco/src/tools/profile.ts
|
|
4837
|
+
var profileTools;
|
|
4838
|
+
var init_profile = __esm(() => {
|
|
4839
|
+
init_factories();
|
|
4840
|
+
profileTools = [
|
|
4841
|
+
accountGet("get_account_summary", "Summary of a DESCO prepaid account: customer, meter and connection details.", "/summary"),
|
|
4842
|
+
accountGet("get_contact_office", "The DESCO office that serves this account: name, address and phone.", "/contact-office")
|
|
4843
|
+
];
|
|
4844
|
+
});
|
|
4845
|
+
|
|
4846
|
+
// ../../connectors/desco/src/tools/usage.ts
|
|
4847
|
+
var usageTools;
|
|
4848
|
+
var init_usage = __esm(() => {
|
|
4849
|
+
init_src();
|
|
4850
|
+
init_factories();
|
|
4851
|
+
usageTools = [
|
|
4852
|
+
accountGet("get_daily_usage", "Daily electricity usage for a date range. Dates are YYYY-MM-DD.", "/usage/daily", {
|
|
4853
|
+
dateFrom: dateInput,
|
|
4854
|
+
dateTo: dateInput
|
|
4855
|
+
}),
|
|
4856
|
+
accountGet("get_monthly_usage", "Monthly electricity usage for a month range. Months are YYYY-MM.", "/usage/monthly", {
|
|
4857
|
+
monthFrom: monthInput,
|
|
4858
|
+
monthTo: monthInput
|
|
4859
|
+
}),
|
|
4860
|
+
accountGet("get_consumption_comparison", "Compare monthly consumption this year against last year, up to an end month.", "/consumption-comparison", { year: number2().int().min(2000).max(2100).optional(), endMonth: number2().int().min(1).max(12).optional() }),
|
|
4861
|
+
accountGet("get_energy_vs_consumed_taka", "Energy (kWh) versus money consumed (BDT) per month. Months are YYYY-MM.", "/energy-vs-consumed-taka", { monthFrom: monthInput, monthTo: monthInput })
|
|
4862
|
+
];
|
|
4863
|
+
});
|
|
4864
|
+
|
|
4865
|
+
// ../../connectors/desco/src/tools/index.ts
|
|
4866
|
+
var tools;
|
|
4867
|
+
var init_tools = __esm(() => {
|
|
4868
|
+
init_accounts2();
|
|
4869
|
+
init_billing();
|
|
4870
|
+
init_directory();
|
|
4871
|
+
init_info();
|
|
4872
|
+
init_profile();
|
|
4873
|
+
init_usage();
|
|
4874
|
+
tools = [
|
|
4875
|
+
...accountTools,
|
|
4876
|
+
...profileTools,
|
|
4877
|
+
...usageTools,
|
|
4878
|
+
...billingTools,
|
|
4879
|
+
...infoTools,
|
|
4880
|
+
...directoryTools
|
|
4881
|
+
];
|
|
4882
|
+
});
|
|
4883
|
+
|
|
4884
|
+
// ../../connectors/desco/src/index.ts
|
|
4885
|
+
var exports_src = {};
|
|
4886
|
+
__export(exports_src, {
|
|
4887
|
+
default: () => src_default,
|
|
4888
|
+
desco: () => desco
|
|
4889
|
+
});
|
|
4890
|
+
var desco, src_default;
|
|
4891
|
+
var init_src2 = __esm(() => {
|
|
4892
|
+
init_src();
|
|
4893
|
+
init_tools();
|
|
4613
4894
|
desco = defineConnector({
|
|
4614
4895
|
id: "desco",
|
|
4615
|
-
version: "0.
|
|
4896
|
+
version: "0.3.0",
|
|
4616
4897
|
status: "beta",
|
|
4617
|
-
description: "DESCO prepaid electricity:
|
|
4898
|
+
description: "DESCO prepaid electricity: accounts, balance, usage, recharges, tariffs, notices and recharge points (unofficial)",
|
|
4618
4899
|
baseUrl: "https://prepaid.desco.org.bd/api",
|
|
4619
4900
|
auth: formLogin({
|
|
4620
4901
|
csrfPath: "/auth/csrf",
|
|
4621
4902
|
loginPath: "/auth/login",
|
|
4622
4903
|
secrets: { username: "DESCO_USERNAME", password: "DESCO_PASSWORD" }
|
|
4623
4904
|
}),
|
|
4624
|
-
tools
|
|
4625
|
-
defineTool({
|
|
4626
|
-
name: "list_accounts",
|
|
4627
|
-
description: "List the DESCO prepaid accounts linked to the signed-in user, with account IDs. Use first when the user has not given an accountId.",
|
|
4628
|
-
access: "read",
|
|
4629
|
-
input: object({}),
|
|
4630
|
-
output: AccountsOut,
|
|
4631
|
-
handler: async (_input, ctx) => ({ accounts: await listAccounts(ctx) })
|
|
4632
|
-
}),
|
|
4633
|
-
defineTool({
|
|
4634
|
-
name: "get_balance",
|
|
4635
|
-
description: "Get the daily prepaid electricity balance in BDT for a DESCO account. Use when asked about meter balance or remaining credit. Omit accountId if only one account is linked.",
|
|
4636
|
-
access: "read",
|
|
4637
|
-
input: object({
|
|
4638
|
-
accountId: number2().int().positive().optional().describe("Internal accountId from list_accounts, not the account or meter number.")
|
|
4639
|
-
}),
|
|
4640
|
-
output: BalanceOut,
|
|
4641
|
-
handler: async (input, ctx) => {
|
|
4642
|
-
const accountId = input.accountId ?? await resolveAccountId(ctx);
|
|
4643
|
-
const raw = await ctx.http.json(`/accounts/${accountId}/balance`, RawBalance);
|
|
4644
|
-
const balance = raw.balance ?? null;
|
|
4645
|
-
const timestampAvailable = raw.timestampAvailable !== false;
|
|
4646
|
-
const unavailable = balance === null || !timestampAvailable;
|
|
4647
|
-
return {
|
|
4648
|
-
balance,
|
|
4649
|
-
currency: raw.currency ?? null,
|
|
4650
|
-
balanceSnapshotAt: raw.balanceSnapshotAt ?? null,
|
|
4651
|
-
timestampAvailable,
|
|
4652
|
-
stale: raw.stale === true,
|
|
4653
|
-
currentMonthConsumedTaka: raw.currentMonthConsumedTaka ?? null,
|
|
4654
|
-
readingTime: raw.readingTime ?? null,
|
|
4655
|
-
consumerMessages: raw.consumerMessages ?? [],
|
|
4656
|
-
note: unavailable ? "The balance is unavailable right now. Do not treat it as zero." : "This is a daily snapshot, not a live meter reading. A recent recharge may not appear until the next update."
|
|
4657
|
-
};
|
|
4658
|
-
}
|
|
4659
|
-
}),
|
|
4660
|
-
defineTool({
|
|
4661
|
-
name: "get_realtime_status",
|
|
4662
|
-
description: "Read the last realtime-reading result and whether a new reading is allowed, per meter. Use to explain realtime limits. It does not request a new reading.",
|
|
4663
|
-
access: "read",
|
|
4664
|
-
input: object({}),
|
|
4665
|
-
output: RealtimeOut,
|
|
4666
|
-
handler: async (_input, ctx) => {
|
|
4667
|
-
const raw = await ctx.http.json("/accounts/realtime-balance", RawRealtime);
|
|
4668
|
-
return {
|
|
4669
|
-
enabled: raw.enabled === true,
|
|
4670
|
-
meters: raw.meters.map((meter) => ({
|
|
4671
|
-
accountId: meter.accountId ?? null,
|
|
4672
|
-
meterNoLast4: maskLast4(meter.meterNo),
|
|
4673
|
-
meterType: meter.meterType ?? null,
|
|
4674
|
-
status: meter.status ?? null,
|
|
4675
|
-
message: meter.message ?? null,
|
|
4676
|
-
lastRealtimeBalance: meter.lastRealtimeBalance ?? null,
|
|
4677
|
-
lastRealtimeReceivedAt: meter.lastRealtimeReceivedAt ?? null,
|
|
4678
|
-
nextEligibleAt: meter.nextEligibleAt ?? null,
|
|
4679
|
-
attemptsToday: meter.attemptsToday ?? null,
|
|
4680
|
-
remainingAttempts: meter.remainingAttempts ?? null
|
|
4681
|
-
}))
|
|
4682
|
-
};
|
|
4683
|
-
}
|
|
4684
|
-
})
|
|
4685
|
-
]
|
|
4905
|
+
tools
|
|
4686
4906
|
});
|
|
4687
4907
|
src_default = desco;
|
|
4688
4908
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bixbd/utils-mcp",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.6",
|
|
4
4
|
"description": "Connect utility portals to AI agents through MCP. Works with any MCP app via npx; credentials stay on your machine.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mcp",
|
|
@@ -47,8 +47,8 @@
|
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"@bixbd/utils-mcp-connector-example": "0.0.0",
|
|
50
|
-
"@bixbd/utils-mcp-connector-desco": "0.1.0-beta.
|
|
51
|
-
"@bixbd/utils-mcp-core": "0.1.0-beta.
|
|
50
|
+
"@bixbd/utils-mcp-connector-desco": "0.1.0-beta.6",
|
|
51
|
+
"@bixbd/utils-mcp-core": "0.1.0-beta.6",
|
|
52
52
|
"@modelcontextprotocol/sdk": "^1.0.0"
|
|
53
53
|
}
|
|
54
54
|
}
|