@fibukiapp/openclaw-plugin 0.1.0
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/README.md +105 -0
- package/openclaw.plugin.json +27 -0
- package/package.json +24 -0
- package/skills/fibuki-guide/SKILL.md +97 -0
- package/src/index.ts +287 -0
- package/tsconfig.json +14 -0
package/README.md
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# FiBuKI OpenClaw Plugin
|
|
2
|
+
|
|
3
|
+
Manage your FiBuKI tax accounting data through AI assistants.
|
|
4
|
+
|
|
5
|
+
## What Claude Can Do
|
|
6
|
+
|
|
7
|
+
| Task | Tools Used |
|
|
8
|
+
|------|------------|
|
|
9
|
+
| **View bank accounts** | `list_sources`, `get_source` |
|
|
10
|
+
| **Browse transactions** | `list_transactions`, `get_transaction` |
|
|
11
|
+
| **Find incomplete work** | `list_transactions` (isComplete=false), `list_transactions_needing_files` |
|
|
12
|
+
| **Match receipts** | `list_files`, `connect_file_to_transaction`, `auto_connect_file_suggestions` |
|
|
13
|
+
| **Categorize transactions** | `list_no_receipt_categories`, `assign_no_receipt_category` |
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# From npm (when published)
|
|
19
|
+
openclaw plugins install @fibuki/openclaw-plugin
|
|
20
|
+
|
|
21
|
+
# Or link locally for development
|
|
22
|
+
cd integrations/openclaw-plugin
|
|
23
|
+
openclaw plugins install -l .
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Configuration
|
|
27
|
+
|
|
28
|
+
1. **Generate an API Key** in FiBuKI:
|
|
29
|
+
- Go to **Settings > Integrations > AI Agents**
|
|
30
|
+
- Click "Create API Key"
|
|
31
|
+
- Copy the key (starts with `fk_`)
|
|
32
|
+
|
|
33
|
+
2. **Add to OpenClaw config:**
|
|
34
|
+
|
|
35
|
+
```json5
|
|
36
|
+
{
|
|
37
|
+
plugins: {
|
|
38
|
+
entries: {
|
|
39
|
+
"fibuki": {
|
|
40
|
+
enabled: true,
|
|
41
|
+
config: {
|
|
42
|
+
apiKey: "fk_your_api_key_here"
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Available Tools
|
|
51
|
+
|
|
52
|
+
### Bank Accounts
|
|
53
|
+
- `list_sources` - List all connected bank accounts
|
|
54
|
+
- `get_source` - Get details of a specific account
|
|
55
|
+
|
|
56
|
+
### Transactions
|
|
57
|
+
- `list_transactions` - Search/filter transactions (use `isComplete: false` for incomplete)
|
|
58
|
+
- `get_transaction` - Get full transaction details
|
|
59
|
+
- `update_transaction` - Update description, mark complete
|
|
60
|
+
|
|
61
|
+
### Files (Receipts/Invoices)
|
|
62
|
+
- `list_files` - List uploaded files with match suggestions
|
|
63
|
+
- `get_file` - Get file details including extracted data
|
|
64
|
+
- `connect_file_to_transaction` - Link file to transaction
|
|
65
|
+
- `disconnect_file_from_transaction` - Unlink file
|
|
66
|
+
- `list_transactions_needing_files` - Find transactions without receipts
|
|
67
|
+
- `auto_connect_file_suggestions` - Bulk-connect high-confidence matches
|
|
68
|
+
|
|
69
|
+
### No-Receipt Categories
|
|
70
|
+
- `list_no_receipt_categories` - List categories (bank fees, payroll, etc.)
|
|
71
|
+
- `assign_no_receipt_category` - Mark transaction as not needing receipt
|
|
72
|
+
- `remove_no_receipt_category` - Remove category from transaction
|
|
73
|
+
|
|
74
|
+
## Example Conversations
|
|
75
|
+
|
|
76
|
+
**User:** "Show me incomplete transactions from last month"
|
|
77
|
+
```
|
|
78
|
+
Claude uses: list_transactions with isComplete=false, dateFrom, dateTo
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
**User:** "Match all my unconnected receipts"
|
|
82
|
+
```
|
|
83
|
+
Claude uses: auto_connect_file_suggestions
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
**User:** "The bank fee doesn't need a receipt"
|
|
87
|
+
```
|
|
88
|
+
Claude uses: list_no_receipt_categories, then assign_no_receipt_category
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## API Key Security
|
|
92
|
+
|
|
93
|
+
- API keys are hashed before storage (we never store the raw key)
|
|
94
|
+
- Keys can be revoked anytime in Settings
|
|
95
|
+
- Each key tracks last used time and usage count
|
|
96
|
+
- Maximum 5 active keys per user
|
|
97
|
+
- Optional expiry dates supported
|
|
98
|
+
|
|
99
|
+
## Domain Context
|
|
100
|
+
|
|
101
|
+
The plugin includes a skills file (`skills/fibuki-guide/SKILL.md`) that gives Claude context about:
|
|
102
|
+
- FiBuKI's data model (sources, transactions, files, partners)
|
|
103
|
+
- Transaction completion logic
|
|
104
|
+
- Amount handling (cents, not euros!)
|
|
105
|
+
- Common workflows
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "fibuki",
|
|
3
|
+
"name": "FiBuKI Tax Studio",
|
|
4
|
+
"description": "Manage bank transactions, receipts, files, and tax categorization through FiBuKI. 15+ tools for transactions, files, and categories.",
|
|
5
|
+
"skills": ["skills/fibuki-guide"],
|
|
6
|
+
"channel": {
|
|
7
|
+
"docsPath": "/integrations/fibuki",
|
|
8
|
+
"blurb": "German tax accounting automation"
|
|
9
|
+
},
|
|
10
|
+
"configSchema": {
|
|
11
|
+
"type": "object",
|
|
12
|
+
"properties": {
|
|
13
|
+
"apiKey": {
|
|
14
|
+
"type": "string",
|
|
15
|
+
"description": "Your FiBuKI API key (generate at Settings > Integrations > AI Agents)"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"required": ["apiKey"]
|
|
19
|
+
},
|
|
20
|
+
"uiHints": {
|
|
21
|
+
"apiKey": {
|
|
22
|
+
"label": "API Key",
|
|
23
|
+
"placeholder": "fk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
|
24
|
+
"sensitive": true
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@fibukiapp/openclaw-plugin",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "FiBuKI Tax Studio plugin for OpenClaw - manage transactions, receipts, and tax categorization",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "src/index.ts",
|
|
7
|
+
"openclaw": {
|
|
8
|
+
"extensions": ["./src/index.ts"]
|
|
9
|
+
},
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "https://github.com/fibuki/openclaw-plugin"
|
|
13
|
+
},
|
|
14
|
+
"keywords": ["openclaw", "fibuki", "tax", "accounting", "receipts", "invoices"],
|
|
15
|
+
"author": "FiBuKI",
|
|
16
|
+
"license": "MIT",
|
|
17
|
+
"scripts": {
|
|
18
|
+
"typecheck": "tsc --noEmit"
|
|
19
|
+
},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"@types/node": "^20.0.0",
|
|
22
|
+
"typescript": "^5.9.0"
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# FiBuKI Tax Accounting Guide
|
|
2
|
+
|
|
3
|
+
You are helping manage a FiBuKI tax accounting account. This guide explains the domain.
|
|
4
|
+
|
|
5
|
+
## What is FiBuKI?
|
|
6
|
+
|
|
7
|
+
FiBuKI is a German tax accounting tool for small businesses and freelancers. It helps users:
|
|
8
|
+
- Import bank transactions (via CSV or Open Banking)
|
|
9
|
+
- Upload and match receipts/invoices to transactions
|
|
10
|
+
- Categorize transactions for tax purposes
|
|
11
|
+
- Track completion status for bookkeeping
|
|
12
|
+
|
|
13
|
+
## Core Data Model
|
|
14
|
+
|
|
15
|
+
### Sources (Bank Accounts)
|
|
16
|
+
- Represent bank accounts or credit cards
|
|
17
|
+
- Transactions are imported from sources
|
|
18
|
+
- Types: `bank_account`, `credit_card`
|
|
19
|
+
- Can be connected via CSV upload or Open Banking (GoCardless)
|
|
20
|
+
|
|
21
|
+
### Transactions
|
|
22
|
+
- Individual bank movements (debits/credits)
|
|
23
|
+
- Have: date, amount (in cents!), name, partner
|
|
24
|
+
- **Cannot be individually deleted** (accounting integrity)
|
|
25
|
+
- Complete when they have a file OR a no-receipt category
|
|
26
|
+
|
|
27
|
+
### Files (Receipts/Invoices)
|
|
28
|
+
- Uploaded PDFs or images
|
|
29
|
+
- AI extracts: amount, date, VAT, partner
|
|
30
|
+
- System suggests matching transactions (transactionSuggestions)
|
|
31
|
+
- Many-to-many relationship with transactions
|
|
32
|
+
|
|
33
|
+
### Partners
|
|
34
|
+
- Companies or people the user transacts with
|
|
35
|
+
- Examples: "Amazon", "REWE", "Deutsche Telekom"
|
|
36
|
+
- System auto-detects partners from transaction names
|
|
37
|
+
|
|
38
|
+
### No-Receipt Categories
|
|
39
|
+
- For transactions that don't need receipts
|
|
40
|
+
- Examples: Bank fees, Interest, Internal transfers, Payroll, Taxes
|
|
41
|
+
- Assigning a category marks the transaction complete
|
|
42
|
+
|
|
43
|
+
## Transaction Completion Logic
|
|
44
|
+
|
|
45
|
+
A transaction is **complete** (isComplete=true) when:
|
|
46
|
+
1. It has at least one connected file (fileIds.length > 0), OR
|
|
47
|
+
2. It has a no-receipt category assigned (noReceiptCategoryId is set)
|
|
48
|
+
|
|
49
|
+
Your goal: Help the user get all transactions to complete status.
|
|
50
|
+
|
|
51
|
+
## Common Workflows
|
|
52
|
+
|
|
53
|
+
### 1. Review Incomplete Transactions
|
|
54
|
+
```
|
|
55
|
+
list_transactions with isComplete=false
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### 2. Match Files to Transactions
|
|
59
|
+
```
|
|
60
|
+
1. list_files with hasConnections=false (unmatched files)
|
|
61
|
+
2. Look at transactionSuggestions on each file
|
|
62
|
+
3. connect_file_to_transaction for good matches
|
|
63
|
+
4. Or use auto_connect_file_suggestions for bulk matching
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### 3. Categorize No-Receipt Transactions
|
|
67
|
+
```
|
|
68
|
+
1. list_no_receipt_categories (get available categories)
|
|
69
|
+
2. assign_no_receipt_category for bank fees, transfers, etc.
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### 4. Find Transactions Needing Receipts
|
|
73
|
+
```
|
|
74
|
+
list_transactions_needing_files
|
|
75
|
+
```
|
|
76
|
+
Returns transactions without files AND without no-receipt categories.
|
|
77
|
+
|
|
78
|
+
## Amount Handling
|
|
79
|
+
|
|
80
|
+
**All amounts are in CENTS (integer)**
|
|
81
|
+
- 10.50 EUR = 1050
|
|
82
|
+
- -25.00 EUR = -2500 (negative = expense)
|
|
83
|
+
- When displaying to user, divide by 100
|
|
84
|
+
|
|
85
|
+
## Date Handling
|
|
86
|
+
|
|
87
|
+
All dates are ISO 8601 format:
|
|
88
|
+
- `2024-01-15` for date-only
|
|
89
|
+
- `2024-01-15T10:30:00Z` for timestamps
|
|
90
|
+
|
|
91
|
+
## Important Rules
|
|
92
|
+
|
|
93
|
+
1. **Never delete individual transactions** - They must be deleted with their source
|
|
94
|
+
2. **Amounts are in cents** - Always divide by 100 for display
|
|
95
|
+
3. **Files can connect to multiple transactions** - Many-to-many relationship
|
|
96
|
+
4. **Trust transactionSuggestions** - Server-side matching is accurate
|
|
97
|
+
5. **High confidence = 85+** - Auto-connect suggestions above this threshold
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FiBuKI OpenClaw Plugin
|
|
3
|
+
*
|
|
4
|
+
* Exposes FiBuKI tools as OpenClaw agent tools via the FiBuKI HTTP API.
|
|
5
|
+
* Users authenticate with an API key generated in FiBuKI Settings.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const API_BASE_URL = "https://europe-west1-taxstudio-f12fb.cloudfunctions.net";
|
|
9
|
+
|
|
10
|
+
// OpenClaw plugin API types
|
|
11
|
+
interface OpenClawApi {
|
|
12
|
+
config: PluginConfig;
|
|
13
|
+
logger: {
|
|
14
|
+
info: (msg: string) => void;
|
|
15
|
+
error: (msg: string) => void;
|
|
16
|
+
debug: (msg: string) => void;
|
|
17
|
+
};
|
|
18
|
+
registerAgentTool: (tool: AgentTool) => void;
|
|
19
|
+
registerService: (service: Service) => void;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
interface PluginConfig {
|
|
23
|
+
apiKey?: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
interface AgentTool {
|
|
27
|
+
name: string;
|
|
28
|
+
description: string;
|
|
29
|
+
inputSchema: Record<string, unknown>;
|
|
30
|
+
handler: (args: Record<string, unknown>) => Promise<string>;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
interface Service {
|
|
34
|
+
id: string;
|
|
35
|
+
start: () => void;
|
|
36
|
+
stop: () => void;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Tool definitions with full documentation for Claude
|
|
40
|
+
const TOOL_DEFINITIONS: AgentTool[] = [
|
|
41
|
+
// ========== SOURCES ==========
|
|
42
|
+
{
|
|
43
|
+
name: "list_sources",
|
|
44
|
+
description: "List all bank accounts/sources for the user. Returns account names, IBANs, types (bank_account/credit_card), and currency.",
|
|
45
|
+
inputSchema: { type: "object", properties: {} },
|
|
46
|
+
handler: async () => "", // Placeholder, replaced at registration
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
name: "get_source",
|
|
50
|
+
description: "Get details of a specific bank account/source by ID.",
|
|
51
|
+
inputSchema: {
|
|
52
|
+
type: "object",
|
|
53
|
+
properties: {
|
|
54
|
+
sourceId: { type: "string", description: "The bank account/source ID" },
|
|
55
|
+
},
|
|
56
|
+
required: ["sourceId"],
|
|
57
|
+
},
|
|
58
|
+
handler: async () => "",
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
// ========== TRANSACTIONS ==========
|
|
62
|
+
{
|
|
63
|
+
name: "list_transactions",
|
|
64
|
+
description:
|
|
65
|
+
"List transactions with optional filters. Returns date, amount (in cents!), partner, description, completion status. Use isComplete=false to find incomplete transactions.",
|
|
66
|
+
inputSchema: {
|
|
67
|
+
type: "object",
|
|
68
|
+
properties: {
|
|
69
|
+
sourceId: { type: "string", description: "Filter by bank account ID" },
|
|
70
|
+
dateFrom: { type: "string", description: "Start date (ISO format: 2024-01-01)" },
|
|
71
|
+
dateTo: { type: "string", description: "End date (ISO format)" },
|
|
72
|
+
search: { type: "string", description: "Search in name, description, partner" },
|
|
73
|
+
isComplete: { type: "boolean", description: "Filter by completion status" },
|
|
74
|
+
limit: { type: "number", description: "Max results (default 50, max 100)" },
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
handler: async () => "",
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
name: "get_transaction",
|
|
81
|
+
description: "Get full details of a specific transaction including partner suggestions and file attachments.",
|
|
82
|
+
inputSchema: {
|
|
83
|
+
type: "object",
|
|
84
|
+
properties: {
|
|
85
|
+
transactionId: { type: "string", description: "The transaction ID" },
|
|
86
|
+
},
|
|
87
|
+
required: ["transactionId"],
|
|
88
|
+
},
|
|
89
|
+
handler: async () => "",
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
name: "update_transaction",
|
|
93
|
+
description: "Update a transaction's description or completion status. Use for adding tax-relevant notes.",
|
|
94
|
+
inputSchema: {
|
|
95
|
+
type: "object",
|
|
96
|
+
properties: {
|
|
97
|
+
transactionId: { type: "string", description: "The transaction ID" },
|
|
98
|
+
description: { type: "string", description: "Description for tax purposes" },
|
|
99
|
+
isComplete: { type: "boolean", description: "Mark as complete/incomplete" },
|
|
100
|
+
},
|
|
101
|
+
required: ["transactionId"],
|
|
102
|
+
},
|
|
103
|
+
handler: async () => "",
|
|
104
|
+
},
|
|
105
|
+
|
|
106
|
+
// ========== FILES ==========
|
|
107
|
+
{
|
|
108
|
+
name: "list_files",
|
|
109
|
+
description:
|
|
110
|
+
"List uploaded files (receipts/invoices) with match suggestions. Files have transactionSuggestions with confidence scores. Use hasConnections=false to find unmatched files.",
|
|
111
|
+
inputSchema: {
|
|
112
|
+
type: "object",
|
|
113
|
+
properties: {
|
|
114
|
+
hasConnections: { type: "boolean", description: "true = matched files, false = unmatched" },
|
|
115
|
+
hasSuggestions: { type: "boolean", description: "Filter by whether file has transaction suggestions" },
|
|
116
|
+
limit: { type: "number", description: "Max results (default 50)" },
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
handler: async () => "",
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
name: "get_file",
|
|
123
|
+
description: "Get full details of a file including extracted data (amount, date, partner) and transaction suggestions.",
|
|
124
|
+
inputSchema: {
|
|
125
|
+
type: "object",
|
|
126
|
+
properties: {
|
|
127
|
+
fileId: { type: "string", description: "The file ID" },
|
|
128
|
+
},
|
|
129
|
+
required: ["fileId"],
|
|
130
|
+
},
|
|
131
|
+
handler: async () => "",
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
name: "connect_file_to_transaction",
|
|
135
|
+
description:
|
|
136
|
+
"Connect a file (receipt) to a transaction. This marks the transaction as complete. Use when you've confirmed a file matches a transaction.",
|
|
137
|
+
inputSchema: {
|
|
138
|
+
type: "object",
|
|
139
|
+
properties: {
|
|
140
|
+
fileId: { type: "string", description: "The file ID to connect" },
|
|
141
|
+
transactionId: { type: "string", description: "The transaction ID to connect to" },
|
|
142
|
+
},
|
|
143
|
+
required: ["fileId", "transactionId"],
|
|
144
|
+
},
|
|
145
|
+
handler: async () => "",
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
name: "disconnect_file_from_transaction",
|
|
149
|
+
description: "Disconnect a file from a transaction. Use when a match was incorrect.",
|
|
150
|
+
inputSchema: {
|
|
151
|
+
type: "object",
|
|
152
|
+
properties: {
|
|
153
|
+
fileId: { type: "string", description: "The file ID" },
|
|
154
|
+
transactionId: { type: "string", description: "The transaction ID" },
|
|
155
|
+
},
|
|
156
|
+
required: ["fileId", "transactionId"],
|
|
157
|
+
},
|
|
158
|
+
handler: async () => "",
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
name: "list_transactions_needing_files",
|
|
162
|
+
description:
|
|
163
|
+
"Find transactions without receipts (no files connected AND no no-receipt category). These need action.",
|
|
164
|
+
inputSchema: {
|
|
165
|
+
type: "object",
|
|
166
|
+
properties: {
|
|
167
|
+
minAmount: { type: "number", description: "Minimum amount in cents (absolute value)" },
|
|
168
|
+
limit: { type: "number", description: "Max results (default 50)" },
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
handler: async () => "",
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
name: "auto_connect_file_suggestions",
|
|
175
|
+
description:
|
|
176
|
+
"Automatically connect files to transactions where suggestion confidence is above threshold. Great for bulk matching. Default threshold is 89%.",
|
|
177
|
+
inputSchema: {
|
|
178
|
+
type: "object",
|
|
179
|
+
properties: {
|
|
180
|
+
fileId: { type: "string", description: "Specific file ID, or omit for all unmatched files" },
|
|
181
|
+
minConfidence: { type: "number", description: "Minimum confidence 0-100 (default 89)" },
|
|
182
|
+
},
|
|
183
|
+
},
|
|
184
|
+
handler: async () => "",
|
|
185
|
+
},
|
|
186
|
+
|
|
187
|
+
// ========== CATEGORIES ==========
|
|
188
|
+
{
|
|
189
|
+
name: "list_no_receipt_categories",
|
|
190
|
+
description:
|
|
191
|
+
"List categories for transactions that don't need receipts: Bank fees, Interest, Internal transfers, Payroll, Taxes, etc.",
|
|
192
|
+
inputSchema: { type: "object", properties: {} },
|
|
193
|
+
handler: async () => "",
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
name: "assign_no_receipt_category",
|
|
197
|
+
description:
|
|
198
|
+
"Assign a no-receipt category to a transaction. This marks it complete without needing a file. Use for bank fees, interest, internal transfers, etc.",
|
|
199
|
+
inputSchema: {
|
|
200
|
+
type: "object",
|
|
201
|
+
properties: {
|
|
202
|
+
transactionId: { type: "string", description: "The transaction ID" },
|
|
203
|
+
categoryId: { type: "string", description: "The category ID to assign" },
|
|
204
|
+
},
|
|
205
|
+
required: ["transactionId", "categoryId"],
|
|
206
|
+
},
|
|
207
|
+
handler: async () => "",
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
name: "remove_no_receipt_category",
|
|
211
|
+
description: "Remove a no-receipt category from a transaction.",
|
|
212
|
+
inputSchema: {
|
|
213
|
+
type: "object",
|
|
214
|
+
properties: {
|
|
215
|
+
transactionId: { type: "string", description: "The transaction ID" },
|
|
216
|
+
},
|
|
217
|
+
required: ["transactionId"],
|
|
218
|
+
},
|
|
219
|
+
handler: async () => "",
|
|
220
|
+
},
|
|
221
|
+
];
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Call the FiBuKI MCP API
|
|
225
|
+
*/
|
|
226
|
+
async function callApi(
|
|
227
|
+
apiKey: string,
|
|
228
|
+
tool: string,
|
|
229
|
+
args: Record<string, unknown>
|
|
230
|
+
): Promise<string> {
|
|
231
|
+
const response = await fetch(`${API_BASE_URL}/mcpApi`, {
|
|
232
|
+
method: "POST",
|
|
233
|
+
headers: {
|
|
234
|
+
"Content-Type": "application/json",
|
|
235
|
+
Authorization: `Bearer ${apiKey}`,
|
|
236
|
+
},
|
|
237
|
+
body: JSON.stringify({ tool, arguments: args }),
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
const data = await response.json();
|
|
241
|
+
|
|
242
|
+
if (!response.ok || !data.success) {
|
|
243
|
+
throw new Error(data.error || `API error: ${response.status}`);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
return JSON.stringify(data.result, null, 2);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Main plugin registration function
|
|
251
|
+
*/
|
|
252
|
+
export default function register(api: OpenClawApi) {
|
|
253
|
+
const { config, logger } = api;
|
|
254
|
+
|
|
255
|
+
// Validate required config
|
|
256
|
+
if (!config.apiKey) {
|
|
257
|
+
logger.error("FiBuKI plugin requires apiKey in config. Generate one at Settings > Integrations > AI Agents");
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
const apiKey = config.apiKey;
|
|
262
|
+
logger.info("FiBuKI plugin initializing...");
|
|
263
|
+
|
|
264
|
+
// Register all tools
|
|
265
|
+
for (const toolDef of TOOL_DEFINITIONS) {
|
|
266
|
+
api.registerAgentTool({
|
|
267
|
+
name: toolDef.name,
|
|
268
|
+
description: toolDef.description,
|
|
269
|
+
inputSchema: toolDef.inputSchema,
|
|
270
|
+
handler: async (args) => {
|
|
271
|
+
try {
|
|
272
|
+
return await callApi(apiKey, toolDef.name, args);
|
|
273
|
+
} catch (error) {
|
|
274
|
+
const msg = error instanceof Error ? error.message : "Unknown error";
|
|
275
|
+
return `Error: ${msg}`;
|
|
276
|
+
}
|
|
277
|
+
},
|
|
278
|
+
});
|
|
279
|
+
logger.debug(`Registered tool: ${toolDef.name}`);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
logger.info(`FiBuKI plugin loaded with ${TOOL_DEFINITIONS.length} tools`);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// Export plugin metadata
|
|
286
|
+
export const id = "fibuki";
|
|
287
|
+
export const name = "FiBuKI Tax Studio";
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "bundler",
|
|
6
|
+
"esModuleInterop": true,
|
|
7
|
+
"strict": true,
|
|
8
|
+
"skipLibCheck": true,
|
|
9
|
+
"outDir": "dist",
|
|
10
|
+
"declaration": true,
|
|
11
|
+
"resolveJsonModule": true
|
|
12
|
+
},
|
|
13
|
+
"include": ["src/**/*"]
|
|
14
|
+
}
|