@hapticpaper/mcp-server 1.0.8 → 1.0.9

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.
@@ -0,0 +1,107 @@
1
+ import axios from 'axios';
2
+ export class HapticPaperClient {
3
+ client;
4
+ tokenProvider;
5
+ constructor(config) {
6
+ this.client = axios.create({
7
+ baseURL: config.baseUrl,
8
+ headers: {
9
+ 'Content-Type': 'application/json',
10
+ },
11
+ });
12
+ this.tokenProvider = config.tokenProvider;
13
+ // Request interceptor to add auth token
14
+ this.client.interceptors.request.use(async (config) => {
15
+ if (this.tokenProvider) {
16
+ const token = await this.tokenProvider();
17
+ if (token) {
18
+ config.headers.Authorization = `Bearer ${token}`;
19
+ }
20
+ }
21
+ return config;
22
+ });
23
+ }
24
+ async authHeaders(accessToken) {
25
+ if (accessToken) {
26
+ return { Authorization: `Bearer ${accessToken}` };
27
+ }
28
+ if (!this.tokenProvider) {
29
+ return {};
30
+ }
31
+ const token = await this.tokenProvider();
32
+ return token ? { Authorization: `Bearer ${token}` } : {};
33
+ }
34
+ // Account Methods
35
+ async getAccount(accessToken) {
36
+ const response = await this.client.get('/gpt/account', { headers: await this.authHeaders(accessToken) });
37
+ return response.data;
38
+ }
39
+ // Task Methods
40
+ async createTask(data, accessToken) {
41
+ const response = await this.client.post('/gpt/tasks', data, { headers: await this.authHeaders(accessToken) });
42
+ return response.data;
43
+ }
44
+ async getTask(taskId, accessToken) {
45
+ const response = await this.client.get(`/gpt/tasks/${taskId}`, { headers: await this.authHeaders(accessToken) });
46
+ return response.data;
47
+ }
48
+ async listTasks(params, accessToken) {
49
+ const response = await this.client.get('/gpt/tasks', { params, headers: await this.authHeaders(accessToken) });
50
+ return response.data;
51
+ }
52
+ async cancelTask(taskId, reason, accessToken) {
53
+ const response = await this.client.post(`/gpt/tasks/${taskId}/cancel`, { reason }, { headers: await this.authHeaders(accessToken) });
54
+ return response.data;
55
+ }
56
+ // Worker Methods
57
+ async searchWorkers(params, accessToken) {
58
+ const response = await this.client.post('/gpt/workers/search', params, { headers: await this.authHeaders(accessToken) });
59
+ return response.data;
60
+ }
61
+ async getWorkerProfile(workerId, accessToken) {
62
+ // This endpoint might not exist in gptRoutes yet, assuming it maps to backend logic
63
+ // If not in GPT routes, we might need to add it or use a different route
64
+ // For now assuming it exists based on plan
65
+ const response = await this.client.get(`/gpt/workers/${workerId}`, { headers: await this.authHeaders(accessToken) });
66
+ return response.data;
67
+ }
68
+ // Estimate Methods
69
+ async getEstimate(params, accessToken) {
70
+ const response = await this.client.post('/gpt/estimate', params, { headers: await this.authHeaders(accessToken) });
71
+ return response.data;
72
+ }
73
+ async getSkillCategories() {
74
+ // Placeholder or real endpoint
75
+ return [
76
+ {
77
+ name: "Delivery",
78
+ description: "Physical delivery of items",
79
+ examples: ["Food delivery", "Package courier"],
80
+ priceRange: { min: 15, max: 50 }
81
+ },
82
+ {
83
+ name: "General Help",
84
+ description: "Moving, cleaning, organizing",
85
+ examples: ["Help moving boxes", "Garage cleanup"],
86
+ priceRange: { min: 30, max: 100 }
87
+ }
88
+ ];
89
+ }
90
+ // Qualification Methods
91
+ async discoverEarningOpportunity(params) {
92
+ const response = await this.client.post('/gpt/qualification/discover', params);
93
+ return response.data;
94
+ }
95
+ async continueQualification(sessionId, userResponse) {
96
+ const response = await this.client.post(`/gpt/qualification/${sessionId}/respond`, { userResponse });
97
+ return response.data;
98
+ }
99
+ async getQualificationStatus(sessionId) {
100
+ const response = await this.client.get(`/gpt/qualification/${sessionId}`);
101
+ return response.data;
102
+ }
103
+ async completeQualification(sessionId) {
104
+ const response = await this.client.post(`/gpt/qualification/${sessionId}/complete`, {});
105
+ return response.data;
106
+ }
107
+ }
package/dist/index.js CHANGED
@@ -11,7 +11,7 @@ import crypto from 'node:crypto';
11
11
  import fs from 'node:fs';
12
12
  import path from 'node:path';
13
13
  import jwt from 'jsonwebtoken';
14
- import { HireHumanClient } from "./client/hireHumanClient.js";
14
+ import { HapticPaperClient } from "./client/hapticPaperClient.js";
15
15
  import { registerAllTools } from "./tools/index.js";
16
16
  import { registerAllResources } from "./resources/index.js";
17
17
  import { TokenManager, MCPOAuthHandler } from "./auth/oauth.js";
@@ -49,10 +49,10 @@ async function main() {
49
49
  return;
50
50
  }
51
51
  const widgetJs = fs.readFileSync(widgetBundlePath, 'utf8');
52
- server.registerResource('hirehuman-widget', 'ui://widget/hirehuman.html', {}, async () => ({
52
+ server.registerResource('hirehuman-widget', 'ui://widget/hapticpaper.html', {}, async () => ({
53
53
  contents: [
54
54
  {
55
- uri: 'ui://widget/hirehuman.html',
55
+ uri: 'ui://widget/hapticpaper.html',
56
56
  mimeType: 'text/html+skybridge',
57
57
  text: `
58
58
  <div id="hirehuman-root"></div>
@@ -76,7 +76,7 @@ ${widgetJs}
76
76
  _meta: {
77
77
  'openai/widgetPrefersBorder': true,
78
78
  'openai/widgetDomain': 'https://chatgpt.com',
79
- 'openai/widgetDescription': 'Shows interactive task and worker results for Hire-a-Human tools.',
79
+ 'openai/widgetDescription': 'Shows interactive task and worker results for Haptic-Paper tools.',
80
80
  'openai/widgetCSP': {
81
81
  connect_domains: ['https://chatgpt.com'],
82
82
  resource_domains: ['https://*.oaistatic.com'],
@@ -88,7 +88,7 @@ ${widgetJs}
88
88
  }
89
89
  function createMcpServer(client) {
90
90
  const server = new McpServer({
91
- name: "hire-a-human",
91
+ name: "haptic-paper",
92
92
  version: "1.0.0"
93
93
  });
94
94
  registerWidgetTemplate(server);
@@ -112,7 +112,7 @@ ${widgetJs}
112
112
  return tokens.access_token;
113
113
  };
114
114
  // Initialize Client with auto-auth tokenProvider
115
- const client = new HireHumanClient({
115
+ const client = new HapticPaperClient({
116
116
  baseUrl: process.env.API_URL || 'https://hapticpaper.com/api/v1',
117
117
  tokenProvider: async () => {
118
118
  // 1. Check for API key (CI/headless mode)
@@ -209,7 +209,7 @@ ${widgetJs}
209
209
  resource: resourceServerUrl.toString(),
210
210
  authorization_servers: [issuer],
211
211
  scopes_supported: scopesSupported,
212
- resource_name: 'Hire-a-Human MCP',
212
+ resource_name: 'Haptic-Paper MCP',
213
213
  });
214
214
  });
215
215
  if (shouldAdvertiseAuthMetadata) {
@@ -218,7 +218,7 @@ ${widgetJs}
218
218
  oauthMetadata,
219
219
  resourceServerUrl,
220
220
  scopesSupported,
221
- resourceName: 'Hire-a-Human MCP',
221
+ resourceName: 'Haptic-Paper MCP',
222
222
  }));
223
223
  }
224
224
  else if (!authMetadataDisabled) {
@@ -15,7 +15,7 @@ const templates = [
15
15
  typicalDuration: "3-5 hours"
16
16
  }
17
17
  ];
18
- export function registerAllResources(server, _client) {
18
+ export function registerAllResources(server, client) {
19
19
  server.registerResource('task-templates', TEMPLATES_URI, {
20
20
  title: 'Task Templates',
21
21
  description: 'List of common task templates with pricing guidance',
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "hapticpaper",
3
3
  "description": "Connect your account to create human tasks from agentic pipelines.",
4
- "version": "1.0.7",
4
+ "version": "1.0.9",
5
5
  "contextFileName": "HAPTICPAPER.md",
6
6
  "mcpServers": {
7
7
  "hapticpaper": {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@hapticpaper/mcp-server",
3
3
  "mcpName": "com.hapticpaper/mcp",
4
- "version": "1.0.8",
4
+ "version": "1.0.9",
5
5
  "description": "Official MCP Server for Haptic Paper - Connect your account to create human tasks from agentic pipelines.",
6
6
  "type": "module",
7
7
  "main": "dist/index.js",
package/server.json CHANGED
@@ -6,12 +6,16 @@
6
6
  "icons": [
7
7
  {
8
8
  "mimeType": "image/png",
9
- "sizes": ["32x32"],
9
+ "sizes": [
10
+ "32x32"
11
+ ],
10
12
  "src": "https://hapticpaper.com/favicon-32x32.png"
11
13
  },
12
14
  {
13
15
  "mimeType": "image/png",
14
- "sizes": ["192x192"],
16
+ "sizes": [
17
+ "192x192"
18
+ ],
15
19
  "src": "https://hapticpaper.com/android-chrome-192x192.png"
16
20
  }
17
21
  ],
@@ -21,7 +25,7 @@
21
25
  "subfolder": "packages/mcp-server"
22
26
  },
23
27
  "websiteUrl": "https://hapticpaper.com/developer",
24
- "version": "1.0.8",
28
+ "version": "1.0.9",
25
29
  "remotes": [
26
30
  {
27
31
  "type": "streamable-http",
@@ -33,7 +37,7 @@
33
37
  "registryType": "npm",
34
38
  "registryBaseUrl": "https://registry.npmjs.org",
35
39
  "identifier": "@hapticpaper/mcp-server",
36
- "version": "1.0.8",
40
+ "version": "1.0.9",
37
41
  "transport": {
38
42
  "type": "stdio"
39
43
  },