@thecorporation/mcp-server 26.3.10 → 26.3.11
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 +37 -3
- package/dist/index.js +4 -22
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/auth.ts +15 -31
package/README.md
CHANGED
|
@@ -39,7 +39,40 @@ claude mcp add thecorporation -- npx -y @thecorporation/mcp-server
|
|
|
39
39
|
|
|
40
40
|
## Authentication
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
The MCP server shares credentials with the CLI. Authenticate once, use everywhere.
|
|
43
|
+
|
|
44
|
+
### Option 1: Authenticate via CLI (recommended)
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
npx @thecorporation/cli setup
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
This sends a magic link to your email. Click the link, paste the code into the terminal, and your credentials are saved to `~/.corp/config.json`. The MCP server reads this file automatically — no additional configuration needed.
|
|
51
|
+
|
|
52
|
+
Your workspace is the same whether you access it from the CLI, MCP server, or chat at [humans.thecorporation.ai](https://humans.thecorporation.ai/chat).
|
|
53
|
+
|
|
54
|
+
### Option 2: Environment variables
|
|
55
|
+
|
|
56
|
+
Set credentials explicitly in your MCP client config:
|
|
57
|
+
|
|
58
|
+
```json
|
|
59
|
+
{
|
|
60
|
+
"mcpServers": {
|
|
61
|
+
"thecorporation": {
|
|
62
|
+
"command": "npx",
|
|
63
|
+
"args": ["-y", "@thecorporation/mcp-server"],
|
|
64
|
+
"env": {
|
|
65
|
+
"CORP_API_KEY": "sk_...",
|
|
66
|
+
"CORP_WORKSPACE_ID": "ws_..."
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Option 3: Self-hosted
|
|
74
|
+
|
|
75
|
+
Point to your own API server:
|
|
43
76
|
|
|
44
77
|
```json
|
|
45
78
|
{
|
|
@@ -48,6 +81,7 @@ On first run, the server automatically provisions a workspace and saves credenti
|
|
|
48
81
|
"command": "npx",
|
|
49
82
|
"args": ["-y", "@thecorporation/mcp-server"],
|
|
50
83
|
"env": {
|
|
84
|
+
"CORP_API_URL": "http://localhost:8000",
|
|
51
85
|
"CORP_API_KEY": "sk_...",
|
|
52
86
|
"CORP_WORKSPACE_ID": "ws_..."
|
|
53
87
|
}
|
|
@@ -59,8 +93,8 @@ On first run, the server automatically provisions a workspace and saves credenti
|
|
|
59
93
|
| Env var | Description | Default |
|
|
60
94
|
|---|---|---|
|
|
61
95
|
| `CORP_API_URL` | API base URL | `https://api.thecorporation.ai` |
|
|
62
|
-
| `CORP_API_KEY` | API key |
|
|
63
|
-
| `CORP_WORKSPACE_ID` | Workspace ID |
|
|
96
|
+
| `CORP_API_KEY` | API key | from `~/.corp/config.json` |
|
|
97
|
+
| `CORP_WORKSPACE_ID` | Workspace ID | from `~/.corp/config.json` |
|
|
64
98
|
|
|
65
99
|
## Tools
|
|
66
100
|
|
package/dist/index.js
CHANGED
|
@@ -64,7 +64,7 @@ function createMcpServer(client) {
|
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
// src/auth.ts
|
|
67
|
-
import { readFileSync
|
|
67
|
+
import { readFileSync } from "fs";
|
|
68
68
|
import { join as join2 } from "path";
|
|
69
69
|
import { homedir as homedir2 } from "os";
|
|
70
70
|
var CONFIG_FILE = join2(homedir2(), ".corp", "config.json");
|
|
@@ -75,21 +75,6 @@ function loadConfig() {
|
|
|
75
75
|
return {};
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
|
-
function saveConfig(cfg) {
|
|
79
|
-
const dir = join2(homedir2(), ".corp");
|
|
80
|
-
mkdirSync(dir, { recursive: true });
|
|
81
|
-
writeFileSync(CONFIG_FILE, JSON.stringify(cfg, null, 2) + "\n");
|
|
82
|
-
}
|
|
83
|
-
async function provision(apiUrl) {
|
|
84
|
-
const resp = await fetch(`${apiUrl.replace(/\/+$/, "")}/v1/workspaces/provision`, {
|
|
85
|
-
method: "POST",
|
|
86
|
-
headers: { "Content-Type": "application/json" },
|
|
87
|
-
body: JSON.stringify({ name: "mcp-auto" }),
|
|
88
|
-
signal: AbortSignal.timeout(15e3)
|
|
89
|
-
});
|
|
90
|
-
if (!resp.ok) throw new Error(`Provision failed: ${resp.status}`);
|
|
91
|
-
return await resp.json();
|
|
92
|
-
}
|
|
93
78
|
async function resolveOrProvisionAuth(apiUrl = "https://api.thecorporation.ai") {
|
|
94
79
|
const envKey = process.env.CORP_API_KEY || "";
|
|
95
80
|
const envWs = process.env.CORP_WORKSPACE_ID || "";
|
|
@@ -100,12 +85,9 @@ async function resolveOrProvisionAuth(apiUrl = "https://api.thecorporation.ai")
|
|
|
100
85
|
if (cfg.api_key && cfg.workspace_id) {
|
|
101
86
|
return { workspaceId: cfg.workspace_id, apiKey: cfg.api_key, scopes: ["*"] };
|
|
102
87
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
if (!cfg.api_url) cfg.api_url = apiUrl;
|
|
107
|
-
saveConfig(cfg);
|
|
108
|
-
return { workspaceId: result.workspace_id, apiKey: result.api_key, scopes: ["*"] };
|
|
88
|
+
throw new Error(
|
|
89
|
+
"No credentials found. Run `npx @thecorporation/cli setup` to authenticate, or set CORP_API_KEY and CORP_WORKSPACE_ID environment variables."
|
|
90
|
+
);
|
|
109
91
|
}
|
|
110
92
|
|
|
111
93
|
// src/index.ts
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/server.ts","../src/auth.ts"],"sourcesContent":["/**\n * Entry point — resolve auth, start MCP server on stdio.\n */\n\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { CorpAPIClient } from \"@thecorporation/corp-tools\";\nimport { createMcpServer } from \"./server.js\";\nimport { resolveOrProvisionAuth } from \"./auth.js\";\n\nasync function main(): Promise<void> {\n const apiUrl = process.env.CORP_API_URL || \"https://api.thecorporation.ai\";\n\n const ctx = await resolveOrProvisionAuth(apiUrl);\n const client = new CorpAPIClient(apiUrl, ctx.apiKey, ctx.workspaceId);\n const server = createMcpServer(client);\n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n\nmain().catch((err) => {\n console.error(\"Fatal:\", err);\n process.exit(1);\n});\n","/**\n * MCP server — registers all tools from corp-tools definitions,\n * dispatches to the backend API via CorpAPIClient.\n */\n\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport {\n GENERATED_TOOL_DEFINITIONS,\n CorpAPIClient,\n executeTool,\n type ToolContext,\n} from \"@thecorporation/corp-tools\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\n\n// ---------------------------------------------------------------------------\n// Build Zod schemas from JSON Schema properties\n// ---------------------------------------------------------------------------\n\ninterface ToolFunction {\n name: string;\n description: string;\n parameters: {\n type: string;\n properties: Record<string, { type: string; description?: string; enum?: string[]; items?: { type: string } }>;\n required: string[];\n };\n}\n\ninterface ToolDef {\n type: string;\n function: ToolFunction;\n}\n\nfunction buildZodShape(fn: ToolFunction): Record<string, z.ZodTypeAny> {\n const shape: Record<string, z.ZodTypeAny> = {};\n const props = fn.parameters.properties || {};\n const required = new Set(fn.parameters.required || []);\n\n for (const [pname, pinfo] of Object.entries(props)) {\n let schema: z.ZodTypeAny;\n switch (pinfo.type) {\n case \"integer\":\n schema = z.number().int();\n break;\n case \"number\":\n schema = z.number();\n break;\n case \"boolean\":\n schema = z.boolean();\n break;\n case \"array\":\n schema = z.array(pinfo.items?.type === \"object\" ? z.record(z.unknown()) : z.string());\n break;\n case \"object\":\n schema = z.record(z.unknown());\n break;\n default:\n schema = pinfo.enum ? z.enum(pinfo.enum as [string, ...string[]]) : z.string();\n }\n if (pinfo.description) schema = schema.describe(pinfo.description);\n if (!required.has(pname)) schema = schema.optional();\n shape[pname] = schema;\n }\n return shape;\n}\n\n// ---------------------------------------------------------------------------\n// Create and configure MCP server\n// ---------------------------------------------------------------------------\n\nexport function createMcpServer(client: CorpAPIClient): McpServer {\n const server = new McpServer({\n name: \"thecorporation\",\n version: \"0.1.0\",\n });\n\n const ctx: ToolContext = {\n dataDir: join(homedir(), \".corp\", \"data\"),\n };\n\n for (const td of GENERATED_TOOL_DEFINITIONS as unknown as ToolDef[]) {\n const fn = td.function;\n const shape = buildZodShape(fn);\n\n server.tool(fn.name, fn.description, shape, async (args) => {\n const result = await executeTool(fn.name, args as Record<string, unknown>, client, ctx);\n return { content: [{ type: \"text\" as const, text: result }] };\n });\n }\n\n return server;\n}\n","/**\n * MCP server authentication —
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/server.ts","../src/auth.ts"],"sourcesContent":["/**\n * Entry point — resolve auth, start MCP server on stdio.\n */\n\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { CorpAPIClient } from \"@thecorporation/corp-tools\";\nimport { createMcpServer } from \"./server.js\";\nimport { resolveOrProvisionAuth } from \"./auth.js\";\n\nasync function main(): Promise<void> {\n const apiUrl = process.env.CORP_API_URL || \"https://api.thecorporation.ai\";\n\n const ctx = await resolveOrProvisionAuth(apiUrl);\n const client = new CorpAPIClient(apiUrl, ctx.apiKey, ctx.workspaceId);\n const server = createMcpServer(client);\n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n\nmain().catch((err) => {\n console.error(\"Fatal:\", err);\n process.exit(1);\n});\n","/**\n * MCP server — registers all tools from corp-tools definitions,\n * dispatches to the backend API via CorpAPIClient.\n */\n\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport {\n GENERATED_TOOL_DEFINITIONS,\n CorpAPIClient,\n executeTool,\n type ToolContext,\n} from \"@thecorporation/corp-tools\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\n\n// ---------------------------------------------------------------------------\n// Build Zod schemas from JSON Schema properties\n// ---------------------------------------------------------------------------\n\ninterface ToolFunction {\n name: string;\n description: string;\n parameters: {\n type: string;\n properties: Record<string, { type: string; description?: string; enum?: string[]; items?: { type: string } }>;\n required: string[];\n };\n}\n\ninterface ToolDef {\n type: string;\n function: ToolFunction;\n}\n\nfunction buildZodShape(fn: ToolFunction): Record<string, z.ZodTypeAny> {\n const shape: Record<string, z.ZodTypeAny> = {};\n const props = fn.parameters.properties || {};\n const required = new Set(fn.parameters.required || []);\n\n for (const [pname, pinfo] of Object.entries(props)) {\n let schema: z.ZodTypeAny;\n switch (pinfo.type) {\n case \"integer\":\n schema = z.number().int();\n break;\n case \"number\":\n schema = z.number();\n break;\n case \"boolean\":\n schema = z.boolean();\n break;\n case \"array\":\n schema = z.array(pinfo.items?.type === \"object\" ? z.record(z.unknown()) : z.string());\n break;\n case \"object\":\n schema = z.record(z.unknown());\n break;\n default:\n schema = pinfo.enum ? z.enum(pinfo.enum as [string, ...string[]]) : z.string();\n }\n if (pinfo.description) schema = schema.describe(pinfo.description);\n if (!required.has(pname)) schema = schema.optional();\n shape[pname] = schema;\n }\n return shape;\n}\n\n// ---------------------------------------------------------------------------\n// Create and configure MCP server\n// ---------------------------------------------------------------------------\n\nexport function createMcpServer(client: CorpAPIClient): McpServer {\n const server = new McpServer({\n name: \"thecorporation\",\n version: \"0.1.0\",\n });\n\n const ctx: ToolContext = {\n dataDir: join(homedir(), \".corp\", \"data\"),\n };\n\n for (const td of GENERATED_TOOL_DEFINITIONS as unknown as ToolDef[]) {\n const fn = td.function;\n const shape = buildZodShape(fn);\n\n server.tool(fn.name, fn.description, shape, async (args) => {\n const result = await executeTool(fn.name, args as Record<string, unknown>, client, ctx);\n return { content: [{ type: \"text\" as const, text: result }] };\n });\n }\n\n return server;\n}\n","/**\n * MCP server authentication — shared config with CLI.\n *\n * Resolution order:\n * 1. CORP_API_KEY + CORP_WORKSPACE_ID env vars (explicit)\n * 2. ~/.corp/config.json (shared with CLI — run `corp setup` first)\n *\n * MCP servers run over stdio, so interactive auth (magic link) is not\n * possible here. Users authenticate once via `corp setup` (which does\n * the magic link flow for cloud) and the MCP server reuses those\n * credentials from the shared config file.\n */\n\nimport { readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\n\nexport interface McpAuthContext {\n workspaceId: string;\n apiKey: string;\n scopes: string[];\n}\n\nconst CONFIG_FILE = join(homedir(), \".corp\", \"config.json\");\n\nfunction loadConfig(): Record<string, string> {\n try {\n return JSON.parse(readFileSync(CONFIG_FILE, \"utf-8\"));\n } catch {\n return {};\n }\n}\n\nexport async function resolveOrProvisionAuth(\n apiUrl: string = \"https://api.thecorporation.ai\",\n): Promise<McpAuthContext> {\n // 1. Env vars (set in claude_desktop_config.json or similar)\n const envKey = process.env.CORP_API_KEY || \"\";\n const envWs = process.env.CORP_WORKSPACE_ID || \"\";\n if (envKey && envWs) {\n return { workspaceId: envWs, apiKey: envKey, scopes: [\"*\"] };\n }\n\n // 2. Shared config from CLI (run `corp setup` to authenticate)\n const cfg = loadConfig();\n if (cfg.api_key && cfg.workspace_id) {\n return { workspaceId: cfg.workspace_id, apiKey: cfg.api_key, scopes: [\"*\"] };\n }\n\n // No credentials found — guide user to authenticate via CLI\n throw new Error(\n \"No credentials found. Run `npx @thecorporation/cli setup` to authenticate, \" +\n \"or set CORP_API_KEY and CORP_WORKSPACE_ID environment variables.\"\n );\n}\n"],"mappings":"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","names":["CorpAPIClient","join","homedir","CorpAPIClient"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thecorporation/mcp-server",
|
|
3
|
-
"version": "26.3.
|
|
3
|
+
"version": "26.3.11",
|
|
4
4
|
"description": "MCP server for agent-native corporate operations",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
15
|
"@modelcontextprotocol/sdk": "^1.12.0",
|
|
16
|
-
"@thecorporation/corp-tools": "26.3.
|
|
16
|
+
"@thecorporation/corp-tools": "26.3.11",
|
|
17
17
|
"zod": "^3.24.0"
|
|
18
18
|
},
|
|
19
19
|
"devDependencies": {
|
package/src/auth.ts
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* MCP server authentication —
|
|
2
|
+
* MCP server authentication — shared config with CLI.
|
|
3
3
|
*
|
|
4
4
|
* Resolution order:
|
|
5
5
|
* 1. CORP_API_KEY + CORP_WORKSPACE_ID env vars (explicit)
|
|
6
|
-
* 2. ~/.corp/config.json (shared with
|
|
7
|
-
*
|
|
6
|
+
* 2. ~/.corp/config.json (shared with CLI — run `corp setup` first)
|
|
7
|
+
*
|
|
8
|
+
* MCP servers run over stdio, so interactive auth (magic link) is not
|
|
9
|
+
* possible here. Users authenticate once via `corp setup` (which does
|
|
10
|
+
* the magic link flow for cloud) and the MCP server reuses those
|
|
11
|
+
* credentials from the shared config file.
|
|
8
12
|
*/
|
|
9
13
|
|
|
10
|
-
import { readFileSync
|
|
14
|
+
import { readFileSync } from "node:fs";
|
|
11
15
|
import { join } from "node:path";
|
|
12
16
|
import { homedir } from "node:os";
|
|
13
17
|
|
|
@@ -27,45 +31,25 @@ function loadConfig(): Record<string, string> {
|
|
|
27
31
|
}
|
|
28
32
|
}
|
|
29
33
|
|
|
30
|
-
function saveConfig(cfg: Record<string, string>): void {
|
|
31
|
-
const dir = join(homedir(), ".corp");
|
|
32
|
-
mkdirSync(dir, { recursive: true });
|
|
33
|
-
writeFileSync(CONFIG_FILE, JSON.stringify(cfg, null, 2) + "\n");
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
async function provision(apiUrl: string): Promise<Record<string, string>> {
|
|
37
|
-
const resp = await fetch(`${apiUrl.replace(/\/+$/, "")}/v1/workspaces/provision`, {
|
|
38
|
-
method: "POST",
|
|
39
|
-
headers: { "Content-Type": "application/json" },
|
|
40
|
-
body: JSON.stringify({ name: "mcp-auto" }),
|
|
41
|
-
signal: AbortSignal.timeout(15_000),
|
|
42
|
-
});
|
|
43
|
-
if (!resp.ok) throw new Error(`Provision failed: ${resp.status}`);
|
|
44
|
-
return await resp.json() as Record<string, string>;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
34
|
export async function resolveOrProvisionAuth(
|
|
48
35
|
apiUrl: string = "https://api.thecorporation.ai",
|
|
49
36
|
): Promise<McpAuthContext> {
|
|
50
|
-
// 1. Env vars
|
|
37
|
+
// 1. Env vars (set in claude_desktop_config.json or similar)
|
|
51
38
|
const envKey = process.env.CORP_API_KEY || "";
|
|
52
39
|
const envWs = process.env.CORP_WORKSPACE_ID || "";
|
|
53
40
|
if (envKey && envWs) {
|
|
54
41
|
return { workspaceId: envWs, apiKey: envKey, scopes: ["*"] };
|
|
55
42
|
}
|
|
56
43
|
|
|
57
|
-
// 2.
|
|
44
|
+
// 2. Shared config from CLI (run `corp setup` to authenticate)
|
|
58
45
|
const cfg = loadConfig();
|
|
59
46
|
if (cfg.api_key && cfg.workspace_id) {
|
|
60
47
|
return { workspaceId: cfg.workspace_id, apiKey: cfg.api_key, scopes: ["*"] };
|
|
61
48
|
}
|
|
62
49
|
|
|
63
|
-
//
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
saveConfig(cfg);
|
|
69
|
-
|
|
70
|
-
return { workspaceId: result.workspace_id, apiKey: result.api_key, scopes: ["*"] };
|
|
50
|
+
// No credentials found — guide user to authenticate via CLI
|
|
51
|
+
throw new Error(
|
|
52
|
+
"No credentials found. Run `npx @thecorporation/cli setup` to authenticate, " +
|
|
53
|
+
"or set CORP_API_KEY and CORP_WORKSPACE_ID environment variables."
|
|
54
|
+
);
|
|
71
55
|
}
|