@aigne/example-mcp-blocklet 1.9.2 → 1.10.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.
Files changed (3) hide show
  1. package/README.md +38 -3
  2. package/index.ts +35 -39
  3. package/package.json +5 -4
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # MCP Blocklet Demo
2
2
 
3
- This demo demonstrates how to use [AIGNE Framework](https://github.com/AIGNE-io/aigne-framework) and MCP to interact with apps hosted on the [Blocklet platform](https://github.com/blocklet).
3
+ This demo demonstrates how to use [AIGNE Framework](https://github.com/AIGNE-io/aigne-framework) and MCP to interact with apps hosted on the [Blocklet platform](https://github.com/blocklet). The example now supports both one-shot and interactive chat modes, along with customizable model settings and pipeline input/output.
4
4
 
5
5
  ## Prerequisites
6
6
 
@@ -15,7 +15,14 @@ This demo demonstrates how to use [AIGNE Framework](https://github.com/AIGNE-io/
15
15
  ```bash
16
16
  export OPENAI_API_KEY=YOUR_OPENAI_API_KEY # Set your OpenAI API key
17
17
 
18
- npx -y @aigne/example-mcp-blocklet # Run the example
18
+ # Run in one-shot mode (default)
19
+ npx -y @aigne/example-mcp-blocklet
20
+
21
+ # Run in interactive chat mode
22
+ npx -y @aigne/example-mcp-blocklet --chat
23
+
24
+ # Use pipeline input
25
+ echo "What are the features of this blocklet app?" | npx -y @aigne/example-mcp-blocklet
19
26
  ```
20
27
 
21
28
  ## Installation
@@ -46,7 +53,7 @@ BLOCKLET_APP_URL="" # Set your Blocklet app URL here
46
53
  ### Run the Example
47
54
 
48
55
  ```bash
49
- pnpm start
56
+ pnpm start # Run in one-shot mode (default)
50
57
  ```
51
58
 
52
59
  or
@@ -55,6 +62,34 @@ or
55
62
  pnpm start https://your-blocklet-app-url
56
63
  ```
57
64
 
65
+ ### Run Options
66
+
67
+ The example supports the following command-line parameters:
68
+
69
+ | Parameter | Description | Default |
70
+ |-----------|-------------|---------|
71
+ | `--chat` | Run in interactive chat mode | Disabled (one-shot mode) |
72
+ | `--model <provider[:model]>` | AI model to use in format 'provider[:model]' where model is optional. Examples: 'openai' or 'openai:gpt-4o-mini' | openai |
73
+ | `--temperature <value>` | Temperature for model generation | Provider default |
74
+ | `--top-p <value>` | Top-p sampling value | Provider default |
75
+ | `--presence-penalty <value>` | Presence penalty value | Provider default |
76
+ | `--frequency-penalty <value>` | Frequency penalty value | Provider default |
77
+ | `--log-level <level>` | Set logging level (ERROR, WARN, INFO, DEBUG, TRACE) | INFO |
78
+ | `--input`, `-i <input>` | Specify input directly | None |
79
+
80
+ #### Examples
81
+
82
+ ```bash
83
+ # Run in chat mode (interactive)
84
+ pnpm start -- --chat
85
+
86
+ # Set logging level
87
+ pnpm start -- --log-level DEBUG
88
+
89
+ # Use pipeline input
90
+ echo "What are the features of this blocklet app?" | pnpm start
91
+ ```
92
+
58
93
  ## License
59
94
 
60
95
  This project is licensed under the MIT License.
package/index.ts CHANGED
@@ -1,19 +1,13 @@
1
1
  #!/usr/bin/env bunwrapper
2
2
 
3
3
  import assert from "node:assert";
4
- import { runChatLoopInTerminal } from "@aigne/cli/utils/run-chat-loop.js";
5
- import { AIAgent, AIGNE, MCPAgent, PromptBuilder } from "@aigne/core";
6
- import { loadModel } from "@aigne/core/loader/index.js";
7
- import { logger } from "@aigne/core/utils/logger.js";
4
+ import { runWithAIGNE } from "@aigne/cli/utils/run-with-aigne.js";
5
+ import { AIAgent, MCPAgent, PromptBuilder } from "@aigne/core";
8
6
  import { UnauthorizedError, refreshAuthorization } from "@modelcontextprotocol/sdk/client/auth.js";
9
7
  import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
10
- // @ts-ignore
11
8
  import JWT from "jsonwebtoken";
12
-
13
9
  import { TerminalOAuthProvider } from "./oauth.js";
14
10
 
15
- logger.enable(`aigne:mcp,${process.env.DEBUG}`);
16
-
17
11
  const rawUrl = process.argv[2] || process.env.BLOCKLET_APP_URL;
18
12
  assert(
19
13
  rawUrl,
@@ -56,9 +50,12 @@ try {
56
50
  let tokens = await provider.tokens();
57
51
  if (tokens) {
58
52
  let decoded = JWT.decode(tokens.access_token);
59
- if (decoded) {
53
+ if (decoded && typeof decoded === "object") {
54
+ const exp = decoded.exp;
55
+ assert(typeof exp === "number", "Invalid access token");
56
+
60
57
  const now = Date.now();
61
- const expiresAt = decoded.exp * 1000;
58
+ const expiresAt = exp * 1000;
62
59
  if (now < expiresAt) {
63
60
  console.info("Tokens already exist and not expired, skipping authorization");
64
61
  } else if (tokens.refresh_token) {
@@ -66,7 +63,7 @@ try {
66
63
  decoded = JWT.decode(tokens.refresh_token);
67
64
  if (decoded) {
68
65
  const now = Date.now();
69
- const expiresAt = decoded.exp * 1000;
66
+ const expiresAt = exp * 1000;
70
67
  if (now < expiresAt) {
71
68
  console.info("Refresh token already exists and not expired, refreshing authorization");
72
69
  try {
@@ -111,34 +108,33 @@ try {
111
108
  }
112
109
  }
113
110
 
114
- const model = await loadModel();
115
-
116
- const blocklet = await MCPAgent.from({
117
- url: appUrl.href,
118
- transport: "streamableHttp",
119
- opts: {
120
- authProvider: provider,
111
+ await runWithAIGNE(
112
+ async () => {
113
+ const blocklet = await MCPAgent.from({
114
+ url: appUrl.href,
115
+ transport: "streamableHttp",
116
+ opts: {
117
+ authProvider: provider,
118
+ },
119
+ });
120
+
121
+ const agent = AIAgent.from({
122
+ instructions: PromptBuilder.from(
123
+ "You are a helpful assistant that can help users query and analyze data from the blocklet. You can perform various database queries on the blocklet database, before performing any queries, please try to understand the user's request and generate a query base on the database schema.",
124
+ ),
125
+ skills: [blocklet],
126
+ memory: true,
127
+ });
128
+
129
+ return agent;
121
130
  },
122
- });
123
-
124
- const aigne = new AIGNE({
125
- model,
126
- skills: [blocklet],
127
- });
128
-
129
- const agent = AIAgent.from({
130
- instructions: PromptBuilder.from(
131
- "You are a helpful assistant that can help users query and analyze data from the blocklet. You can perform various database queries on the blocklet database, before performing any queries, please try to understand the user's request and generate a query base on the database schema.",
132
- ),
133
- memory: true,
134
- });
135
-
136
- const userAgent = aigne.invoke(agent);
137
-
138
- await runChatLoopInTerminal(userAgent, {
139
- welcome:
140
- "Hello! I'm a chatbot that can help you interact with the blocklet. Try asking me a question about the blocklet!",
141
- defaultQuestion: "How many users are there in the database?",
142
- });
131
+ {
132
+ chatLoopOptions: {
133
+ welcome:
134
+ "Hello! I'm a chatbot that can help you interact with the blocklet. Try asking me a question about the blocklet!",
135
+ defaultQuestion: "How many users are there in the database?",
136
+ },
137
+ },
138
+ );
143
139
 
144
140
  process.exit(0);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aigne/example-mcp-blocklet",
3
- "version": "1.9.2",
3
+ "version": "1.10.0",
4
4
  "description": "A demonstration of using AIGNE Framework and MCP Server hosted by the Blocklet platform",
5
5
  "author": "Arcblock <blocklet@arcblock.io> https://github.com/blocklet",
6
6
  "homepage": "https://github.com/AIGNE-io/aigne-framework/tree/main/examples/mcp-blocklet",
@@ -20,11 +20,12 @@
20
20
  "jsonwebtoken": "^9.0.2",
21
21
  "open": "^10.1.2",
22
22
  "zod": "^3.24.4",
23
- "@aigne/cli": "^1.9.1",
24
- "@aigne/core": "^1.15.0"
23
+ "@aigne/cli": "^1.10.0",
24
+ "@aigne/core": "^1.16.0"
25
25
  },
26
26
  "devDependencies": {
27
- "@aigne/test-utils": "^0.2.0"
27
+ "@types/jsonwebtoken": "^9.0.9",
28
+ "@aigne/test-utils": "^0.3.0"
28
29
  },
29
30
  "scripts": {
30
31
  "start": "bun run index.ts",