@askmesh/mcp 0.4.1 → 0.5.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.
@@ -7,4 +7,5 @@ export declare class AutoResponder {
7
7
  constructor(client: AskMeshClient);
8
8
  setServer(server: Server): void;
9
9
  handleRequest(request: IncomingRequest): Promise<void>;
10
+ private callAnthropicAPI;
10
11
  }
@@ -1,4 +1,11 @@
1
1
  import { readLocalContext } from './context_reader.js';
2
+ const SYSTEM_PROMPT = `You are an AI coding agent responding on behalf of a developer through AskMesh.
3
+ You have access to the developer's project context below.
4
+ Use this context to answer accurately and concisely.
5
+ Reference specific files, conventions, or decisions when relevant.
6
+ If the context doesn't contain enough info, say so honestly.
7
+ Answer in the same language as the question.
8
+ Keep responses under 500 words unless more detail is needed.`;
2
9
  export class AutoResponder {
3
10
  client;
4
11
  mcpServer = null;
@@ -14,7 +21,6 @@ export class AutoResponder {
14
21
  // Uses the user's existing Claude subscription, no API key needed
15
22
  if (this.mcpServer) {
16
23
  try {
17
- // Include local context in the sampling request
18
24
  const context = readLocalContext();
19
25
  const result = (await this.mcpServer.request({
20
26
  method: 'sampling/createMessage',
@@ -55,7 +61,50 @@ export class AutoResponder {
55
61
  console.error('[AskMesh] MCP sampling not available');
56
62
  }
57
63
  }
58
- // Strategy 2: Manualquestion stays pending
64
+ // Strategy 2: Anthropic API fallback (optional for standalone/server mode)
65
+ const apiKey = process.env.ANTHROPIC_API_KEY;
66
+ if (apiKey) {
67
+ try {
68
+ const context = readLocalContext();
69
+ const answer = await this.callAnthropicAPI(apiKey, request, context);
70
+ if (answer) {
71
+ await this.client.answerRequest(request.id, answer);
72
+ console.error(`[AskMesh] Responded to #${request.id} via Anthropic API`);
73
+ return;
74
+ }
75
+ }
76
+ catch (err) {
77
+ console.error('[AskMesh] Anthropic API failed:', err);
78
+ }
79
+ }
80
+ // Strategy 3: Manual — question stays pending
59
81
  console.error(`[AskMesh] Question #${request.id} queued — use askmesh(action:"pending") to respond`);
60
82
  }
83
+ async callAnthropicAPI(apiKey, request, context) {
84
+ const model = process.env.ANTHROPIC_MODEL || 'claude-sonnet-4-20250514';
85
+ const response = await fetch('https://api.anthropic.com/v1/messages', {
86
+ method: 'POST',
87
+ headers: {
88
+ 'x-api-key': apiKey,
89
+ 'anthropic-version': '2023-06-01',
90
+ 'content-type': 'application/json',
91
+ },
92
+ body: JSON.stringify({
93
+ model,
94
+ max_tokens: 2048,
95
+ system: SYSTEM_PROMPT,
96
+ messages: [
97
+ {
98
+ role: 'user',
99
+ content: `Project context:\n\n${context}\n\n---\n\nQuestion from @${request.fromUsername}:\n${request.question}${request.context ? `\n\nAdditional context: ${request.context}` : ''}`,
100
+ },
101
+ ],
102
+ }),
103
+ });
104
+ if (!response.ok) {
105
+ throw new Error(`Anthropic API ${response.status}: ${await response.text()}`);
106
+ }
107
+ const data = (await response.json());
108
+ return data.content?.[0]?.text || null;
109
+ }
61
110
  }
package/dist/index.js CHANGED
@@ -28,6 +28,28 @@ sse.start(URL, TOKEN, async (request) => {
28
28
  }, (answer) => {
29
29
  console.error(`[AskMesh] Answer received for request #${answer.id}: "${answer.answer.slice(0, 100)}${answer.answer.length > 100 ? '...' : ''}"`);
30
30
  });
31
+ // Polling fallback — fetch pending requests periodically
32
+ // Useful for server agents that may miss SSE events
33
+ const POLL_INTERVAL = Number(process.env.ASKMESH_POLL_INTERVAL || 0); // seconds, 0 = disabled
34
+ if (POLL_INTERVAL > 0) {
35
+ console.error(`[AskMesh] Polling enabled every ${POLL_INTERVAL}s`);
36
+ setInterval(async () => {
37
+ try {
38
+ const { requests } = await client.getPendingRequests();
39
+ for (const req of requests) {
40
+ console.error(`[AskMesh] Polled pending #${req.id}: "${req.question}"`);
41
+ await autoResponder.handleRequest({
42
+ id: req.id,
43
+ fromAgentId: req.fromAgentId,
44
+ fromUsername: `agent#${req.fromAgentId}`,
45
+ question: req.question,
46
+ context: req.context,
47
+ });
48
+ }
49
+ }
50
+ catch { }
51
+ }, POLL_INTERVAL * 1000);
52
+ }
31
53
  // Cleanup on exit
32
54
  process.on('SIGINT', () => {
33
55
  sse.stop();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@askmesh/mcp",
3
- "version": "0.4.1",
3
+ "version": "0.5.0",
4
4
  "description": "AskMesh MCP server — connect your AI coding agent to your team's mesh network",
5
5
  "type": "module",
6
6
  "bin": {