@backstage-community/plugin-mcp-chat 0.0.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 +361 -0
- package/config.d.ts +47 -0
- package/dist/api/McpChatApi.esm.js +55 -0
- package/dist/api/McpChatApi.esm.js.map +1 -0
- package/dist/api/index.esm.js +8 -0
- package/dist/api/index.esm.js.map +1 -0
- package/dist/components/BotIcon/BotIcon.esm.js +57 -0
- package/dist/components/BotIcon/BotIcon.esm.js.map +1 -0
- package/dist/components/ChatContainer/ChatContainer.esm.js +246 -0
- package/dist/components/ChatContainer/ChatContainer.esm.js.map +1 -0
- package/dist/components/ChatContainer/ChatMessage.esm.js +466 -0
- package/dist/components/ChatContainer/ChatMessage.esm.js.map +1 -0
- package/dist/components/ChatContainer/QuickStart.esm.js +271 -0
- package/dist/components/ChatContainer/QuickStart.esm.js.map +1 -0
- package/dist/components/ChatContainer/TypingIndicator.esm.js +154 -0
- package/dist/components/ChatContainer/TypingIndicator.esm.js.map +1 -0
- package/dist/components/ChatPage/ChatPage.esm.js +142 -0
- package/dist/components/ChatPage/ChatPage.esm.js.map +1 -0
- package/dist/components/ChatPage/index.esm.js +2 -0
- package/dist/components/ChatPage/index.esm.js.map +1 -0
- package/dist/components/RightPane/ActiveMcpServers.esm.js +159 -0
- package/dist/components/RightPane/ActiveMcpServers.esm.js.map +1 -0
- package/dist/components/RightPane/ActiveTools.esm.js +308 -0
- package/dist/components/RightPane/ActiveTools.esm.js.map +1 -0
- package/dist/components/RightPane/ProviderStatus.esm.js +225 -0
- package/dist/components/RightPane/ProviderStatus.esm.js.map +1 -0
- package/dist/components/RightPane/RightPane.esm.js +242 -0
- package/dist/components/RightPane/RightPane.esm.js.map +1 -0
- package/dist/hooks/useAvailableTools.esm.js +33 -0
- package/dist/hooks/useAvailableTools.esm.js.map +1 -0
- package/dist/hooks/useMcpServers.esm.js +40 -0
- package/dist/hooks/useMcpServers.esm.js.map +1 -0
- package/dist/hooks/useProviderStatus.esm.js +22 -0
- package/dist/hooks/useProviderStatus.esm.js.map +1 -0
- package/dist/index.d.ts +150 -0
- package/dist/index.esm.js +3 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/plugin.esm.js +33 -0
- package/dist/plugin.esm.js.map +1 -0
- package/dist/routes.esm.js +8 -0
- package/dist/routes.esm.js.map +1 -0
- package/package.json +91 -0
package/README.md
ADDED
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
# MCP Chat for Backstage
|
|
2
|
+
|
|
3
|
+
Welcome to the MCP (Model Context Protocol) Chat plugin for Backstage! This plugin enables you to integrate AI-powered chat capabilities into your Backstage platform, supporting multiple AI providers and MCP servers.
|
|
4
|
+
|
|
5
|
+
[](https://backstage.io)
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
The MCP Chat plugin brings conversational AI capabilities directly into your Backstage environment. It leverages the Model Context Protocol to connect with various AI providers and external tools, enabling developers to interact with their infrastructure, catalogs, and external services through natural language.
|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
- 🤖 **Multi-Provider AI Support**: Works with OpenAI, Claude, Gemini, and Ollama
|
|
14
|
+
- 🔧 **Multi-Server Support**: Connect multiple MCP servers (STDIO, SSE, Streamable HTTP)
|
|
15
|
+
- 🛠️ **Tool Management**: Browse and dynamically enable/disable tools from connected MCP servers
|
|
16
|
+
- 💬 **Rich Chat Interface**: Beautiful, responsive chat UI with markdown support
|
|
17
|
+
- ⚡ **Quick Setup**: Configurable QuickStart prompts for common use cases
|
|
18
|
+
|
|
19
|
+
## Supported AI Providers
|
|
20
|
+
|
|
21
|
+
The following AI providers and models have been thoroughly tested:
|
|
22
|
+
|
|
23
|
+
| Provider | Model | Status | Notes |
|
|
24
|
+
| ---------- | ------------------ | --------------- | ------------------------------------------------------------- |
|
|
25
|
+
| **OpenAI** | `gpt-4o-mini` | ✅ Fully Tested | Recommended for production use |
|
|
26
|
+
| **Gemini** | `gemini-2.5-flash` | ✅ Fully Tested | Excellent performance with tool calling |
|
|
27
|
+
| **Ollama** | `llama3.1:8b` | ✅ Tested | Works well, but `llama3.1:30b` recommended for better results |
|
|
28
|
+
|
|
29
|
+
> **Note**: While other providers and models may work, they have not been extensively tested. The plugin supports any provider that implements tool calling functionality, but compatibility is not guaranteed for untested configurations.
|
|
30
|
+
|
|
31
|
+
## Quick Start with Gemini (Free)
|
|
32
|
+
|
|
33
|
+
To quickly test this plugin, we recommend using Gemini's free API:
|
|
34
|
+
|
|
35
|
+
1. **Visit Google AI Studio**: Go to <https://aistudio.google.com>
|
|
36
|
+
2. **Sign in**: Use your Google account to sign in
|
|
37
|
+
3. **Create API Key**:
|
|
38
|
+
- Click on "**Get API key**" in the left sidebar
|
|
39
|
+
- Click "**Create API key in new project**" (or select an existing project)
|
|
40
|
+
- **Copy** the generated API key
|
|
41
|
+
4. **Set Environment Variable**:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
export GEMINI_API_KEY="your-api-key-here"
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
> **💡 Tip**: Gemini offers a generous **free tier** that's perfect for testing and development with the MCP Chat.
|
|
48
|
+
|
|
49
|
+
## Screenshots
|
|
50
|
+
|
|
51
|
+
<div align="center">
|
|
52
|
+
|
|
53
|
+
<table>
|
|
54
|
+
<tr>
|
|
55
|
+
<td style="padding: 0 10px;">
|
|
56
|
+
<img src="../../docs/images/quick-prompts.png" alt="Quick Prompts" width="900"/>
|
|
57
|
+
<div align="center"><em>Pre-configured prompts for common tasks</em></div>
|
|
58
|
+
</td>
|
|
59
|
+
<td rowspan="2" style="vertical-align: top; padding: 0 10px;">
|
|
60
|
+
<img src="../../docs/images/mcp-tools-panel.png" alt="MCP Tools Panel" height="600"/>
|
|
61
|
+
<div align="center"><em>Available MCP tools and server connections</em></div>
|
|
62
|
+
</td>
|
|
63
|
+
</tr>
|
|
64
|
+
<tr>
|
|
65
|
+
<td style="padding: 0 10px;">
|
|
66
|
+
<img src="../../docs/images/chat-interface.png" alt="Chat Interface" width="900"/>
|
|
67
|
+
<div align="center"><em>The main chat interface with AI responses and tool integration</em></div>
|
|
68
|
+
</td>
|
|
69
|
+
</tr>
|
|
70
|
+
</table>
|
|
71
|
+
|
|
72
|
+
</div>
|
|
73
|
+
|
|
74
|
+
## Prerequisites
|
|
75
|
+
|
|
76
|
+
- Backstage v1.20+ (for new backend system support)
|
|
77
|
+
- Backstage v1.40+ (if installing Backstage MCP server in the same instance)
|
|
78
|
+
- Node.js 18+
|
|
79
|
+
- One or more AI provider API keys (OpenAI, Gemini, etc.)
|
|
80
|
+
- (Optional) MCP server dependencies
|
|
81
|
+
|
|
82
|
+
## Installation
|
|
83
|
+
|
|
84
|
+
This plugin consists of two packages:
|
|
85
|
+
|
|
86
|
+
- `@backstage-community/plugin-mcp-chat` - Frontend plugin
|
|
87
|
+
- `@backstage-community/plugin-mcp-chat-backend` - Backend plugin
|
|
88
|
+
|
|
89
|
+
### Backend Installation
|
|
90
|
+
|
|
91
|
+
1. **Install the backend plugin**:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
# From your Backstage root directory
|
|
95
|
+
yarn --cwd packages/backend add @backstage-community/plugin-mcp-chat-backend
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
2. **Add to your backend**:
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
// In packages/backend/src/index.ts
|
|
102
|
+
const backend = createBackend();
|
|
103
|
+
// ... other plugins
|
|
104
|
+
backend.add(import('@backstage-community/plugin-mcp-chat-backend'));
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Frontend Installation
|
|
108
|
+
|
|
109
|
+
1. **Install the frontend plugin**:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
# From your Backstage root directory
|
|
113
|
+
yarn --cwd packages/app add @backstage-community/plugin-mcp-chat
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
2. **Add to your app**:
|
|
117
|
+
|
|
118
|
+
**For the classic frontend system:**
|
|
119
|
+
|
|
120
|
+
```tsx
|
|
121
|
+
// In packages/app/src/App.tsx
|
|
122
|
+
import { McpChatPage } from '@backstage-community/plugin-mcp-chat';
|
|
123
|
+
|
|
124
|
+
// Add to your routes
|
|
125
|
+
<Route path="/mcp-chat" element={<McpChatPage />} />;
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
3. **Add navigation**:
|
|
129
|
+
|
|
130
|
+
```tsx
|
|
131
|
+
// In packages/app/src/components/Root/Root.tsx
|
|
132
|
+
import { MCPChatIcon } from '@backstage-community/plugin-mcp-chat';
|
|
133
|
+
|
|
134
|
+
// In your sidebar items
|
|
135
|
+
<SidebarItem icon={MCPChatIcon} to="mcp-chat" text="MCP Chat" />;
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Configuration
|
|
139
|
+
|
|
140
|
+
Add the following configuration to your `app-config.yaml`:
|
|
141
|
+
|
|
142
|
+
```yaml
|
|
143
|
+
mcpChat:
|
|
144
|
+
# Configure AI providers (currently only the first provider is used)
|
|
145
|
+
# Supported Providers: OpenAI, Gemini, Claude, and Ollama
|
|
146
|
+
providers:
|
|
147
|
+
- id: openai # OpenAI provider
|
|
148
|
+
token: ${OPENAI_API_KEY}
|
|
149
|
+
model: gpt-4o-mini # or gpt-4, gpt-3.5-turbo, etc.
|
|
150
|
+
- id: claude # Claude provider
|
|
151
|
+
token: ${CLAUDE_API_KEY}
|
|
152
|
+
model: claude-sonnet-4-20250514 # or claude-3-7-sonnet-latest
|
|
153
|
+
- id: gemini # Gemini provider
|
|
154
|
+
token: ${GEMINI_API_KEY}
|
|
155
|
+
model: gemini-2.5-flash # or gemini-2.0-pro, etc.
|
|
156
|
+
- id: ollama # Ollama provider
|
|
157
|
+
baseUrl: 'http://localhost:11434'
|
|
158
|
+
model: llama3.1:8b # or any model you have locally
|
|
159
|
+
|
|
160
|
+
# Configure MCP servers
|
|
161
|
+
mcpServers:
|
|
162
|
+
# Brave Search for web searching
|
|
163
|
+
- id: brave-search-server
|
|
164
|
+
name: Brave Search Server
|
|
165
|
+
npxCommand: '@modelcontextprotocol/server-brave-search@latest'
|
|
166
|
+
env:
|
|
167
|
+
BRAVE_API_KEY: ${BRAVE_API_KEY}
|
|
168
|
+
|
|
169
|
+
# Kubernetes server for K8s operations
|
|
170
|
+
- id: kubernetes-server
|
|
171
|
+
name: Kubernetes Server
|
|
172
|
+
npxCommand: 'kubernetes-mcp-server@latest'
|
|
173
|
+
env:
|
|
174
|
+
KUBECONFIG: ${KUBECONFIG}
|
|
175
|
+
|
|
176
|
+
# Backstage server integration
|
|
177
|
+
- id: backstage-server
|
|
178
|
+
name: Backstage Server
|
|
179
|
+
url: 'http://localhost:7007/api/mcp-actions/v1'
|
|
180
|
+
headers:
|
|
181
|
+
Authorization: 'Bearer ${BACKSTAGE_MCP_TOKEN}'
|
|
182
|
+
|
|
183
|
+
# Configure quick prompts
|
|
184
|
+
quickPrompts:
|
|
185
|
+
- title: 'Search Latest Tech News'
|
|
186
|
+
description: 'Find the latest technology news and developments'
|
|
187
|
+
prompt: 'Search for the latest developments in Model Context Protocol and its applications'
|
|
188
|
+
category: Research
|
|
189
|
+
|
|
190
|
+
- title: 'Kubernetes Health Check'
|
|
191
|
+
description: 'Check the health of Kubernetes clusters'
|
|
192
|
+
prompt: 'Show me the current Kubernetes deployments, pods status, and resource utilization in a nicely formatted text with bullet points'
|
|
193
|
+
category: Infrastructure
|
|
194
|
+
|
|
195
|
+
- title: 'Backstage Catalog Query'
|
|
196
|
+
description: 'Query the Backstage software catalog'
|
|
197
|
+
prompt: 'Describe the "example-app" microservice in our Backstage catalog'
|
|
198
|
+
category: Catalog
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
For more advanced MCP server configuration examples (including STDIO, Streamable HTTP, SSE, custom scripts, and arguments), see [SERVER_CONFIGURATION](../../docs/SERVER_CONFIGURATION.md).
|
|
202
|
+
|
|
203
|
+
### Environment Variables
|
|
204
|
+
|
|
205
|
+
Set the following environment variables in your Backstage deployment:
|
|
206
|
+
|
|
207
|
+
```bash
|
|
208
|
+
# AI Provider API Keys
|
|
209
|
+
export OPENAI_API_KEY="sk-..."
|
|
210
|
+
export GEMINI_API_KEY="..."
|
|
211
|
+
|
|
212
|
+
# MCP Server Configuration
|
|
213
|
+
export BRAVE_API_KEY="..."
|
|
214
|
+
export BACKSTAGE_MCP_TOKEN="..."
|
|
215
|
+
export KUBECONFIG="/path/to/your/kubeconfig.yaml"
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## Usage
|
|
219
|
+
|
|
220
|
+
1. **Navigate to the Plugin**: Go to the **MCP Chat** page in your Backstage instance
|
|
221
|
+
|
|
222
|
+
2. **Access Configuration**: Expand the Configuration sidebar on the right to view:
|
|
223
|
+
|
|
224
|
+
- Provider connectivity status
|
|
225
|
+
- Connected MCP servers and their available tools
|
|
226
|
+
- Tool management controls for enabling/disabling specific servers
|
|
227
|
+
|
|
228
|
+
3. **Start Chatting**: Begin a conversation by:
|
|
229
|
+
- Selecting from the provided quick prompts, or
|
|
230
|
+
- Typing your own queries directly into the chat input field
|
|
231
|
+
|
|
232
|
+
### Example Queries
|
|
233
|
+
|
|
234
|
+
| Query | MCP Server Required | Purpose |
|
|
235
|
+
| ------------------------------------------------------------------ | ------------------- | ------------------------------- |
|
|
236
|
+
| "Search for the latest news about Kubernetes security" | Brave Search | Find relevant articles and news |
|
|
237
|
+
| "Show me all pods in the default namespace" | Kubernetes | Query cluster resources |
|
|
238
|
+
| "Describe the "example-app" microservice in our Backstage catalog" | Backstage | Access catalog entity |
|
|
239
|
+
|
|
240
|
+
## Development
|
|
241
|
+
|
|
242
|
+
### Local Development Setup
|
|
243
|
+
|
|
244
|
+
1. **Clone the repository**:
|
|
245
|
+
|
|
246
|
+
```bash
|
|
247
|
+
git clone https://github.com/backstage/community-plugins.git
|
|
248
|
+
cd workspaces/mcp-chat
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
2. **Install dependencies**:
|
|
252
|
+
|
|
253
|
+
```bash
|
|
254
|
+
yarn install
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
3. **Start the development server**:
|
|
258
|
+
|
|
259
|
+
```bash
|
|
260
|
+
yarn start
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
4. **Access the plugin**: Navigate to <http://localhost:3000/mcp-chat>
|
|
264
|
+
|
|
265
|
+
### Testing
|
|
266
|
+
|
|
267
|
+
Run the test suite:
|
|
268
|
+
|
|
269
|
+
```bash
|
|
270
|
+
# Run all tests
|
|
271
|
+
yarn test:all
|
|
272
|
+
|
|
273
|
+
# Run tests in watch mode
|
|
274
|
+
yarn test --watch
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### Building
|
|
278
|
+
|
|
279
|
+
Build all packages:
|
|
280
|
+
|
|
281
|
+
```bash
|
|
282
|
+
yarn build:all
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
## Troubleshooting
|
|
286
|
+
|
|
287
|
+
### Common Issues
|
|
288
|
+
|
|
289
|
+
#### AI Provider Shows as Disconnected
|
|
290
|
+
|
|
291
|
+
- **Cause**: Missing or invalid API keys
|
|
292
|
+
- **Solution**:
|
|
293
|
+
- Verify API keys are set as environment variables
|
|
294
|
+
- Check provider configuration in `app-config.yaml`
|
|
295
|
+
- Ensure the specified model is available for your API key
|
|
296
|
+
|
|
297
|
+
#### Tools Are Not Being Called
|
|
298
|
+
|
|
299
|
+
- **Cause**: AI provider doesn't support tool calling or model limitations
|
|
300
|
+
- **Solution**:
|
|
301
|
+
- Ensure your AI provider supports tool calling
|
|
302
|
+
- For Ollama, use larger models like `llama3.1:30b` for better results
|
|
303
|
+
- Verify MCP server API keys are correctly configured
|
|
304
|
+
- Check backend logs for connection errors
|
|
305
|
+
|
|
306
|
+
#### MCP Servers Not Connecting
|
|
307
|
+
|
|
308
|
+
- **Cause**: Missing dependencies or configuration issues
|
|
309
|
+
- **Solution**:
|
|
310
|
+
- Verify all required environment variables are set
|
|
311
|
+
- Check MCP server logs for connection errors
|
|
312
|
+
- Ensure MCP server dependencies are installed
|
|
313
|
+
|
|
314
|
+
### Debug Endpoints
|
|
315
|
+
|
|
316
|
+
Use these endpoints for debugging:
|
|
317
|
+
|
|
318
|
+
- **Provider Status**: `/api/mcp-chat/provider/status`
|
|
319
|
+
- **MCP Server Status**: `/api/mcp-chat/mcp/status`
|
|
320
|
+
- **Available Tools**: `/api/mcp-chat/tools`
|
|
321
|
+
|
|
322
|
+
## API Reference
|
|
323
|
+
|
|
324
|
+
### Backend Endpoints
|
|
325
|
+
|
|
326
|
+
| Endpoint | Method | Description |
|
|
327
|
+
| ------------------------------- | ------ | ------------------------------------- |
|
|
328
|
+
| `/api/mcp-chat/chat` | POST | Send chat messages |
|
|
329
|
+
| `/api/mcp-chat/provider/status` | GET | Get status of connected AI provider |
|
|
330
|
+
| `/api/mcp-chat/mcp/status` | GET | Get status of connected MCP servers |
|
|
331
|
+
| `/api/mcp-chat/tools` | GET | List available MCP tools from servers |
|
|
332
|
+
|
|
333
|
+
## Contributing
|
|
334
|
+
|
|
335
|
+
Please see our [Contributing Guidelines](../../CONTRIBUTING.md) for detailed information.
|
|
336
|
+
|
|
337
|
+
### Development Guidelines
|
|
338
|
+
|
|
339
|
+
- Follow the existing code style and patterns
|
|
340
|
+
- Add tests for new functionality
|
|
341
|
+
- Update documentation as needed
|
|
342
|
+
- Ensure all tests pass before submitting
|
|
343
|
+
|
|
344
|
+
## Support and Community
|
|
345
|
+
|
|
346
|
+
- **Issues**: [Create an issue](https://github.com/backstage/community-plugins/issues)
|
|
347
|
+
- **Discord**: [Join our Discord](https://discord.gg/backstage)
|
|
348
|
+
- **Documentation**: [Backstage Documentation](https://backstage.io/docs)
|
|
349
|
+
- **Community**: [Backstage Community](https://backstage.io/community)
|
|
350
|
+
|
|
351
|
+
## Changelog
|
|
352
|
+
|
|
353
|
+
See [CHANGELOG.md](./CHANGELOG.md) for details about changes in each version.
|
|
354
|
+
|
|
355
|
+
## License
|
|
356
|
+
|
|
357
|
+
This plugin is licensed under the Apache 2.0 License. See [LICENSE](../../LICENSE) for details.
|
|
358
|
+
|
|
359
|
+
---
|
|
360
|
+
|
|
361
|
+
**Made with ❤️ for the Backstage Community**
|
package/config.d.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 The Backstage Authors
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
export interface Config {
|
|
18
|
+
/** Configuration options for the MCP Chat plugin */
|
|
19
|
+
mcpChat?: {
|
|
20
|
+
/**
|
|
21
|
+
* Quick prompts configuration for the frontend
|
|
22
|
+
* @visibility frontend
|
|
23
|
+
*/
|
|
24
|
+
quickPrompts?: Array<{
|
|
25
|
+
/**
|
|
26
|
+
* Title of the quick prompt
|
|
27
|
+
* @visibility frontend
|
|
28
|
+
*/
|
|
29
|
+
title: string;
|
|
30
|
+
/**
|
|
31
|
+
* Description of what the prompt does
|
|
32
|
+
* @visibility frontend
|
|
33
|
+
*/
|
|
34
|
+
description: string;
|
|
35
|
+
/**
|
|
36
|
+
* The actual prompt text to be used
|
|
37
|
+
* @visibility frontend
|
|
38
|
+
*/
|
|
39
|
+
prompt: string;
|
|
40
|
+
/**
|
|
41
|
+
* Category to group related prompts
|
|
42
|
+
* @visibility frontend
|
|
43
|
+
*/
|
|
44
|
+
category: string;
|
|
45
|
+
}>;
|
|
46
|
+
};
|
|
47
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { ResponseError } from '@backstage/errors';
|
|
2
|
+
|
|
3
|
+
class McpChat {
|
|
4
|
+
discoveryApi;
|
|
5
|
+
fetchApi;
|
|
6
|
+
constructor(options) {
|
|
7
|
+
this.discoveryApi = options.discoveryApi;
|
|
8
|
+
this.fetchApi = options.fetchApi;
|
|
9
|
+
}
|
|
10
|
+
async sendChatMessage(messages, enabledTools = [], signal) {
|
|
11
|
+
const baseUrl = await this.discoveryApi.getBaseUrl("mcp-chat");
|
|
12
|
+
const response = await this.fetchApi.fetch(`${baseUrl}/chat`, {
|
|
13
|
+
method: "POST",
|
|
14
|
+
headers: {
|
|
15
|
+
"Content-Type": "application/json"
|
|
16
|
+
},
|
|
17
|
+
body: JSON.stringify({
|
|
18
|
+
messages,
|
|
19
|
+
enabledTools
|
|
20
|
+
}),
|
|
21
|
+
signal
|
|
22
|
+
});
|
|
23
|
+
if (!response.ok) {
|
|
24
|
+
throw await ResponseError.fromResponse(response);
|
|
25
|
+
}
|
|
26
|
+
return response.json();
|
|
27
|
+
}
|
|
28
|
+
async getMCPServerStatus() {
|
|
29
|
+
const baseUrl = await this.discoveryApi.getBaseUrl("mcp-chat");
|
|
30
|
+
const response = await this.fetchApi.fetch(`${baseUrl}/mcp/status`);
|
|
31
|
+
if (!response.ok) {
|
|
32
|
+
throw await ResponseError.fromResponse(response);
|
|
33
|
+
}
|
|
34
|
+
return response.json();
|
|
35
|
+
}
|
|
36
|
+
async getAvailableTools() {
|
|
37
|
+
const baseUrl = await this.discoveryApi.getBaseUrl("mcp-chat");
|
|
38
|
+
const response = await this.fetchApi.fetch(`${baseUrl}/tools`);
|
|
39
|
+
if (!response.ok) {
|
|
40
|
+
throw await ResponseError.fromResponse(response);
|
|
41
|
+
}
|
|
42
|
+
return response.json();
|
|
43
|
+
}
|
|
44
|
+
async getProviderStatus() {
|
|
45
|
+
const baseUrl = await this.discoveryApi.getBaseUrl("mcp-chat");
|
|
46
|
+
const response = await this.fetchApi.fetch(`${baseUrl}/provider/status`);
|
|
47
|
+
if (!response.ok) {
|
|
48
|
+
throw await ResponseError.fromResponse(response);
|
|
49
|
+
}
|
|
50
|
+
return response.json();
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export { McpChat };
|
|
55
|
+
//# sourceMappingURL=McpChatApi.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"McpChatApi.esm.js","sources":["../../src/api/McpChatApi.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { DiscoveryApi, FetchApi } from '@backstage/core-plugin-api';\nimport { ResponseError } from '@backstage/errors';\nimport {\n ChatMessage,\n ChatResponse,\n MCPServerStatusData,\n ProviderStatusData,\n ToolsResponse,\n} from '../types';\n\n/**\n * @public\n */\nexport interface McpChatApi {\n sendChatMessage(\n messages: ChatMessage[],\n enabledTools?: string[],\n signal?: AbortSignal,\n ): Promise<ChatResponse>;\n getMCPServerStatus(): Promise<MCPServerStatusData>;\n getAvailableTools(): Promise<ToolsResponse>;\n getProviderStatus(): Promise<ProviderStatusData>;\n}\n\nexport class McpChat implements McpChatApi {\n private readonly discoveryApi: DiscoveryApi;\n private readonly fetchApi: FetchApi;\n\n constructor(options: { discoveryApi: DiscoveryApi; fetchApi: FetchApi }) {\n this.discoveryApi = options.discoveryApi;\n this.fetchApi = options.fetchApi;\n }\n\n async sendChatMessage(\n messages: ChatMessage[],\n enabledTools: string[] = [],\n signal?: AbortSignal,\n ): Promise<ChatResponse> {\n const baseUrl = await this.discoveryApi.getBaseUrl('mcp-chat');\n\n const response = await this.fetchApi.fetch(`${baseUrl}/chat`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n messages,\n enabledTools,\n }),\n signal,\n });\n\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n return response.json();\n }\n\n async getMCPServerStatus(): Promise<MCPServerStatusData> {\n const baseUrl = await this.discoveryApi.getBaseUrl('mcp-chat');\n const response = await this.fetchApi.fetch(`${baseUrl}/mcp/status`);\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n return response.json();\n }\n\n async getAvailableTools(): Promise<ToolsResponse> {\n const baseUrl = await this.discoveryApi.getBaseUrl('mcp-chat');\n\n const response = await this.fetchApi.fetch(`${baseUrl}/tools`);\n\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n return response.json();\n }\n\n async getProviderStatus(): Promise<ProviderStatusData> {\n const baseUrl = await this.discoveryApi.getBaseUrl('mcp-chat');\n\n const response = await this.fetchApi.fetch(`${baseUrl}/provider/status`);\n\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n return response.json();\n }\n}\n"],"names":[],"mappings":";;AAwCO,MAAM,OAAA,CAA8B;AAAA,EACxB,YAAA;AAAA,EACA,QAAA;AAAA,EAEjB,YAAY,OAAA,EAA6D;AACvE,IAAA,IAAA,CAAK,eAAe,OAAA,CAAQ,YAAA;AAC5B,IAAA,IAAA,CAAK,WAAW,OAAA,CAAQ,QAAA;AAAA;AAC1B,EAEA,MAAM,eAAA,CACJ,QAAA,EACA,YAAA,GAAyB,IACzB,MAAA,EACuB;AACvB,IAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,YAAA,CAAa,WAAW,UAAU,CAAA;AAE7D,IAAA,MAAM,WAAW,MAAM,IAAA,CAAK,SAAS,KAAA,CAAM,CAAA,EAAG,OAAO,CAAA,KAAA,CAAA,EAAS;AAAA,MAC5D,MAAA,EAAQ,MAAA;AAAA,MACR,OAAA,EAAS;AAAA,QACP,cAAA,EAAgB;AAAA,OAClB;AAAA,MACA,IAAA,EAAM,KAAK,SAAA,CAAU;AAAA,QACnB,QAAA;AAAA,QACA;AAAA,OACD,CAAA;AAAA,MACD;AAAA,KACD,CAAA;AAED,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,MAAM,MAAM,aAAA,CAAc,YAAA,CAAa,QAAQ,CAAA;AAAA;AAGjD,IAAA,OAAO,SAAS,IAAA,EAAK;AAAA;AACvB,EAEA,MAAM,kBAAA,GAAmD;AACvD,IAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,YAAA,CAAa,WAAW,UAAU,CAAA;AAC7D,IAAA,MAAM,WAAW,MAAM,IAAA,CAAK,SAAS,KAAA,CAAM,CAAA,EAAG,OAAO,CAAA,WAAA,CAAa,CAAA;AAClE,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,MAAM,MAAM,aAAA,CAAc,YAAA,CAAa,QAAQ,CAAA;AAAA;AAEjD,IAAA,OAAO,SAAS,IAAA,EAAK;AAAA;AACvB,EAEA,MAAM,iBAAA,GAA4C;AAChD,IAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,YAAA,CAAa,WAAW,UAAU,CAAA;AAE7D,IAAA,MAAM,WAAW,MAAM,IAAA,CAAK,SAAS,KAAA,CAAM,CAAA,EAAG,OAAO,CAAA,MAAA,CAAQ,CAAA;AAE7D,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,MAAM,MAAM,aAAA,CAAc,YAAA,CAAa,QAAQ,CAAA;AAAA;AAGjD,IAAA,OAAO,SAAS,IAAA,EAAK;AAAA;AACvB,EAEA,MAAM,iBAAA,GAAiD;AACrD,IAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,YAAA,CAAa,WAAW,UAAU,CAAA;AAE7D,IAAA,MAAM,WAAW,MAAM,IAAA,CAAK,SAAS,KAAA,CAAM,CAAA,EAAG,OAAO,CAAA,gBAAA,CAAkB,CAAA;AAEvE,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,MAAM,MAAM,aAAA,CAAc,YAAA,CAAa,QAAQ,CAAA;AAAA;AAGjD,IAAA,OAAO,SAAS,IAAA,EAAK;AAAA;AAEzB;;;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":["../../src/api/index.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { createApiRef } from '@backstage/core-plugin-api';\nimport { McpChatApi } from './McpChatApi';\n\n/**\n * @public\n */\nexport const mcpChatApiRef = createApiRef<McpChatApi>({\n id: 'plugin.mcp-chat.service',\n});\n"],"names":[],"mappings":";;AAsBO,MAAM,gBAAgB,YAAA,CAAyB;AAAA,EACpD,EAAA,EAAI;AACN,CAAC;;;;"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
const BotIcon = ({
|
|
4
|
+
size = 30,
|
|
5
|
+
color = "#333",
|
|
6
|
+
...props
|
|
7
|
+
}) => {
|
|
8
|
+
return /* @__PURE__ */ jsxs(
|
|
9
|
+
"svg",
|
|
10
|
+
{
|
|
11
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
12
|
+
viewBox: "0 0 100 100",
|
|
13
|
+
width: size,
|
|
14
|
+
height: size,
|
|
15
|
+
fill: color,
|
|
16
|
+
...props,
|
|
17
|
+
children: [
|
|
18
|
+
/* @__PURE__ */ jsx(
|
|
19
|
+
"path",
|
|
20
|
+
{
|
|
21
|
+
d: "M71,21.2V5H58v14H41V5H29v15C14.1,22,3,34,3,49v0.7C3,66.1,16.4,79,33.5,79H52V64H33.1C24.5,64,18,57.7,18,49.3v-0.7\n C18,40.3,24.5,34,33.1,34l26.3,0c11.2,0,21.1,8.1,22.7,19.2C84.1,67,73.5,79,60.2,79H52v15h8.7c19.4,0,36-14.5,37.8-33.8\n C100.1,41.8,87.9,25.9,71,21.2z"
|
|
22
|
+
}
|
|
23
|
+
),
|
|
24
|
+
/* @__PURE__ */ jsx("rect", { x: "31", y: "43", width: "12", height: "12" }),
|
|
25
|
+
/* @__PURE__ */ jsx("rect", { x: "55", y: "43", width: "12", height: "12" })
|
|
26
|
+
]
|
|
27
|
+
}
|
|
28
|
+
);
|
|
29
|
+
};
|
|
30
|
+
const BotIconComponent = ({
|
|
31
|
+
fontSize = "medium",
|
|
32
|
+
color = "inherit",
|
|
33
|
+
titleAccess,
|
|
34
|
+
htmlColor,
|
|
35
|
+
inheritViewBox,
|
|
36
|
+
shapeRendering,
|
|
37
|
+
...props
|
|
38
|
+
}) => {
|
|
39
|
+
const sizeMap = {
|
|
40
|
+
small: 20,
|
|
41
|
+
medium: 24,
|
|
42
|
+
large: 35,
|
|
43
|
+
inherit: 24
|
|
44
|
+
};
|
|
45
|
+
const size = typeof fontSize === "string" ? sizeMap[fontSize] || 24 : 24;
|
|
46
|
+
return /* @__PURE__ */ jsx(
|
|
47
|
+
BotIcon,
|
|
48
|
+
{
|
|
49
|
+
size,
|
|
50
|
+
color: color === "inherit" ? "#B5B5B5" : color,
|
|
51
|
+
...props
|
|
52
|
+
}
|
|
53
|
+
);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export { BotIcon, BotIconComponent };
|
|
57
|
+
//# sourceMappingURL=BotIcon.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BotIcon.esm.js","sources":["../../../src/components/BotIcon/BotIcon.tsx"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n * SVG Icon Attribution:\n *\n * Icon: \"Chatbot\" by Tanmay Goswami from The Noun Project\n * License: Creative Commons (CC BY 3.0)\n * URL: https://thenounproject.com/icon/chatbot-4453381/\n */\nimport type { FC, SVGProps } from 'react';\nimport { SvgIconProps } from '@mui/material/SvgIcon';\n\nexport interface BotIconProps extends SVGProps<SVGSVGElement> {\n /** Size of the icon (width and height) */\n size?: number;\n /** Color of the icon */\n color?: string;\n}\n\nexport const BotIcon: FC<BotIconProps> = ({\n size = 30,\n color = '#333',\n ...props\n}) => {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 100 100\"\n width={size}\n height={size}\n fill={color}\n {...props}\n >\n <path\n d=\"M71,21.2V5H58v14H41V5H29v15C14.1,22,3,34,3,49v0.7C3,66.1,16.4,79,33.5,79H52V64H33.1C24.5,64,18,57.7,18,49.3v-0.7\n C18,40.3,24.5,34,33.1,34l26.3,0c11.2,0,21.1,8.1,22.7,19.2C84.1,67,73.5,79,60.2,79H52v15h8.7c19.4,0,36-14.5,37.8-33.8\n C100.1,41.8,87.9,25.9,71,21.2z\"\n />\n <rect x=\"31\" y=\"43\" width=\"12\" height=\"12\" />\n <rect x=\"55\" y=\"43\" width=\"12\" height=\"12\" />\n </svg>\n );\n};\n\n// Backstage IconComponent compatible wrapper\nexport const BotIconComponent: FC<SvgIconProps> = ({\n fontSize = 'medium',\n color = 'inherit',\n titleAccess,\n htmlColor,\n inheritViewBox,\n shapeRendering,\n ...props\n}) => {\n // Map fontSize to size\n const sizeMap = {\n small: 20,\n medium: 24,\n large: 35,\n inherit: 24,\n };\n\n const size = typeof fontSize === 'string' ? sizeMap[fontSize] || 24 : 24;\n\n return (\n <BotIcon\n size={size}\n color={color === 'inherit' ? '#B5B5B5' : (color as string)}\n {...props}\n />\n );\n};\n"],"names":[],"mappings":";;AAiCO,MAAM,UAA4B,CAAC;AAAA,EACxC,IAAA,GAAO,EAAA;AAAA,EACP,KAAA,GAAQ,MAAA;AAAA,EACR,GAAG;AACL,CAAA,KAAM;AACJ,EAAA,uBACE,IAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAM,4BAAA;AAAA,MACN,OAAA,EAAQ,aAAA;AAAA,MACR,KAAA,EAAO,IAAA;AAAA,MACP,MAAA,EAAQ,IAAA;AAAA,MACR,IAAA,EAAM,KAAA;AAAA,MACL,GAAG,KAAA;AAAA,MAEJ,QAAA,EAAA;AAAA,wBAAA,GAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,CAAA,EAAE;AAAA;AAAA,SAGJ;AAAA,wBACA,GAAA,CAAC,UAAK,CAAA,EAAE,IAAA,EAAK,GAAE,IAAA,EAAK,KAAA,EAAM,IAAA,EAAK,MAAA,EAAO,IAAA,EAAK,CAAA;AAAA,wBAC3C,GAAA,CAAC,UAAK,CAAA,EAAE,IAAA,EAAK,GAAE,IAAA,EAAK,KAAA,EAAM,IAAA,EAAK,MAAA,EAAO,IAAA,EAAK;AAAA;AAAA;AAAA,GAC7C;AAEJ;AAGO,MAAM,mBAAqC,CAAC;AAAA,EACjD,QAAA,GAAW,QAAA;AAAA,EACX,KAAA,GAAQ,SAAA;AAAA,EACR,WAAA;AAAA,EACA,SAAA;AAAA,EACA,cAAA;AAAA,EACA,cAAA;AAAA,EACA,GAAG;AACL,CAAA,KAAM;AAEJ,EAAA,MAAM,OAAA,GAAU;AAAA,IACd,KAAA,EAAO,EAAA;AAAA,IACP,MAAA,EAAQ,EAAA;AAAA,IACR,KAAA,EAAO,EAAA;AAAA,IACP,OAAA,EAAS;AAAA,GACX;AAEA,EAAA,MAAM,OAAO,OAAO,QAAA,KAAa,WAAW,OAAA,CAAQ,QAAQ,KAAK,EAAA,GAAK,EAAA;AAEtE,EAAA,uBACE,GAAA;AAAA,IAAC,OAAA;AAAA,IAAA;AAAA,MACC,IAAA;AAAA,MACA,KAAA,EAAO,KAAA,KAAU,SAAA,GAAY,SAAA,GAAa,KAAA;AAAA,MACzC,GAAG;AAAA;AAAA,GACN;AAEJ;;;;"}
|