@forcedream/mcp-server 0.4.3 → 0.5.1
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/index.js +15 -15
- package/dist/invoke_agent.js +8 -7
- package/dist/search_agents.js +1 -1
- package/dist/search_costs.js +1 -1
- package/dist/search_reliability.js +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -9,8 +9,8 @@ import { searchReliability, searchReliabilitySchema } from './search_reliability
|
|
|
9
9
|
import { searchCosts, searchCostsSchema } from './search_costs.js';
|
|
10
10
|
import { searchProviders } from './search_providers.js';
|
|
11
11
|
const server = new McpServer({ name: 'forcedream', version: '0.3.0' });
|
|
12
|
-
//
|
|
13
|
-
server.registerTool('
|
|
12
|
+
// forcedream_verify_proof — trustless, keyless. Verify a ForceDream proof's Ed25519 signature client-side.
|
|
13
|
+
server.registerTool('forcedream_verify_proof', {
|
|
14
14
|
title: 'Verify a ForceDream proof',
|
|
15
15
|
description: 'Independently verify that a ForceDream agent proof is authentic and untampered, using public-key cryptography. ' +
|
|
16
16
|
'Provide a task_id (proof is fetched from the public endpoint) or a full proof object. Verification runs locally — ' +
|
|
@@ -28,12 +28,12 @@ server.registerTool('verify_proof', {
|
|
|
28
28
|
return { content: [{ type: 'text', text: JSON.stringify({ verified: false, error: e.message }, null, 2) }], isError: true };
|
|
29
29
|
}
|
|
30
30
|
});
|
|
31
|
-
//
|
|
32
|
-
server.registerTool('
|
|
31
|
+
// forcedream_search_agents — keyless discovery of real agents with honest, system-derived metrics.
|
|
32
|
+
server.registerTool('forcedream_search_agents', {
|
|
33
33
|
title: 'Search ForceDream agents',
|
|
34
34
|
description: 'Discover ForceDream agents and their honest, system-derived metrics (proof_count, success_rate). ' +
|
|
35
35
|
'Optionally filter by capability (e.g. "research:citation") or free-text query. No key needed. ' +
|
|
36
|
-
'Every agent listed has real cryptographic proofs you can verify with
|
|
36
|
+
'Every agent listed has real cryptographic proofs you can verify with forcedream_verify_proof.',
|
|
37
37
|
inputSchema: searchAgentsSchema,
|
|
38
38
|
}, async ({ capability, query }) => {
|
|
39
39
|
try {
|
|
@@ -44,11 +44,11 @@ server.registerTool('search_agents', {
|
|
|
44
44
|
return { content: [{ type: 'text', text: JSON.stringify({ error: e.message }, null, 2) }], isError: true };
|
|
45
45
|
}
|
|
46
46
|
});
|
|
47
|
-
//
|
|
48
|
-
server.registerTool('
|
|
47
|
+
// forcedream_invoke_agent — spends balance (needs FD_API_KEY). Returns output + a verifiable proof_id.
|
|
48
|
+
server.registerTool('forcedream_invoke_agent', {
|
|
49
49
|
title: 'Invoke a ForceDream agent',
|
|
50
50
|
description: 'Invoke a ForceDream agent to do real work. SPENDS your balance — requires FD_API_KEY in the server env. ' +
|
|
51
|
-
'Returns the output, what you were charged, and a proof_id you can verify with
|
|
51
|
+
'Returns the output, what you were charged, and a proof_id you can verify with forcedream_verify_proof. ' +
|
|
52
52
|
'Handles honest declines (charged 0) and insufficient balance gracefully. Invokes once; never double-charges.',
|
|
53
53
|
inputSchema: invokeAgentSchema,
|
|
54
54
|
}, async ({ agent_slug, task, max_wait_seconds }) => {
|
|
@@ -60,11 +60,11 @@ server.registerTool('invoke_agent', {
|
|
|
60
60
|
return { content: [{ type: 'text', text: JSON.stringify({ status: 'error', error: e.message }, null, 2) }], isError: true };
|
|
61
61
|
}
|
|
62
62
|
});
|
|
63
|
-
//
|
|
64
|
-
server.registerTool('
|
|
63
|
+
// forcedream_search_reliability — keyless. Real, system-measured reliability per agent.
|
|
64
|
+
server.registerTool('forcedream_search_reliability', {
|
|
65
65
|
title: 'Search agent reliability data',
|
|
66
66
|
description: 'Real, system-measured reliability per agent: success_rate, avg_latency_ms, sample_size. No key needed. ' +
|
|
67
|
-
'Same real data as
|
|
67
|
+
'Same real data as forcedream_search_agents\' health field, exposed standalone for reliability-focused queries.',
|
|
68
68
|
inputSchema: searchReliabilitySchema,
|
|
69
69
|
}, async ({ agent_slug }) => {
|
|
70
70
|
try {
|
|
@@ -75,8 +75,8 @@ server.registerTool('search_reliability', {
|
|
|
75
75
|
return { content: [{ type: 'text', text: JSON.stringify({ error: e.message }, null, 2) }], isError: true };
|
|
76
76
|
}
|
|
77
77
|
});
|
|
78
|
-
//
|
|
79
|
-
server.registerTool('
|
|
78
|
+
// forcedream_search_costs — keyless. Real price_per_call_pence per agent.
|
|
79
|
+
server.registerTool('forcedream_search_costs', {
|
|
80
80
|
title: 'Search agent pricing',
|
|
81
81
|
description: 'Real price_per_call_pence for every registered agent. No key needed. ' +
|
|
82
82
|
'Useful for budget-aware agent selection before invoking.',
|
|
@@ -90,8 +90,8 @@ server.registerTool('search_costs', {
|
|
|
90
90
|
return { content: [{ type: 'text', text: JSON.stringify({ error: e.message }, null, 2) }], isError: true };
|
|
91
91
|
}
|
|
92
92
|
});
|
|
93
|
-
//
|
|
94
|
-
server.registerTool('
|
|
93
|
+
// forcedream_search_providers — keyless. Real, live inference-provider health.
|
|
94
|
+
server.registerTool('forcedream_search_providers', {
|
|
95
95
|
title: 'Search provider health',
|
|
96
96
|
description: 'Real, live inference-provider health: health_score, breaker_state, uptime_ratio, recent successes/failures. ' +
|
|
97
97
|
'The same real intelligence the platform\'s own adaptive routing uses internally. No key needed.',
|
package/dist/invoke_agent.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
const FD_API = process.env.FD_API_BASE || 'https://api.forcedream.ai';
|
|
3
3
|
/**
|
|
4
|
-
* Zod input schema for the
|
|
4
|
+
* Zod input schema for the forcedream_invoke_agent tool. agent_slug and task are required;
|
|
5
5
|
* max_wait_seconds bounds how long this call polls before returning a pollable task_id.
|
|
6
6
|
*/
|
|
7
7
|
export const invokeAgentSchema = {
|
|
8
|
-
agent_slug: z.string().describe('The agent to invoke, e.g. "atlas-research-v1". Use
|
|
8
|
+
agent_slug: z.string().describe('The agent to invoke, e.g. "atlas-research-v1". Use forcedream_search_agents to discover.'),
|
|
9
9
|
task: z.string().describe('The task/query for the agent (Atlas: a research question).'),
|
|
10
10
|
max_wait_seconds: z.number().optional().describe('Max seconds to poll (default 60). On timeout, returns task_id to poll later.'),
|
|
11
11
|
};
|
|
@@ -45,8 +45,9 @@ const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
|
45
45
|
export async function invokeAgent(args) {
|
|
46
46
|
// Mock mode: explicit opt-in only, never a default. Intercepts BEFORE any real network call --
|
|
47
47
|
// no real balance touched, no real agent invoked. Every field is unmistakably labeled so a mock
|
|
48
|
-
// result can never be confused for a real one. Scoped to
|
|
49
|
-
//
|
|
48
|
+
// result can never be confused for a real one. Scoped to forcedream_invoke_agent only:
|
|
49
|
+
// forcedream_search_agents and forcedream_verify_proof are already free and keyless, so mocking
|
|
50
|
+
// them would only make testing worse.
|
|
50
51
|
if (process.env.FD_MOCK_MODE === 'true') {
|
|
51
52
|
return {
|
|
52
53
|
status: 'completed',
|
|
@@ -55,11 +56,11 @@ export async function invokeAgent(args) {
|
|
|
55
56
|
output: { mock: true, note: 'Synthetic mock output. This is not real ForceDream data.' },
|
|
56
57
|
charged_pence: 0,
|
|
57
58
|
mock: true,
|
|
58
|
-
message: 'MOCK MODE ACTIVE (FD_MOCK_MODE=true): no real agent was invoked, no balance was spent, and this response has no real proof_id --
|
|
59
|
+
message: 'MOCK MODE ACTIVE (FD_MOCK_MODE=true): no real agent was invoked, no balance was spent, and this response has no real proof_id -- forcedream_verify_proof will correctly reject it if you try. Unset FD_MOCK_MODE to invoke real agents.',
|
|
59
60
|
};
|
|
60
61
|
}
|
|
61
62
|
if (!process.env.FD_API_KEY) {
|
|
62
|
-
return { status: 'error', agent: args.agent_slug, message: 'FD_API_KEY is required to invoke (invoking spends your balance). Set it in the MCP server env.
|
|
63
|
+
return { status: 'error', agent: args.agent_slug, message: 'FD_API_KEY is required to invoke (invoking spends your balance). Set it in the MCP server env. forcedream_search_agents and forcedream_verify_proof need no key.' };
|
|
63
64
|
}
|
|
64
65
|
const slug = args.agent_slug;
|
|
65
66
|
const maxWaitMs = Math.max(5, Math.min(120, args.max_wait_seconds ?? 60)) * 1000;
|
|
@@ -83,7 +84,7 @@ export async function invokeAgent(args) {
|
|
|
83
84
|
return {
|
|
84
85
|
status: 'completed', agent: slug, task_id: taskId, output: d.output, charged_pence: d.charged_pence,
|
|
85
86
|
proof_id: d.proof_id || taskId,
|
|
86
|
-
verify_proof_hint: `Verify trustlessly: call
|
|
87
|
+
verify_proof_hint: `Verify trustlessly: call forcedream_verify_proof with task_id "${d.proof_id || taskId}". The signature proves authenticity without trusting ForceDream.`,
|
|
87
88
|
message: `Completed. Charged ${d.charged_pence}p. Cryptographically proven (proof_id ${d.proof_id || taskId}).`,
|
|
88
89
|
};
|
|
89
90
|
}
|
package/dist/search_agents.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
const FD_API = process.env.FD_API_BASE || 'https://api.forcedream.ai';
|
|
3
3
|
/**
|
|
4
|
-
* Zod input schema for the
|
|
4
|
+
* Zod input schema for the forcedream_search_agents tool. Both fields optional -- omitting both
|
|
5
5
|
* returns the full real agent registry, merged with live reliability data.
|
|
6
6
|
*/
|
|
7
7
|
export const searchAgentsSchema = {
|
package/dist/search_costs.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
const FD_API = process.env.FD_API_BASE || 'https://api.forcedream.ai';
|
|
3
3
|
/**
|
|
4
|
-
* Zod input schema for
|
|
4
|
+
* Zod input schema for forcedream_search_costs. Optional max_price_pence filter for budget-aware selection.
|
|
5
5
|
*/
|
|
6
6
|
export const searchCostsSchema = {
|
|
7
7
|
max_price_pence: z.number().optional().describe('Optional: only return agents at or under this price.'),
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
const FD_API = process.env.FD_API_BASE || 'https://api.forcedream.ai';
|
|
3
3
|
/**
|
|
4
|
-
* Zod input schema for
|
|
4
|
+
* Zod input schema for forcedream_search_reliability. Optional agent_slug filter; omit for all agents.
|
|
5
5
|
*/
|
|
6
6
|
export const searchReliabilitySchema = {
|
|
7
7
|
agent_slug: z.string().optional().describe('Optional: filter to one agent slug. Omit to return all.'),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forcedream/mcp-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"mcpName": "io.github.forcedreamai/mcp-server",
|
|
5
5
|
"description": "MCP server for ForceDream \u2014 discover, invoke, and trustlessly verify AI agents with cryptographic proofs.",
|
|
6
6
|
"type": "module",
|