fly-agent-mcp 1.2.2 → 1.2.3
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 +1 -2
- package/index.js +103 -87
- package/package.json +5 -8
- package/LICENSE +0 -21
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@ npm install -g fly-agent-mcp
|
|
|
14
14
|
|
|
15
15
|
### 1. Get your API Key
|
|
16
16
|
|
|
17
|
-
1. Log in to [fly-social.com](https://fly-social.com
|
|
17
|
+
1. Log in to [fly-social.com](https://app.fly-social.com)
|
|
18
18
|
2. Go to Settings → Integrations → API Keys
|
|
19
19
|
3. Generate a new API key (starts with `fly_sk_...`)
|
|
20
20
|
|
|
@@ -165,7 +165,6 @@ Fly Agent supports businesses with multiple locations:
|
|
|
165
165
|
|
|
166
166
|
## Support
|
|
167
167
|
|
|
168
|
-
- Report issues: [GitHub Issues](https://github.com/ZoomLocal-Tech/fly-agent-proxy/issues)
|
|
169
168
|
- Email: support@fly-social.com
|
|
170
169
|
|
|
171
170
|
## License
|
package/index.js
CHANGED
|
@@ -8,112 +8,128 @@
|
|
|
8
8
|
* FLY_API_KEY=fly_sk_xxx node index.js
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
ListPromptsRequestSchema,
|
|
21
|
-
GetPromptRequestSchema,
|
|
22
|
-
} from "@modelcontextprotocol/sdk/types.js";
|
|
23
|
-
|
|
24
|
-
const API_KEY = process.env.FLY_API_KEY;
|
|
25
|
-
const FLY_ENV = process.env.FLY_ENV || "main";
|
|
26
|
-
|
|
27
|
-
// Map FLY_ENV to Cloud Run URLs (internal use only)
|
|
28
|
-
const ENV_URLS = {
|
|
29
|
-
dev: "https://fly-agent-dev-681315111540.asia-south1.run.app/mcp/sse",
|
|
30
|
-
staging: "https://fly-agent-staging-681315111540.asia-south1.run.app/mcp/sse",
|
|
31
|
-
main: "https://fly-agent-main-681315111540.asia-south1.run.app/mcp/sse",
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
const MCP_URL = process.env.FLY_MCP_URL || ENV_URLS[FLY_ENV] || ENV_URLS.main;
|
|
35
|
-
|
|
36
|
-
if (!API_KEY) {
|
|
37
|
-
console.error("Error: FLY_API_KEY environment variable required");
|
|
38
|
-
process.exit(1);
|
|
11
|
+
// Polyfill fetch for Node < 18
|
|
12
|
+
async function ensureFetch() {
|
|
13
|
+
if (!globalThis.fetch) {
|
|
14
|
+
const nodeFetch = await import("node-fetch");
|
|
15
|
+
globalThis.fetch = nodeFetch.default;
|
|
16
|
+
globalThis.Headers = nodeFetch.Headers;
|
|
17
|
+
globalThis.Request = nodeFetch.Request;
|
|
18
|
+
globalThis.Response = nodeFetch.Response;
|
|
19
|
+
}
|
|
39
20
|
}
|
|
40
21
|
|
|
41
|
-
//
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
22
|
+
// Main entry point
|
|
23
|
+
async function bootstrap() {
|
|
24
|
+
// Ensure fetch is available before importing MCP SDK
|
|
25
|
+
await ensureFetch();
|
|
26
|
+
|
|
27
|
+
// Dynamic imports after fetch polyfill
|
|
28
|
+
const { Client } = await import("@modelcontextprotocol/sdk/client/index.js");
|
|
29
|
+
const { SSEClientTransport } = await import("@modelcontextprotocol/sdk/client/sse.js");
|
|
30
|
+
const { Server } = await import("@modelcontextprotocol/sdk/server/index.js");
|
|
31
|
+
const { StdioServerTransport } = await import("@modelcontextprotocol/sdk/server/stdio.js");
|
|
32
|
+
const {
|
|
33
|
+
ListToolsRequestSchema,
|
|
34
|
+
CallToolRequestSchema,
|
|
35
|
+
ListResourcesRequestSchema,
|
|
36
|
+
ReadResourceRequestSchema,
|
|
37
|
+
ListPromptsRequestSchema,
|
|
38
|
+
GetPromptRequestSchema,
|
|
39
|
+
} = await import("@modelcontextprotocol/sdk/types.js");
|
|
40
|
+
|
|
41
|
+
const API_KEY = process.env.FLY_API_KEY;
|
|
42
|
+
const FLY_ENV = process.env.FLY_ENV || "main";
|
|
43
|
+
|
|
44
|
+
// Map FLY_ENV to Cloud Run URLs (internal use only)
|
|
45
|
+
const ENV_URLS = {
|
|
46
|
+
dev: "https://fly-agent-dev-681315111540.asia-south1.run.app/mcp/sse",
|
|
47
|
+
staging: "https://fly-agent-staging-681315111540.asia-south1.run.app/mcp/sse",
|
|
48
|
+
main: "https://fly-agent-main-681315111540.asia-south1.run.app/mcp/sse",
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const MCP_URL = process.env.FLY_MCP_URL || ENV_URLS[FLY_ENV] || ENV_URLS.main;
|
|
52
|
+
|
|
53
|
+
if (!API_KEY) {
|
|
54
|
+
console.error("Error: FLY_API_KEY environment variable required");
|
|
55
|
+
process.exit(1);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Create local stdio server
|
|
59
|
+
const server = new Server(
|
|
60
|
+
{ name: "fly-agent-proxy", version: "1.0.0" },
|
|
61
|
+
{ capabilities: { tools: {}, resources: {}, prompts: {} } }
|
|
62
|
+
);
|
|
46
63
|
|
|
47
|
-
// Remote client
|
|
48
|
-
let remoteClient = null;
|
|
64
|
+
// Remote client
|
|
65
|
+
let remoteClient = null;
|
|
49
66
|
|
|
50
|
-
async function connectToRemote() {
|
|
51
|
-
|
|
67
|
+
async function connectToRemote() {
|
|
68
|
+
if (remoteClient) return remoteClient;
|
|
52
69
|
|
|
53
|
-
|
|
70
|
+
console.error("Connecting to remote MCP server...");
|
|
54
71
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
72
|
+
const transport = new SSEClientTransport(new URL(MCP_URL), {
|
|
73
|
+
requestInit: {
|
|
74
|
+
headers: {
|
|
75
|
+
"X-API-Key": API_KEY,
|
|
76
|
+
},
|
|
59
77
|
},
|
|
60
|
-
}
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
remoteClient = new Client(
|
|
81
|
+
{ name: "fly-agent-proxy-client", version: "1.0.0" },
|
|
82
|
+
{ capabilities: {} }
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
await remoteClient.connect(transport);
|
|
86
|
+
console.error("Connected to remote MCP server:", MCP_URL);
|
|
87
|
+
return remoteClient;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Proxy tool listing
|
|
91
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
92
|
+
const client = await connectToRemote();
|
|
93
|
+
return await client.listTools();
|
|
61
94
|
});
|
|
62
95
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
await remoteClient.connect(transport);
|
|
69
|
-
console.error("Connected to remote MCP server:", MCP_URL);
|
|
70
|
-
return remoteClient;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// Proxy tool listing
|
|
74
|
-
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
75
|
-
const client = await connectToRemote();
|
|
76
|
-
return await client.listTools();
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
// Proxy tool calls
|
|
80
|
-
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
81
|
-
const client = await connectToRemote();
|
|
82
|
-
return await client.callTool(request.params);
|
|
83
|
-
});
|
|
96
|
+
// Proxy tool calls
|
|
97
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
98
|
+
const client = await connectToRemote();
|
|
99
|
+
return await client.callTool(request.params);
|
|
100
|
+
});
|
|
84
101
|
|
|
85
|
-
// Proxy resource listing
|
|
86
|
-
server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
});
|
|
102
|
+
// Proxy resource listing
|
|
103
|
+
server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
104
|
+
const client = await connectToRemote();
|
|
105
|
+
return await client.listResources();
|
|
106
|
+
});
|
|
90
107
|
|
|
91
|
-
// Proxy resource reading
|
|
92
|
-
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
});
|
|
108
|
+
// Proxy resource reading
|
|
109
|
+
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
110
|
+
const client = await connectToRemote();
|
|
111
|
+
return await client.readResource(request.params);
|
|
112
|
+
});
|
|
96
113
|
|
|
97
|
-
// Proxy prompt listing
|
|
98
|
-
server.setRequestHandler(ListPromptsRequestSchema, async () => {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
});
|
|
114
|
+
// Proxy prompt listing
|
|
115
|
+
server.setRequestHandler(ListPromptsRequestSchema, async () => {
|
|
116
|
+
const client = await connectToRemote();
|
|
117
|
+
return await client.listPrompts();
|
|
118
|
+
});
|
|
102
119
|
|
|
103
|
-
// Proxy prompt getting
|
|
104
|
-
server.setRequestHandler(GetPromptRequestSchema, async (request) => {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
});
|
|
120
|
+
// Proxy prompt getting
|
|
121
|
+
server.setRequestHandler(GetPromptRequestSchema, async (request) => {
|
|
122
|
+
const client = await connectToRemote();
|
|
123
|
+
return await client.getPrompt(request.params);
|
|
124
|
+
});
|
|
108
125
|
|
|
109
|
-
// Start the local stdio server
|
|
110
|
-
async function main() {
|
|
126
|
+
// Start the local stdio server
|
|
111
127
|
const transport = new StdioServerTransport();
|
|
112
128
|
await server.connect(transport);
|
|
113
129
|
console.error(`MCP proxy started - env: ${FLY_ENV}, bridging to`, MCP_URL);
|
|
114
130
|
}
|
|
115
131
|
|
|
116
|
-
|
|
132
|
+
bootstrap().catch((error) => {
|
|
117
133
|
console.error("Fatal error:", error);
|
|
118
134
|
process.exit(1);
|
|
119
135
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fly-agent-mcp",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.3",
|
|
4
4
|
"description": "MCP proxy for Fly Agent - AI-powered Google Business Profile management for Local SEO",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -32,16 +32,13 @@
|
|
|
32
32
|
"license": "MIT",
|
|
33
33
|
"repository": {
|
|
34
34
|
"type": "git",
|
|
35
|
-
"url": "https://github.com/ZoomLocal-Tech/fly-agent
|
|
35
|
+
"url": "https://github.com/ZoomLocal-Tech/fly-agent"
|
|
36
36
|
},
|
|
37
|
-
"bugs": {
|
|
38
|
-
"url": "https://github.com/ZoomLocal-Tech/fly-agent-proxy/issues"
|
|
39
|
-
},
|
|
40
|
-
"homepage": "https://github.com/ZoomLocal-Tech/fly-agent-proxy#readme",
|
|
41
37
|
"engines": {
|
|
42
|
-
"node": ">=
|
|
38
|
+
"node": ">=16.0.0"
|
|
43
39
|
},
|
|
44
40
|
"dependencies": {
|
|
45
|
-
"@modelcontextprotocol/sdk": "^1.0.0"
|
|
41
|
+
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
42
|
+
"node-fetch": "^3.3.2"
|
|
46
43
|
}
|
|
47
44
|
}
|
package/LICENSE
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026 Fly Social
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|