@prmichaelsen/task-mcp 0.2.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/.env.example +19 -0
- package/AGENT.md +1165 -0
- package/CHANGELOG.md +72 -0
- package/agent/commands/acp.commit.md +511 -0
- package/agent/commands/acp.init.md +376 -0
- package/agent/commands/acp.package-install.md +347 -0
- package/agent/commands/acp.proceed.md +311 -0
- package/agent/commands/acp.report.md +392 -0
- package/agent/commands/acp.status.md +280 -0
- package/agent/commands/acp.sync.md +323 -0
- package/agent/commands/acp.update.md +301 -0
- package/agent/commands/acp.validate.md +385 -0
- package/agent/commands/acp.version-check-for-updates.md +275 -0
- package/agent/commands/acp.version-check.md +190 -0
- package/agent/commands/acp.version-update.md +288 -0
- package/agent/commands/command.template.md +273 -0
- package/agent/commands/git.commit.md +511 -0
- package/agent/commands/git.init.md +513 -0
- package/agent/design/.gitkeep +0 -0
- package/agent/design/acp-task-execution-requirements.md +555 -0
- package/agent/design/api-dto-design.md +394 -0
- package/agent/design/code-extraction-guide.md +827 -0
- package/agent/design/design.template.md +136 -0
- package/agent/design/requirements.template.md +387 -0
- package/agent/design/rest-api-integration.md +489 -0
- package/agent/design/sdk-export-requirements.md +549 -0
- package/agent/milestones/.gitkeep +0 -0
- package/agent/milestones/milestone-1-{title}.template.md +206 -0
- package/agent/milestones/milestone-2-task-infrastructure.md +232 -0
- package/agent/milestones/milestone-4-autonomous-execution.md +235 -0
- package/agent/patterns/.gitkeep +0 -0
- package/agent/patterns/bootstrap.md +1271 -0
- package/agent/patterns/bootstrap.template.md +1237 -0
- package/agent/patterns/pattern.template.md +364 -0
- package/agent/progress.template.yaml +158 -0
- package/agent/progress.yaml +375 -0
- package/agent/scripts/check-for-updates.sh +88 -0
- package/agent/scripts/install.sh +157 -0
- package/agent/scripts/uninstall.sh +75 -0
- package/agent/scripts/update.sh +139 -0
- package/agent/scripts/version.sh +35 -0
- package/agent/tasks/.gitkeep +0 -0
- package/agent/tasks/task-1-{title}.template.md +225 -0
- package/agent/tasks/task-86-task-data-model-schemas.md +143 -0
- package/agent/tasks/task-87-task-database-service.md +220 -0
- package/agent/tasks/task-88-firebase-client-wrapper.md +139 -0
- package/agent/tasks/task-88-task-execution-engine.md +277 -0
- package/agent/tasks/task-89-mcp-server-implementation.md +197 -0
- package/agent/tasks/task-90-build-configuration.md +146 -0
- package/agent/tasks/task-91-deployment-configuration.md +128 -0
- package/coverage/base.css +224 -0
- package/coverage/block-navigation.js +87 -0
- package/coverage/favicon.png +0 -0
- package/coverage/index.html +191 -0
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +87 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +191 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +210 -0
- package/coverage/lcov-report/src/client.ts.html +1030 -0
- package/coverage/lcov-report/src/constant/collections.ts.html +469 -0
- package/coverage/lcov-report/src/constant/index.html +116 -0
- package/coverage/lcov-report/src/dto/index.html +116 -0
- package/coverage/lcov-report/src/dto/transformers.ts.html +568 -0
- package/coverage/lcov-report/src/index.html +146 -0
- package/coverage/lcov-report/src/schemas/index.html +116 -0
- package/coverage/lcov-report/src/schemas/task.ts.html +547 -0
- package/coverage/lcov-report/src/server-factory.ts.html +418 -0
- package/coverage/lcov-report/src/server.ts.html +289 -0
- package/coverage/lcov-report/src/services/index.html +116 -0
- package/coverage/lcov-report/src/services/task-database.service.ts.html +1495 -0
- package/coverage/lcov-report/src/tools/index.html +236 -0
- package/coverage/lcov-report/src/tools/index.ts.html +292 -0
- package/coverage/lcov-report/src/tools/task-add-message.ts.html +277 -0
- package/coverage/lcov-report/src/tools/task-complete-task-item.ts.html +343 -0
- package/coverage/lcov-report/src/tools/task-create-milestone.ts.html +286 -0
- package/coverage/lcov-report/src/tools/task-create-task-item.ts.html +358 -0
- package/coverage/lcov-report/src/tools/task-get-next-step.ts.html +460 -0
- package/coverage/lcov-report/src/tools/task-get-status.ts.html +316 -0
- package/coverage/lcov-report/src/tools/task-report-completion.ts.html +343 -0
- package/coverage/lcov-report/src/tools/task-update-progress.ts.html +232 -0
- package/coverage/lcov.info +974 -0
- package/coverage/prettify.css +1 -0
- package/coverage/prettify.js +2 -0
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +210 -0
- package/coverage/src/client.ts.html +1030 -0
- package/coverage/src/constant/collections.ts.html +469 -0
- package/coverage/src/constant/index.html +116 -0
- package/coverage/src/dto/index.html +116 -0
- package/coverage/src/dto/transformers.ts.html +568 -0
- package/coverage/src/index.html +146 -0
- package/coverage/src/schemas/index.html +116 -0
- package/coverage/src/schemas/task.ts.html +547 -0
- package/coverage/src/server-factory.ts.html +418 -0
- package/coverage/src/server.ts.html +289 -0
- package/coverage/src/services/index.html +116 -0
- package/coverage/src/services/task-database.service.ts.html +1495 -0
- package/coverage/src/tools/index.html +236 -0
- package/coverage/src/tools/index.ts.html +292 -0
- package/coverage/src/tools/task-add-message.ts.html +277 -0
- package/coverage/src/tools/task-complete-task-item.ts.html +343 -0
- package/coverage/src/tools/task-create-milestone.ts.html +286 -0
- package/coverage/src/tools/task-create-task-item.ts.html +358 -0
- package/coverage/src/tools/task-get-next-step.ts.html +460 -0
- package/coverage/src/tools/task-get-status.ts.html +316 -0
- package/coverage/src/tools/task-report-completion.ts.html +343 -0
- package/coverage/src/tools/task-update-progress.ts.html +232 -0
- package/firestore.rules +95 -0
- package/jest.config.js +31 -0
- package/package.json +67 -0
- package/src/client.spec.ts +199 -0
- package/src/client.ts +315 -0
- package/src/constant/collections.ts +128 -0
- package/src/dto/index.ts +47 -0
- package/src/dto/task-api.dto.ts +219 -0
- package/src/dto/transformers.spec.ts +462 -0
- package/src/dto/transformers.ts +161 -0
- package/src/schemas/task.ts +154 -0
- package/src/server-factory.spec.ts +70 -0
- package/src/server-factory.ts +111 -0
- package/src/server.ts +68 -0
- package/src/services/task-database.service.e2e.ts +116 -0
- package/src/services/task-database.service.spec.ts +479 -0
- package/src/services/task-database.service.ts +470 -0
- package/src/test-schemas.ts +161 -0
- package/src/tools/index.ts +69 -0
- package/src/tools/task-add-message.ts +64 -0
- package/src/tools/task-complete-task-item.ts +86 -0
- package/src/tools/task-create-milestone.ts +67 -0
- package/src/tools/task-create-task-item.ts +91 -0
- package/src/tools/task-get-next-step.spec.ts +136 -0
- package/src/tools/task-get-next-step.ts +125 -0
- package/src/tools/task-get-status.spec.ts +213 -0
- package/src/tools/task-get-status.ts +77 -0
- package/src/tools/task-report-completion.ts +86 -0
- package/src/tools/task-update-progress.ts +49 -0
- package/src/tools/tools.spec.ts +194 -0
- package/tsconfig.json +31 -0
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
# Task 90: MCP Server Implementation
|
|
2
|
+
|
|
3
|
+
**Milestone**: Milestone 2 - MCP Server Foundation
|
|
4
|
+
**Estimated Time**: 8 hours
|
|
5
|
+
**Dependencies**: Task 89 (Core MCP Tools)
|
|
6
|
+
**Status**: Not Started
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Objective
|
|
11
|
+
|
|
12
|
+
Create the MCP server implementation that exposes task management tools via MCP protocol. Implement both standalone server (stdio transport) and server factory (multi-tenant) following the MCP Server Bootstrap Pattern.
|
|
13
|
+
|
|
14
|
+
## Steps
|
|
15
|
+
|
|
16
|
+
### 1. Install MCP SDK
|
|
17
|
+
|
|
18
|
+
Install dependencies:
|
|
19
|
+
```bash
|
|
20
|
+
npm install @modelcontextprotocol/sdk
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### 2. Create Server Factory
|
|
24
|
+
|
|
25
|
+
Create `src/server-factory.ts`:
|
|
26
|
+
- Export `createServer(userId, options)` function
|
|
27
|
+
- Initialize FirebaseClient with userId
|
|
28
|
+
- Create MCP Server instance
|
|
29
|
+
- Register all tools from `src/tools/`
|
|
30
|
+
- Handle `list_tools` requests
|
|
31
|
+
- Handle `call_tool` requests
|
|
32
|
+
- Return configured Server instance
|
|
33
|
+
|
|
34
|
+
### 3. Create Standalone Server
|
|
35
|
+
|
|
36
|
+
Create `src/server.ts`:
|
|
37
|
+
- CLI entry point for stdio transport
|
|
38
|
+
- Load userId from environment or args
|
|
39
|
+
- Use server factory to create instance
|
|
40
|
+
- Connect with StdioServerTransport
|
|
41
|
+
- Handle graceful shutdown
|
|
42
|
+
|
|
43
|
+
### 4. Create CLI Entry Point
|
|
44
|
+
|
|
45
|
+
Create `src/index.ts`:
|
|
46
|
+
- Parse command line arguments
|
|
47
|
+
- Load environment variables
|
|
48
|
+
- Start standalone server
|
|
49
|
+
- Handle errors
|
|
50
|
+
|
|
51
|
+
### 5. Create Types
|
|
52
|
+
|
|
53
|
+
Create `src/types.ts`:
|
|
54
|
+
- MCP-specific type definitions
|
|
55
|
+
- Server options interface
|
|
56
|
+
- Tool handler types
|
|
57
|
+
- Export shared types
|
|
58
|
+
|
|
59
|
+
### 6. Write Unit Tests
|
|
60
|
+
|
|
61
|
+
Create tests:
|
|
62
|
+
- `src/server-factory.spec.ts` - Test factory function
|
|
63
|
+
- `src/server.spec.ts` - Test server initialization
|
|
64
|
+
- Test tool registration
|
|
65
|
+
- Test request handling
|
|
66
|
+
|
|
67
|
+
## Verification
|
|
68
|
+
|
|
69
|
+
- [ ] Server factory creates isolated instances
|
|
70
|
+
- [ ] Standalone server starts with stdio
|
|
71
|
+
- [ ] All tools registered correctly
|
|
72
|
+
- [ ] list_tools returns all 8 tools
|
|
73
|
+
- [ ] call_tool executes tools correctly
|
|
74
|
+
- [ ] Error handling works
|
|
75
|
+
- [ ] Unit tests pass
|
|
76
|
+
- [ ] TypeScript compiles without errors
|
|
77
|
+
|
|
78
|
+
## Example Server Factory
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
// src/server-factory.ts
|
|
82
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js'
|
|
83
|
+
import {
|
|
84
|
+
CallToolRequestSchema,
|
|
85
|
+
ListToolsRequestSchema,
|
|
86
|
+
ErrorCode,
|
|
87
|
+
McpError
|
|
88
|
+
} from '@modelcontextprotocol/sdk/types.js'
|
|
89
|
+
import { FirebaseClient } from './client.js'
|
|
90
|
+
import {
|
|
91
|
+
taskGetStatusTool,
|
|
92
|
+
handleTaskGetStatus,
|
|
93
|
+
taskGetNextStepTool,
|
|
94
|
+
handleTaskGetNextStep,
|
|
95
|
+
// ... import all tools
|
|
96
|
+
} from './tools/index.js'
|
|
97
|
+
|
|
98
|
+
export interface ServerOptions {
|
|
99
|
+
name?: string
|
|
100
|
+
version?: string
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export function createServer(
|
|
104
|
+
userId: string,
|
|
105
|
+
options: ServerOptions = {}
|
|
106
|
+
): Server {
|
|
107
|
+
if (!userId) {
|
|
108
|
+
throw new Error('userId is required')
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Initialize Firebase client for this user
|
|
112
|
+
const client = new FirebaseClient(userId)
|
|
113
|
+
|
|
114
|
+
// Create MCP server
|
|
115
|
+
const server = new Server(
|
|
116
|
+
{
|
|
117
|
+
name: options.name || 'task-mcp',
|
|
118
|
+
version: options.version || '0.1.0'
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
capabilities: {
|
|
122
|
+
tools: {}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
// Register list_tools handler
|
|
128
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
129
|
+
return {
|
|
130
|
+
tools: [
|
|
131
|
+
taskGetStatusTool,
|
|
132
|
+
taskGetNextStepTool,
|
|
133
|
+
// ... all tool definitions
|
|
134
|
+
]
|
|
135
|
+
}
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
// Register call_tool handler
|
|
139
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
140
|
+
const { name, arguments: args } = request.params
|
|
141
|
+
|
|
142
|
+
try {
|
|
143
|
+
let result: string
|
|
144
|
+
|
|
145
|
+
switch (name) {
|
|
146
|
+
case 'task_get_status':
|
|
147
|
+
result = await handleTaskGetStatus(client, args)
|
|
148
|
+
break
|
|
149
|
+
|
|
150
|
+
case 'task_get_next_step':
|
|
151
|
+
result = await handleTaskGetNextStep(client, args)
|
|
152
|
+
break
|
|
153
|
+
|
|
154
|
+
// ... all tool handlers
|
|
155
|
+
|
|
156
|
+
default:
|
|
157
|
+
throw new McpError(
|
|
158
|
+
ErrorCode.MethodNotFound,
|
|
159
|
+
`Unknown tool: ${name}`
|
|
160
|
+
)
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return {
|
|
164
|
+
content: [
|
|
165
|
+
{
|
|
166
|
+
type: 'text',
|
|
167
|
+
text: result
|
|
168
|
+
}
|
|
169
|
+
]
|
|
170
|
+
}
|
|
171
|
+
} catch (error) {
|
|
172
|
+
if (error instanceof McpError) {
|
|
173
|
+
throw error
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
throw new McpError(
|
|
177
|
+
ErrorCode.InternalError,
|
|
178
|
+
`Tool execution failed: ${error instanceof Error ? error.message : String(error)}`
|
|
179
|
+
)
|
|
180
|
+
}
|
|
181
|
+
})
|
|
182
|
+
|
|
183
|
+
return server
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## Files to Create
|
|
188
|
+
|
|
189
|
+
- `src/server-factory.ts`
|
|
190
|
+
- `src/server-factory.spec.ts`
|
|
191
|
+
- `src/server.ts`
|
|
192
|
+
- `src/index.ts`
|
|
193
|
+
- `src/types.ts`
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
**Next Task**: [Task 91: Build Configuration](task-91-build-configuration.md)
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# Task 91: Build Configuration
|
|
2
|
+
|
|
3
|
+
**Milestone**: Milestone 2 - MCP Server Foundation
|
|
4
|
+
**Estimated Time**: 4 hours
|
|
5
|
+
**Dependencies**: Task 90 (MCP Server Implementation)
|
|
6
|
+
**Status**: Not Started
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Objective
|
|
11
|
+
|
|
12
|
+
Create esbuild configuration for bundling the MCP server for deployment. Set up both build and watch modes following the MCP Server Bootstrap Pattern.
|
|
13
|
+
|
|
14
|
+
## Steps
|
|
15
|
+
|
|
16
|
+
### 1. Install esbuild
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install --save-dev esbuild
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### 2. Create Build Script
|
|
23
|
+
|
|
24
|
+
Create `esbuild.build.js`:
|
|
25
|
+
- Bundle `src/server.ts` for standalone deployment
|
|
26
|
+
- Bundle `src/server-factory.ts` for library usage
|
|
27
|
+
- Target Node.js 20
|
|
28
|
+
- ESM format
|
|
29
|
+
- External dependencies: firebase-admin, @modelcontextprotocol/sdk
|
|
30
|
+
- Generate source maps
|
|
31
|
+
- Generate TypeScript declarations
|
|
32
|
+
|
|
33
|
+
### 3. Create Watch Script
|
|
34
|
+
|
|
35
|
+
Create `esbuild.watch.js`:
|
|
36
|
+
- Same configuration as build script
|
|
37
|
+
- Enable watch mode for development
|
|
38
|
+
- Auto-rebuild on file changes
|
|
39
|
+
|
|
40
|
+
### 4. Update package.json Scripts
|
|
41
|
+
|
|
42
|
+
Add build scripts:
|
|
43
|
+
```json
|
|
44
|
+
{
|
|
45
|
+
"scripts": {
|
|
46
|
+
"build": "node esbuild.build.js",
|
|
47
|
+
"build:watch": "node esbuild.watch.js",
|
|
48
|
+
"clean": "rm -rf dist",
|
|
49
|
+
"dev": "npm run build:watch"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### 5. Test Build
|
|
55
|
+
|
|
56
|
+
Run build and verify:
|
|
57
|
+
- `npm run build` succeeds
|
|
58
|
+
- `dist/server.js` created
|
|
59
|
+
- `dist/server-factory.js` created
|
|
60
|
+
- Type declarations generated
|
|
61
|
+
- No build errors
|
|
62
|
+
|
|
63
|
+
## Verification
|
|
64
|
+
|
|
65
|
+
- [ ] esbuild.build.js created
|
|
66
|
+
- [ ] esbuild.watch.js created
|
|
67
|
+
- [ ] Build succeeds without errors
|
|
68
|
+
- [ ] dist/ directory contains bundled files
|
|
69
|
+
- [ ] TypeScript declarations generated
|
|
70
|
+
- [ ] Source maps generated
|
|
71
|
+
- [ ] Watch mode works for development
|
|
72
|
+
- [ ] Bundle size is reasonable
|
|
73
|
+
|
|
74
|
+
## Example Build Script
|
|
75
|
+
|
|
76
|
+
```javascript
|
|
77
|
+
// esbuild.build.js
|
|
78
|
+
import * as esbuild from 'esbuild';
|
|
79
|
+
import { execSync } from 'child_process';
|
|
80
|
+
|
|
81
|
+
// Build standalone server
|
|
82
|
+
await esbuild.build({
|
|
83
|
+
entryPoints: ['src/server.ts'],
|
|
84
|
+
bundle: true,
|
|
85
|
+
platform: 'node',
|
|
86
|
+
target: 'node20',
|
|
87
|
+
format: 'esm',
|
|
88
|
+
outfile: 'dist/server.js',
|
|
89
|
+
sourcemap: true,
|
|
90
|
+
external: [
|
|
91
|
+
'firebase-admin',
|
|
92
|
+
'@modelcontextprotocol/sdk'
|
|
93
|
+
],
|
|
94
|
+
banner: {
|
|
95
|
+
js: "import { createRequire } from 'module'; const require = createRequire(import.meta.url);"
|
|
96
|
+
},
|
|
97
|
+
alias: {
|
|
98
|
+
'@': './src'
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
// Build server factory
|
|
103
|
+
await esbuild.build({
|
|
104
|
+
entryPoints: ['src/server-factory.ts'],
|
|
105
|
+
bundle: true,
|
|
106
|
+
platform: 'node',
|
|
107
|
+
target: 'node20',
|
|
108
|
+
format: 'esm',
|
|
109
|
+
outfile: 'dist/server-factory.js',
|
|
110
|
+
sourcemap: true,
|
|
111
|
+
external: [
|
|
112
|
+
'firebase-admin',
|
|
113
|
+
'@modelcontextprotocol/sdk'
|
|
114
|
+
],
|
|
115
|
+
banner: {
|
|
116
|
+
js: "import { createRequire } from 'module'; const require = createRequire(import.meta.url);"
|
|
117
|
+
},
|
|
118
|
+
alias: {
|
|
119
|
+
'@': './src'
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
console.log('✓ JavaScript bundles built');
|
|
124
|
+
|
|
125
|
+
// Generate TypeScript declarations
|
|
126
|
+
console.log('Generating TypeScript declarations...');
|
|
127
|
+
try {
|
|
128
|
+
execSync('tsc --emitDeclarationOnly --outDir dist', { stdio: 'inherit' });
|
|
129
|
+
console.log('✓ TypeScript declarations generated');
|
|
130
|
+
} catch (error) {
|
|
131
|
+
console.error('✗ Failed to generate TypeScript declarations');
|
|
132
|
+
process.exit(1);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
console.log('✓ Build complete');
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Files to Create
|
|
139
|
+
|
|
140
|
+
- `esbuild.build.js`
|
|
141
|
+
- `esbuild.watch.js`
|
|
142
|
+
- Update `package.json` scripts
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
**Next Task**: [Task 92: Deployment Configuration](task-92-deployment-configuration.md)
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# Task 92: Deployment Configuration
|
|
2
|
+
|
|
3
|
+
**Milestone**: Milestone 2 - MCP Server Foundation
|
|
4
|
+
**Estimated Time**: 4 hours
|
|
5
|
+
**Dependencies**: Task 91 (Build Configuration)
|
|
6
|
+
**Status**: Not Started
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Objective
|
|
11
|
+
|
|
12
|
+
Create deployment configuration for running task-mcp MCP server on Cloud Run or other platforms. Set up environment variables, service account configuration, and deployment scripts.
|
|
13
|
+
|
|
14
|
+
## Steps
|
|
15
|
+
|
|
16
|
+
### 1. Create Environment Configuration
|
|
17
|
+
|
|
18
|
+
Create `.env.example`:
|
|
19
|
+
```bash
|
|
20
|
+
# Firebase Configuration
|
|
21
|
+
FIREBASE_PROJECT_ID=your-project-id
|
|
22
|
+
FIREBASE_SERVICE_ACCOUNT_PATH=./service-account.json
|
|
23
|
+
# Or use JSON directly:
|
|
24
|
+
# FIREBASE_SERVICE_ACCOUNT_JSON={"type":"service_account",...}
|
|
25
|
+
|
|
26
|
+
# Server Configuration
|
|
27
|
+
NODE_ENV=production
|
|
28
|
+
LOG_LEVEL=info
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### 2. Create Dockerfile
|
|
32
|
+
|
|
33
|
+
Create `Dockerfile`:
|
|
34
|
+
- Use Node.js 20 base image
|
|
35
|
+
- Copy package files and install dependencies
|
|
36
|
+
- Copy source code
|
|
37
|
+
- Build the project
|
|
38
|
+
- Set up entrypoint for server
|
|
39
|
+
- Expose necessary ports (if using SSE)
|
|
40
|
+
|
|
41
|
+
### 3. Create Cloud Run Configuration
|
|
42
|
+
|
|
43
|
+
Create `cloudrun.yaml`:
|
|
44
|
+
- Service name: task-mcp
|
|
45
|
+
- Region: us-central1
|
|
46
|
+
- Memory: 512Mi
|
|
47
|
+
- CPU: 1
|
|
48
|
+
- Min instances: 0
|
|
49
|
+
- Max instances: 10
|
|
50
|
+
- Environment variables
|
|
51
|
+
- Service account
|
|
52
|
+
|
|
53
|
+
### 4. Create Deployment Script
|
|
54
|
+
|
|
55
|
+
Create `scripts/deploy.sh`:
|
|
56
|
+
- Build Docker image
|
|
57
|
+
- Push to Google Container Registry
|
|
58
|
+
- Deploy to Cloud Run
|
|
59
|
+
- Set environment variables
|
|
60
|
+
- Configure service account
|
|
61
|
+
|
|
62
|
+
### 5. Update .gitignore
|
|
63
|
+
|
|
64
|
+
Add to `.gitignore`:
|
|
65
|
+
- `service-account.json`
|
|
66
|
+
- `.env`
|
|
67
|
+
- `.env.local`
|
|
68
|
+
- `dist/`
|
|
69
|
+
- `coverage/`
|
|
70
|
+
|
|
71
|
+
### 6. Create README
|
|
72
|
+
|
|
73
|
+
Create `README.md`:
|
|
74
|
+
- Project description
|
|
75
|
+
- Installation instructions
|
|
76
|
+
- Configuration guide
|
|
77
|
+
- Deployment guide
|
|
78
|
+
- Usage examples
|
|
79
|
+
|
|
80
|
+
## Verification
|
|
81
|
+
|
|
82
|
+
- [ ] .env.example created
|
|
83
|
+
- [ ] Dockerfile builds successfully
|
|
84
|
+
- [ ] Cloud Run configuration valid
|
|
85
|
+
- [ ] Deployment script works
|
|
86
|
+
- [ ] .gitignore updated
|
|
87
|
+
- [ ] README.md complete
|
|
88
|
+
- [ ] Service account not in git
|
|
89
|
+
- [ ] Environment variables documented
|
|
90
|
+
|
|
91
|
+
## Example Dockerfile
|
|
92
|
+
|
|
93
|
+
```dockerfile
|
|
94
|
+
FROM node:20-alpine
|
|
95
|
+
|
|
96
|
+
WORKDIR /app
|
|
97
|
+
|
|
98
|
+
# Copy package files
|
|
99
|
+
COPY package*.json ./
|
|
100
|
+
|
|
101
|
+
# Install dependencies
|
|
102
|
+
RUN npm ci --only=production
|
|
103
|
+
|
|
104
|
+
# Copy source code
|
|
105
|
+
COPY . .
|
|
106
|
+
|
|
107
|
+
# Build the project
|
|
108
|
+
RUN npm run build
|
|
109
|
+
|
|
110
|
+
# Set environment
|
|
111
|
+
ENV NODE_ENV=production
|
|
112
|
+
|
|
113
|
+
# Run the server
|
|
114
|
+
CMD ["node", "dist/server.js"]
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Files to Create
|
|
118
|
+
|
|
119
|
+
- `Dockerfile`
|
|
120
|
+
- `.env.example`
|
|
121
|
+
- `cloudrun.yaml`
|
|
122
|
+
- `scripts/deploy.sh`
|
|
123
|
+
- `README.md`
|
|
124
|
+
- Update `.gitignore`
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
**Next Task**: Milestone 2 Complete! → [Milestone 3: agentbase.me Integration](../milestones/milestone-3-agentbase-integration.md)
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
body, html {
|
|
2
|
+
margin:0; padding: 0;
|
|
3
|
+
height: 100%;
|
|
4
|
+
}
|
|
5
|
+
body {
|
|
6
|
+
font-family: Helvetica Neue, Helvetica, Arial;
|
|
7
|
+
font-size: 14px;
|
|
8
|
+
color:#333;
|
|
9
|
+
}
|
|
10
|
+
.small { font-size: 12px; }
|
|
11
|
+
*, *:after, *:before {
|
|
12
|
+
-webkit-box-sizing:border-box;
|
|
13
|
+
-moz-box-sizing:border-box;
|
|
14
|
+
box-sizing:border-box;
|
|
15
|
+
}
|
|
16
|
+
h1 { font-size: 20px; margin: 0;}
|
|
17
|
+
h2 { font-size: 14px; }
|
|
18
|
+
pre {
|
|
19
|
+
font: 12px/1.4 Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
|
20
|
+
margin: 0;
|
|
21
|
+
padding: 0;
|
|
22
|
+
-moz-tab-size: 2;
|
|
23
|
+
-o-tab-size: 2;
|
|
24
|
+
tab-size: 2;
|
|
25
|
+
}
|
|
26
|
+
a { color:#0074D9; text-decoration:none; }
|
|
27
|
+
a:hover { text-decoration:underline; }
|
|
28
|
+
.strong { font-weight: bold; }
|
|
29
|
+
.space-top1 { padding: 10px 0 0 0; }
|
|
30
|
+
.pad2y { padding: 20px 0; }
|
|
31
|
+
.pad1y { padding: 10px 0; }
|
|
32
|
+
.pad2x { padding: 0 20px; }
|
|
33
|
+
.pad2 { padding: 20px; }
|
|
34
|
+
.pad1 { padding: 10px; }
|
|
35
|
+
.space-left2 { padding-left:55px; }
|
|
36
|
+
.space-right2 { padding-right:20px; }
|
|
37
|
+
.center { text-align:center; }
|
|
38
|
+
.clearfix { display:block; }
|
|
39
|
+
.clearfix:after {
|
|
40
|
+
content:'';
|
|
41
|
+
display:block;
|
|
42
|
+
height:0;
|
|
43
|
+
clear:both;
|
|
44
|
+
visibility:hidden;
|
|
45
|
+
}
|
|
46
|
+
.fl { float: left; }
|
|
47
|
+
@media only screen and (max-width:640px) {
|
|
48
|
+
.col3 { width:100%; max-width:100%; }
|
|
49
|
+
.hide-mobile { display:none!important; }
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.quiet {
|
|
53
|
+
color: #7f7f7f;
|
|
54
|
+
color: rgba(0,0,0,0.5);
|
|
55
|
+
}
|
|
56
|
+
.quiet a { opacity: 0.7; }
|
|
57
|
+
|
|
58
|
+
.fraction {
|
|
59
|
+
font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace;
|
|
60
|
+
font-size: 10px;
|
|
61
|
+
color: #555;
|
|
62
|
+
background: #E8E8E8;
|
|
63
|
+
padding: 4px 5px;
|
|
64
|
+
border-radius: 3px;
|
|
65
|
+
vertical-align: middle;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
div.path a:link, div.path a:visited { color: #333; }
|
|
69
|
+
table.coverage {
|
|
70
|
+
border-collapse: collapse;
|
|
71
|
+
margin: 10px 0 0 0;
|
|
72
|
+
padding: 0;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
table.coverage td {
|
|
76
|
+
margin: 0;
|
|
77
|
+
padding: 0;
|
|
78
|
+
vertical-align: top;
|
|
79
|
+
}
|
|
80
|
+
table.coverage td.line-count {
|
|
81
|
+
text-align: right;
|
|
82
|
+
padding: 0 5px 0 20px;
|
|
83
|
+
}
|
|
84
|
+
table.coverage td.line-coverage {
|
|
85
|
+
text-align: right;
|
|
86
|
+
padding-right: 10px;
|
|
87
|
+
min-width:20px;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
table.coverage td span.cline-any {
|
|
91
|
+
display: inline-block;
|
|
92
|
+
padding: 0 5px;
|
|
93
|
+
width: 100%;
|
|
94
|
+
}
|
|
95
|
+
.missing-if-branch {
|
|
96
|
+
display: inline-block;
|
|
97
|
+
margin-right: 5px;
|
|
98
|
+
border-radius: 3px;
|
|
99
|
+
position: relative;
|
|
100
|
+
padding: 0 4px;
|
|
101
|
+
background: #333;
|
|
102
|
+
color: yellow;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.skip-if-branch {
|
|
106
|
+
display: none;
|
|
107
|
+
margin-right: 10px;
|
|
108
|
+
position: relative;
|
|
109
|
+
padding: 0 4px;
|
|
110
|
+
background: #ccc;
|
|
111
|
+
color: white;
|
|
112
|
+
}
|
|
113
|
+
.missing-if-branch .typ, .skip-if-branch .typ {
|
|
114
|
+
color: inherit !important;
|
|
115
|
+
}
|
|
116
|
+
.coverage-summary {
|
|
117
|
+
border-collapse: collapse;
|
|
118
|
+
width: 100%;
|
|
119
|
+
}
|
|
120
|
+
.coverage-summary tr { border-bottom: 1px solid #bbb; }
|
|
121
|
+
.keyline-all { border: 1px solid #ddd; }
|
|
122
|
+
.coverage-summary td, .coverage-summary th { padding: 10px; }
|
|
123
|
+
.coverage-summary tbody { border: 1px solid #bbb; }
|
|
124
|
+
.coverage-summary td { border-right: 1px solid #bbb; }
|
|
125
|
+
.coverage-summary td:last-child { border-right: none; }
|
|
126
|
+
.coverage-summary th {
|
|
127
|
+
text-align: left;
|
|
128
|
+
font-weight: normal;
|
|
129
|
+
white-space: nowrap;
|
|
130
|
+
}
|
|
131
|
+
.coverage-summary th.file { border-right: none !important; }
|
|
132
|
+
.coverage-summary th.pct { }
|
|
133
|
+
.coverage-summary th.pic,
|
|
134
|
+
.coverage-summary th.abs,
|
|
135
|
+
.coverage-summary td.pct,
|
|
136
|
+
.coverage-summary td.abs { text-align: right; }
|
|
137
|
+
.coverage-summary td.file { white-space: nowrap; }
|
|
138
|
+
.coverage-summary td.pic { min-width: 120px !important; }
|
|
139
|
+
.coverage-summary tfoot td { }
|
|
140
|
+
|
|
141
|
+
.coverage-summary .sorter {
|
|
142
|
+
height: 10px;
|
|
143
|
+
width: 7px;
|
|
144
|
+
display: inline-block;
|
|
145
|
+
margin-left: 0.5em;
|
|
146
|
+
background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent;
|
|
147
|
+
}
|
|
148
|
+
.coverage-summary .sorted .sorter {
|
|
149
|
+
background-position: 0 -20px;
|
|
150
|
+
}
|
|
151
|
+
.coverage-summary .sorted-desc .sorter {
|
|
152
|
+
background-position: 0 -10px;
|
|
153
|
+
}
|
|
154
|
+
.status-line { height: 10px; }
|
|
155
|
+
/* yellow */
|
|
156
|
+
.cbranch-no { background: yellow !important; color: #111; }
|
|
157
|
+
/* dark red */
|
|
158
|
+
.red.solid, .status-line.low, .low .cover-fill { background:#C21F39 }
|
|
159
|
+
.low .chart { border:1px solid #C21F39 }
|
|
160
|
+
.highlighted,
|
|
161
|
+
.highlighted .cstat-no, .highlighted .fstat-no, .highlighted .cbranch-no{
|
|
162
|
+
background: #C21F39 !important;
|
|
163
|
+
}
|
|
164
|
+
/* medium red */
|
|
165
|
+
.cstat-no, .fstat-no, .cbranch-no, .cbranch-no { background:#F6C6CE }
|
|
166
|
+
/* light red */
|
|
167
|
+
.low, .cline-no { background:#FCE1E5 }
|
|
168
|
+
/* light green */
|
|
169
|
+
.high, .cline-yes { background:rgb(230,245,208) }
|
|
170
|
+
/* medium green */
|
|
171
|
+
.cstat-yes { background:rgb(161,215,106) }
|
|
172
|
+
/* dark green */
|
|
173
|
+
.status-line.high, .high .cover-fill { background:rgb(77,146,33) }
|
|
174
|
+
.high .chart { border:1px solid rgb(77,146,33) }
|
|
175
|
+
/* dark yellow (gold) */
|
|
176
|
+
.status-line.medium, .medium .cover-fill { background: #f9cd0b; }
|
|
177
|
+
.medium .chart { border:1px solid #f9cd0b; }
|
|
178
|
+
/* light yellow */
|
|
179
|
+
.medium { background: #fff4c2; }
|
|
180
|
+
|
|
181
|
+
.cstat-skip { background: #ddd; color: #111; }
|
|
182
|
+
.fstat-skip { background: #ddd; color: #111 !important; }
|
|
183
|
+
.cbranch-skip { background: #ddd !important; color: #111; }
|
|
184
|
+
|
|
185
|
+
span.cline-neutral { background: #eaeaea; }
|
|
186
|
+
|
|
187
|
+
.coverage-summary td.empty {
|
|
188
|
+
opacity: .5;
|
|
189
|
+
padding-top: 4px;
|
|
190
|
+
padding-bottom: 4px;
|
|
191
|
+
line-height: 1;
|
|
192
|
+
color: #888;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
.cover-fill, .cover-empty {
|
|
196
|
+
display:inline-block;
|
|
197
|
+
height: 12px;
|
|
198
|
+
}
|
|
199
|
+
.chart {
|
|
200
|
+
line-height: 0;
|
|
201
|
+
}
|
|
202
|
+
.cover-empty {
|
|
203
|
+
background: white;
|
|
204
|
+
}
|
|
205
|
+
.cover-full {
|
|
206
|
+
border-right: none !important;
|
|
207
|
+
}
|
|
208
|
+
pre.prettyprint {
|
|
209
|
+
border: none !important;
|
|
210
|
+
padding: 0 !important;
|
|
211
|
+
margin: 0 !important;
|
|
212
|
+
}
|
|
213
|
+
.com { color: #999 !important; }
|
|
214
|
+
.ignore-none { color: #999; font-weight: normal; }
|
|
215
|
+
|
|
216
|
+
.wrapper {
|
|
217
|
+
min-height: 100%;
|
|
218
|
+
height: auto !important;
|
|
219
|
+
height: 100%;
|
|
220
|
+
margin: 0 auto -48px;
|
|
221
|
+
}
|
|
222
|
+
.footer, .push {
|
|
223
|
+
height: 48px;
|
|
224
|
+
}
|