@civic/x402-mcp 0.0.1

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.
Files changed (154) hide show
  1. package/.claude/settings.local.json +26 -0
  2. package/.env.example +10 -0
  3. package/.github/workflows/ci.yml +144 -0
  4. package/.github/workflows/release.yml +56 -0
  5. package/.idea/modules.xml +8 -0
  6. package/.idea/vcs.xml +6 -0
  7. package/.idea/x402-mcp-example.iml +13 -0
  8. package/CLAUDE.md +31 -0
  9. package/DEVELOPER.md +181 -0
  10. package/README.md +274 -0
  11. package/biome.json +63 -0
  12. package/dist/example/client/client.d.ts +3 -0
  13. package/dist/example/client/client.d.ts.map +1 -0
  14. package/dist/example/client/client.js +93 -0
  15. package/dist/example/client/client.js.map +1 -0
  16. package/dist/example/client.d.ts +3 -0
  17. package/dist/example/client.d.ts.map +1 -0
  18. package/dist/example/client.js +105 -0
  19. package/dist/example/client.js.map +1 -0
  20. package/dist/example/config.d.ts +15 -0
  21. package/dist/example/config.d.ts.map +1 -0
  22. package/dist/example/config.js +20 -0
  23. package/dist/example/config.js.map +1 -0
  24. package/dist/example/proxy/client-proxy.d.ts +3 -0
  25. package/dist/example/proxy/client-proxy.d.ts.map +1 -0
  26. package/dist/example/proxy/client-proxy.js +88 -0
  27. package/dist/example/proxy/client-proxy.js.map +1 -0
  28. package/dist/example/proxy/client.d.ts +3 -0
  29. package/dist/example/proxy/client.d.ts.map +1 -0
  30. package/dist/example/proxy/client.js +97 -0
  31. package/dist/example/proxy/client.js.map +1 -0
  32. package/dist/example/proxy/server-proxy.d.ts +3 -0
  33. package/dist/example/proxy/server-proxy.d.ts.map +1 -0
  34. package/dist/example/proxy/server-proxy.js +72 -0
  35. package/dist/example/proxy/server-proxy.js.map +1 -0
  36. package/dist/example/server.d.ts +2 -0
  37. package/dist/example/server.d.ts.map +1 -0
  38. package/dist/example/server.js +76 -0
  39. package/dist/example/server.js.map +1 -0
  40. package/dist/example/service.d.ts +4 -0
  41. package/dist/example/service.d.ts.map +1 -0
  42. package/dist/example/service.js +15 -0
  43. package/dist/example/service.js.map +1 -0
  44. package/dist/scripts/analyzePayment.d.ts +3 -0
  45. package/dist/scripts/analyzePayment.d.ts.map +1 -0
  46. package/dist/scripts/analyzePayment.js +25 -0
  47. package/dist/scripts/analyzePayment.js.map +1 -0
  48. package/dist/scripts/client-proxy.d.ts +3 -0
  49. package/dist/scripts/client-proxy.d.ts.map +1 -0
  50. package/dist/scripts/client-proxy.js +126 -0
  51. package/dist/scripts/client-proxy.js.map +1 -0
  52. package/dist/scripts/generateWallet.d.ts +3 -0
  53. package/dist/scripts/generateWallet.d.ts.map +1 -0
  54. package/dist/scripts/generateWallet.js +15 -0
  55. package/dist/scripts/generateWallet.js.map +1 -0
  56. package/dist/src/client.d.ts +11 -0
  57. package/dist/src/client.d.ts.map +1 -0
  58. package/dist/src/client.js +52 -0
  59. package/dist/src/client.js.map +1 -0
  60. package/dist/src/client.test.d.ts +2 -0
  61. package/dist/src/client.test.d.ts.map +1 -0
  62. package/dist/src/client.test.js +178 -0
  63. package/dist/src/client.test.js.map +1 -0
  64. package/dist/src/index.d.ts +4 -0
  65. package/dist/src/index.d.ts.map +1 -0
  66. package/dist/src/index.js +7 -0
  67. package/dist/src/index.js.map +1 -0
  68. package/dist/src/index.test.d.ts +2 -0
  69. package/dist/src/index.test.d.ts.map +1 -0
  70. package/dist/src/index.test.js +27 -0
  71. package/dist/src/index.test.js.map +1 -0
  72. package/dist/src/mcpClientWithX402.d.ts +14 -0
  73. package/dist/src/mcpClientWithX402.d.ts.map +1 -0
  74. package/dist/src/mcpClientWithX402.js +78 -0
  75. package/dist/src/mcpClientWithX402.js.map +1 -0
  76. package/dist/src/proxy/client.d.ts +23 -0
  77. package/dist/src/proxy/client.d.ts.map +1 -0
  78. package/dist/src/proxy/client.js +39 -0
  79. package/dist/src/proxy/client.js.map +1 -0
  80. package/dist/src/proxy/client.test.d.ts +2 -0
  81. package/dist/src/proxy/client.test.d.ts.map +1 -0
  82. package/dist/src/proxy/client.test.js +167 -0
  83. package/dist/src/proxy/client.test.js.map +1 -0
  84. package/dist/src/proxy/hooks/apiKeyHook.d.ts +22 -0
  85. package/dist/src/proxy/hooks/apiKeyHook.d.ts.map +1 -0
  86. package/dist/src/proxy/hooks/apiKeyHook.js +72 -0
  87. package/dist/src/proxy/hooks/apiKeyHook.js.map +1 -0
  88. package/dist/src/proxy/hooks/apiKeyHook.test.d.ts +2 -0
  89. package/dist/src/proxy/hooks/apiKeyHook.test.d.ts.map +1 -0
  90. package/dist/src/proxy/hooks/apiKeyHook.test.js +240 -0
  91. package/dist/src/proxy/hooks/apiKeyHook.test.js.map +1 -0
  92. package/dist/src/proxy/index.d.ts +4 -0
  93. package/dist/src/proxy/index.d.ts.map +1 -0
  94. package/dist/src/proxy/index.js +4 -0
  95. package/dist/src/proxy/index.js.map +1 -0
  96. package/dist/src/proxy/server.d.ts +18 -0
  97. package/dist/src/proxy/server.d.ts.map +1 -0
  98. package/dist/src/proxy/server.js +35 -0
  99. package/dist/src/proxy/server.js.map +1 -0
  100. package/dist/src/proxy/server.test.d.ts +2 -0
  101. package/dist/src/proxy/server.test.d.ts.map +1 -0
  102. package/dist/src/proxy/server.test.js +26 -0
  103. package/dist/src/proxy/server.test.js.map +1 -0
  104. package/dist/src/server.d.ts +56 -0
  105. package/dist/src/server.d.ts.map +1 -0
  106. package/dist/src/server.js +320 -0
  107. package/dist/src/server.js.map +1 -0
  108. package/dist/src/server.test.d.ts +2 -0
  109. package/dist/src/server.test.d.ts.map +1 -0
  110. package/dist/src/server.test.js +666 -0
  111. package/dist/src/server.test.js.map +1 -0
  112. package/dist/src/util.d.ts +24 -0
  113. package/dist/src/util.d.ts.map +1 -0
  114. package/dist/src/util.js +47 -0
  115. package/dist/src/util.js.map +1 -0
  116. package/dist/src/util.test.d.ts +2 -0
  117. package/dist/src/util.test.d.ts.map +1 -0
  118. package/dist/src/util.test.js +71 -0
  119. package/dist/src/util.test.js.map +1 -0
  120. package/dist/src/x402Transport.d.ts +45 -0
  121. package/dist/src/x402Transport.d.ts.map +1 -0
  122. package/dist/src/x402Transport.js +288 -0
  123. package/dist/src/x402Transport.js.map +1 -0
  124. package/example/client.ts +125 -0
  125. package/example/config.ts +25 -0
  126. package/example/proxy/README.md +95 -0
  127. package/example/proxy/client-proxy.ts +102 -0
  128. package/example/proxy/client.ts +112 -0
  129. package/example/proxy/server-proxy.ts +80 -0
  130. package/example/server.ts +104 -0
  131. package/example/service.ts +19 -0
  132. package/example-client-proxy.sh +3 -0
  133. package/mcp-servers.json +9 -0
  134. package/package.json +53 -0
  135. package/scripts/analyzePayment.ts +25 -0
  136. package/scripts/client-proxy.ts +142 -0
  137. package/scripts/generateWallet.ts +17 -0
  138. package/src/client.test.ts +237 -0
  139. package/src/client.ts +61 -0
  140. package/src/index.test.ts +34 -0
  141. package/src/index.ts +7 -0
  142. package/src/proxy/client.test.ts +199 -0
  143. package/src/proxy/client.ts +61 -0
  144. package/src/proxy/hooks/apiKeyHook.test.ts +276 -0
  145. package/src/proxy/hooks/apiKeyHook.ts +77 -0
  146. package/src/proxy/index.ts +3 -0
  147. package/src/proxy/server.test.ts +33 -0
  148. package/src/proxy/server.ts +43 -0
  149. package/src/server.test.ts +822 -0
  150. package/src/server.ts +451 -0
  151. package/src/util.test.ts +83 -0
  152. package/src/util.ts +48 -0
  153. package/tsconfig.json +20 -0
  154. package/vitest.config.ts +26 -0
@@ -0,0 +1,167 @@
1
+ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
2
+ import { createClientProxy } from './client.js';
3
+ import { makePaymentAwareClientTransport } from '../client.js';
4
+ // Mock dependencies
5
+ vi.mock('@civic/passthrough-mcp-server', () => ({
6
+ createHttpPassthroughProxy: vi.fn(),
7
+ createStdioPassthroughProxy: vi.fn(),
8
+ }));
9
+ vi.mock('../client.js', () => ({
10
+ makePaymentAwareClientTransport: vi.fn(),
11
+ }));
12
+ describe('createClientProxy', () => {
13
+ let mockWallet;
14
+ let mockHttpProxy;
15
+ let mockStdioProxy;
16
+ let mockTransport;
17
+ beforeEach(async () => {
18
+ vi.clearAllMocks();
19
+ mockWallet = {
20
+ account: { address: '0xabc' },
21
+ chain: { id: 1 },
22
+ };
23
+ mockHttpProxy = {
24
+ start: vi.fn().mockResolvedValue(undefined),
25
+ stop: vi.fn().mockResolvedValue(undefined),
26
+ };
27
+ mockStdioProxy = {
28
+ start: vi.fn().mockResolvedValue(undefined),
29
+ stop: vi.fn().mockResolvedValue(undefined),
30
+ };
31
+ mockTransport = {
32
+ send: vi.fn(),
33
+ receive: vi.fn(),
34
+ };
35
+ vi.mocked(makePaymentAwareClientTransport).mockReturnValue(mockTransport);
36
+ const { createHttpPassthroughProxy, createStdioPassthroughProxy } = vi.mocked(await import('@civic/passthrough-mcp-server'));
37
+ createHttpPassthroughProxy.mockResolvedValue(mockHttpProxy);
38
+ createStdioPassthroughProxy.mockResolvedValue(mockStdioProxy);
39
+ });
40
+ afterEach(() => {
41
+ vi.restoreAllMocks();
42
+ });
43
+ describe('HTTP mode', () => {
44
+ it('should create an HTTP proxy with default port', async () => {
45
+ const targetUrl = 'http://example.com/mcp';
46
+ const proxy = await createClientProxy({
47
+ targetUrl,
48
+ wallet: mockWallet,
49
+ mode: 'http',
50
+ });
51
+ expect(makePaymentAwareClientTransport).toHaveBeenCalledWith(targetUrl, mockWallet);
52
+ const { createHttpPassthroughProxy } = vi.mocked(await import('@civic/passthrough-mcp-server'));
53
+ expect(createHttpPassthroughProxy).toHaveBeenCalledWith({
54
+ port: 4000,
55
+ target: {
56
+ transportType: 'custom',
57
+ transportFactory: expect.any(Function),
58
+ },
59
+ });
60
+ expect(proxy).toBe(mockHttpProxy);
61
+ });
62
+ it('should create an HTTP proxy with custom port', async () => {
63
+ const targetUrl = 'http://example.com/mcp';
64
+ const customPort = 5555;
65
+ const proxy = await createClientProxy({
66
+ targetUrl,
67
+ wallet: mockWallet,
68
+ mode: 'http',
69
+ port: customPort,
70
+ });
71
+ const { createHttpPassthroughProxy } = vi.mocked(await import('@civic/passthrough-mcp-server'));
72
+ expect(createHttpPassthroughProxy).toHaveBeenCalledWith({
73
+ port: customPort,
74
+ target: {
75
+ transportType: 'custom',
76
+ transportFactory: expect.any(Function),
77
+ },
78
+ });
79
+ expect(proxy).toBe(mockHttpProxy);
80
+ });
81
+ it('should use the transport factory correctly', async () => {
82
+ const targetUrl = 'http://example.com/mcp';
83
+ await createClientProxy({
84
+ targetUrl,
85
+ wallet: mockWallet,
86
+ mode: 'http',
87
+ });
88
+ const { createHttpPassthroughProxy } = vi.mocked(await import('@civic/passthrough-mcp-server'));
89
+ const callArgs = createHttpPassthroughProxy.mock.calls[0][0];
90
+ // Check that target is configured with custom transport
91
+ expect(callArgs.target.transportType).toBe('custom');
92
+ // Test that the factory returns the payment-aware transport
93
+ if (callArgs.target.transportType === 'custom' && 'transportFactory' in callArgs.target) {
94
+ const transport = callArgs.target.transportFactory();
95
+ expect(transport).toBe(mockTransport);
96
+ }
97
+ });
98
+ });
99
+ describe('stdio mode', () => {
100
+ it('should create a stdio proxy', async () => {
101
+ const targetUrl = 'http://example.com/mcp';
102
+ const proxy = await createClientProxy({
103
+ targetUrl,
104
+ wallet: mockWallet,
105
+ mode: 'stdio',
106
+ });
107
+ expect(makePaymentAwareClientTransport).toHaveBeenCalledWith(targetUrl, mockWallet);
108
+ const { createStdioPassthroughProxy } = vi.mocked(await import('@civic/passthrough-mcp-server'));
109
+ expect(createStdioPassthroughProxy).toHaveBeenCalledWith({
110
+ target: {
111
+ transportType: 'custom',
112
+ transportFactory: expect.any(Function),
113
+ },
114
+ });
115
+ expect(proxy).toBe(mockStdioProxy);
116
+ });
117
+ it('should use the transport factory correctly in stdio mode', async () => {
118
+ const targetUrl = 'http://example.com/mcp';
119
+ await createClientProxy({
120
+ targetUrl,
121
+ wallet: mockWallet,
122
+ mode: 'stdio',
123
+ });
124
+ const { createStdioPassthroughProxy } = vi.mocked(await import('@civic/passthrough-mcp-server'));
125
+ const callArgs = createStdioPassthroughProxy.mock.calls[0][0];
126
+ // Check that target is configured with custom transport
127
+ expect(callArgs.target.transportType).toBe('custom');
128
+ // Test that the factory returns the payment-aware transport
129
+ if (callArgs.target.transportType === 'custom' && 'transportFactory' in callArgs.target) {
130
+ const transport = callArgs.target.transportFactory();
131
+ expect(transport).toBe(mockTransport);
132
+ }
133
+ });
134
+ });
135
+ describe('transport integration', () => {
136
+ it('should pass wallet to payment-aware transport', async () => {
137
+ const targetUrl = 'https://secure.example.com/mcp';
138
+ const wallet = {
139
+ account: { address: '0x123456' },
140
+ chain: { id: 8453 },
141
+ };
142
+ await createClientProxy({
143
+ targetUrl,
144
+ wallet,
145
+ mode: 'http',
146
+ });
147
+ expect(makePaymentAwareClientTransport).toHaveBeenCalledWith(targetUrl, wallet);
148
+ });
149
+ it('should handle different URL formats', async () => {
150
+ const urls = [
151
+ 'http://localhost:3000/mcp',
152
+ 'https://api.example.com/v1/mcp',
153
+ 'http://192.168.1.1:8080',
154
+ ];
155
+ for (const url of urls) {
156
+ vi.clearAllMocks();
157
+ await createClientProxy({
158
+ targetUrl: url,
159
+ wallet: mockWallet,
160
+ mode: 'stdio',
161
+ });
162
+ expect(makePaymentAwareClientTransport).toHaveBeenCalledWith(url, mockWallet);
163
+ }
164
+ });
165
+ });
166
+ });
167
+ //# sourceMappingURL=client.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.test.js","sourceRoot":"","sources":["../../../src/proxy/client.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import { AbstractHook } from '@civic/passthrough-mcp-server';
2
+ /**
3
+ * Hook that adds an API key to outgoing requests to authenticate with upstream MCP servers
4
+ */
5
+ export declare class ApiKeyHook extends AbstractHook {
6
+ private apiKey;
7
+ constructor(apiKey: string);
8
+ get name(): string;
9
+ /**
10
+ * Add API key to tool call requests
11
+ */
12
+ processToolCallRequest(request: any): Promise<any>;
13
+ /**
14
+ * Add API key to tools list requests
15
+ */
16
+ processToolsListRequest(request: any): Promise<any>;
17
+ /**
18
+ * Add API key to initialize requests
19
+ */
20
+ processInitializeRequest(request: any): Promise<any>;
21
+ }
22
+ //# sourceMappingURL=apiKeyHook.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apiKeyHook.d.ts","sourceRoot":"","sources":["../../../../src/proxy/hooks/apiKeyHook.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAE7D;;GAEG;AACH,qBAAa,UAAW,SAAQ,YAAY;IAC9B,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,MAAM;IAIlC,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED;;OAEG;IACG,sBAAsB,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;IAkBxD;;OAEG;IACG,uBAAuB,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;IAkBzD;;OAEG;IACG,wBAAwB,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;CAiB3D"}
@@ -0,0 +1,72 @@
1
+ import { AbstractHook } from '@civic/passthrough-mcp-server';
2
+ /**
3
+ * Hook that adds an API key to outgoing requests to authenticate with upstream MCP servers
4
+ */
5
+ export class ApiKeyHook extends AbstractHook {
6
+ apiKey;
7
+ constructor(apiKey) {
8
+ super();
9
+ this.apiKey = apiKey;
10
+ }
11
+ get name() {
12
+ return 'api-key-injector';
13
+ }
14
+ /**
15
+ * Add API key to tool call requests
16
+ */
17
+ async processToolCallRequest(request) {
18
+ const modifiedRequest = {
19
+ ...request,
20
+ requestContext: {
21
+ ...request.requestContext,
22
+ headers: {
23
+ ...request.requestContext?.headers,
24
+ Authorization: `Bearer ${this.apiKey}`,
25
+ },
26
+ },
27
+ };
28
+ return {
29
+ resultType: 'continue',
30
+ request: modifiedRequest,
31
+ };
32
+ }
33
+ /**
34
+ * Add API key to tools list requests
35
+ */
36
+ async processToolsListRequest(request) {
37
+ const modifiedRequest = {
38
+ ...request,
39
+ requestContext: {
40
+ ...request.requestContext,
41
+ headers: {
42
+ ...request.requestContext?.headers,
43
+ Authorization: `Bearer ${this.apiKey}`,
44
+ },
45
+ },
46
+ };
47
+ return {
48
+ resultType: 'continue',
49
+ request: modifiedRequest,
50
+ };
51
+ }
52
+ /**
53
+ * Add API key to initialize requests
54
+ */
55
+ async processInitializeRequest(request) {
56
+ const modifiedRequest = {
57
+ ...request,
58
+ requestContext: {
59
+ ...request.requestContext,
60
+ headers: {
61
+ ...request.requestContext?.headers,
62
+ Authorization: `Bearer ${this.apiKey}`,
63
+ },
64
+ },
65
+ };
66
+ return {
67
+ resultType: 'continue',
68
+ request: modifiedRequest,
69
+ };
70
+ }
71
+ }
72
+ //# sourceMappingURL=apiKeyHook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apiKeyHook.js","sourceRoot":"","sources":["../../../../src/proxy/hooks/apiKeyHook.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAE7D;;GAEG;AACH,MAAM,OAAO,UAAW,SAAQ,YAAY;IACtB;IAApB,YAAoB,MAAc;QAChC,KAAK,EAAE,CAAC;QADU,WAAM,GAAN,MAAM,CAAQ;IAElC,CAAC;IAED,IAAI,IAAI;QACN,OAAO,kBAAkB,CAAC;IAC5B,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,sBAAsB,CAAC,OAAY;QACvC,MAAM,eAAe,GAAG;YACtB,GAAG,OAAO;YACV,cAAc,EAAE;gBACd,GAAG,OAAO,CAAC,cAAc;gBACzB,OAAO,EAAE;oBACP,GAAG,OAAO,CAAC,cAAc,EAAE,OAAO;oBAClC,aAAa,EAAE,UAAU,IAAI,CAAC,MAAM,EAAE;iBACvC;aACF;SACF,CAAC;QAEF,OAAO;YACL,UAAU,EAAE,UAAU;YACtB,OAAO,EAAE,eAAe;SACzB,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,uBAAuB,CAAC,OAAY;QACxC,MAAM,eAAe,GAAG;YACtB,GAAG,OAAO;YACV,cAAc,EAAE;gBACd,GAAG,OAAO,CAAC,cAAc;gBACzB,OAAO,EAAE;oBACP,GAAG,OAAO,CAAC,cAAc,EAAE,OAAO;oBAClC,aAAa,EAAE,UAAU,IAAI,CAAC,MAAM,EAAE;iBACvC;aACF;SACF,CAAC;QAEF,OAAO;YACL,UAAU,EAAE,UAAU;YACtB,OAAO,EAAE,eAAe;SACzB,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,wBAAwB,CAAC,OAAY;QACzC,MAAM,eAAe,GAAG;YACtB,GAAG,OAAO;YACV,cAAc,EAAE;gBACd,GAAG,OAAO,CAAC,cAAc;gBACzB,OAAO,EAAE;oBACP,GAAG,OAAO,CAAC,cAAc,EAAE,OAAO;oBAClC,aAAa,EAAE,UAAU,IAAI,CAAC,MAAM,EAAE;iBACvC;aACF;SACF,CAAC;QAEF,OAAO;YACL,UAAU,EAAE,UAAU;YACtB,OAAO,EAAE,eAAe;SACzB,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=apiKeyHook.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apiKeyHook.test.d.ts","sourceRoot":"","sources":["../../../../src/proxy/hooks/apiKeyHook.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,240 @@
1
+ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
2
+ import { ApiKeyHook } from './apiKeyHook.js';
3
+ describe('ApiKeyHook', () => {
4
+ let hook;
5
+ const testApiKey = 'sk-test-123456789';
6
+ beforeEach(() => {
7
+ hook = new ApiKeyHook(testApiKey);
8
+ });
9
+ afterEach(() => {
10
+ vi.clearAllMocks();
11
+ });
12
+ describe('constructor and name', () => {
13
+ it('should initialize with provided API key', () => {
14
+ expect(hook).toBeDefined();
15
+ expect(hook).toBeInstanceOf(ApiKeyHook);
16
+ });
17
+ it('should have correct name', () => {
18
+ expect(hook.name).toBe('api-key-injector');
19
+ });
20
+ });
21
+ describe('processToolCallRequest', () => {
22
+ it('should add Authorization header to request', async () => {
23
+ const request = {
24
+ jsonrpc: '2.0',
25
+ method: 'tools/call',
26
+ params: { name: 'test-tool' },
27
+ id: 1,
28
+ };
29
+ const result = await hook.processToolCallRequest(request);
30
+ expect(result).toEqual({
31
+ resultType: 'continue',
32
+ request: {
33
+ ...request,
34
+ requestContext: {
35
+ headers: {
36
+ Authorization: `Bearer ${testApiKey}`,
37
+ },
38
+ },
39
+ },
40
+ });
41
+ });
42
+ it('should preserve existing requestContext', async () => {
43
+ const request = {
44
+ jsonrpc: '2.0',
45
+ method: 'tools/call',
46
+ params: { name: 'test-tool' },
47
+ id: 1,
48
+ requestContext: {
49
+ existingField: 'value',
50
+ headers: {
51
+ 'X-Custom-Header': 'custom-value',
52
+ },
53
+ },
54
+ };
55
+ const result = await hook.processToolCallRequest(request);
56
+ expect(result).toEqual({
57
+ resultType: 'continue',
58
+ request: {
59
+ ...request,
60
+ requestContext: {
61
+ existingField: 'value',
62
+ headers: {
63
+ 'X-Custom-Header': 'custom-value',
64
+ Authorization: `Bearer ${testApiKey}`,
65
+ },
66
+ },
67
+ },
68
+ });
69
+ });
70
+ it('should override existing Authorization header', async () => {
71
+ const request = {
72
+ jsonrpc: '2.0',
73
+ method: 'tools/call',
74
+ params: {},
75
+ id: 3,
76
+ requestContext: {
77
+ headers: {
78
+ Authorization: 'Bearer old-key',
79
+ },
80
+ },
81
+ };
82
+ const result = await hook.processToolCallRequest(request);
83
+ expect(result.request.requestContext.headers.Authorization).toBe(`Bearer ${testApiKey}`);
84
+ });
85
+ it('should handle request without requestContext', async () => {
86
+ const request = {
87
+ jsonrpc: '2.0',
88
+ method: 'tools/call',
89
+ params: {},
90
+ id: 4,
91
+ };
92
+ const result = await hook.processToolCallRequest(request);
93
+ expect(result).toEqual({
94
+ resultType: 'continue',
95
+ request: {
96
+ ...request,
97
+ requestContext: {
98
+ headers: {
99
+ Authorization: `Bearer ${testApiKey}`,
100
+ },
101
+ },
102
+ },
103
+ });
104
+ });
105
+ });
106
+ describe('processToolsListRequest', () => {
107
+ it('should add Authorization header to tools list request', async () => {
108
+ const request = {
109
+ jsonrpc: '2.0',
110
+ method: 'tools/list',
111
+ params: {},
112
+ id: 1,
113
+ };
114
+ const result = await hook.processToolsListRequest(request);
115
+ expect(result).toEqual({
116
+ resultType: 'continue',
117
+ request: {
118
+ ...request,
119
+ requestContext: {
120
+ headers: {
121
+ Authorization: `Bearer ${testApiKey}`,
122
+ },
123
+ },
124
+ },
125
+ });
126
+ });
127
+ it('should preserve existing headers in tools list', async () => {
128
+ const request = {
129
+ jsonrpc: '2.0',
130
+ method: 'tools/list',
131
+ params: {},
132
+ id: 2,
133
+ requestContext: {
134
+ headers: {
135
+ 'Content-Type': 'application/json',
136
+ },
137
+ },
138
+ };
139
+ const result = await hook.processToolsListRequest(request);
140
+ expect(result.request.requestContext.headers).toEqual({
141
+ 'Content-Type': 'application/json',
142
+ Authorization: `Bearer ${testApiKey}`,
143
+ });
144
+ });
145
+ });
146
+ describe('processInitializeRequest', () => {
147
+ it('should add Authorization header to initialize request', async () => {
148
+ const request = {
149
+ jsonrpc: '2.0',
150
+ method: 'initialize',
151
+ params: {
152
+ clientInfo: {
153
+ name: 'test-client',
154
+ version: '1.0.0',
155
+ },
156
+ },
157
+ id: 1,
158
+ };
159
+ const result = await hook.processInitializeRequest(request);
160
+ expect(result).toEqual({
161
+ resultType: 'continue',
162
+ request: {
163
+ ...request,
164
+ requestContext: {
165
+ headers: {
166
+ Authorization: `Bearer ${testApiKey}`,
167
+ },
168
+ },
169
+ },
170
+ });
171
+ });
172
+ it('should preserve existing requestContext in initialize', async () => {
173
+ const request = {
174
+ jsonrpc: '2.0',
175
+ method: 'initialize',
176
+ params: {},
177
+ id: 2,
178
+ requestContext: {
179
+ sessionId: 'session-123',
180
+ headers: {
181
+ 'User-Agent': 'TestClient/1.0',
182
+ },
183
+ },
184
+ };
185
+ const result = await hook.processInitializeRequest(request);
186
+ expect(result).toEqual({
187
+ resultType: 'continue',
188
+ request: {
189
+ ...request,
190
+ requestContext: {
191
+ sessionId: 'session-123',
192
+ headers: {
193
+ 'User-Agent': 'TestClient/1.0',
194
+ Authorization: `Bearer ${testApiKey}`,
195
+ },
196
+ },
197
+ },
198
+ });
199
+ });
200
+ });
201
+ describe('different API key formats', () => {
202
+ it('should work with various API key formats', async () => {
203
+ const apiKeys = [
204
+ 'simple-key',
205
+ 'sk-proj-very-long-api-key-with-many-characters',
206
+ 'Bearer existing-token',
207
+ 'ApiKey 12345',
208
+ ];
209
+ for (const apiKey of apiKeys) {
210
+ const customHook = new ApiKeyHook(apiKey);
211
+ const request = {
212
+ jsonrpc: '2.0',
213
+ method: 'tools/call',
214
+ params: {},
215
+ id: 1,
216
+ };
217
+ const result = await customHook.processToolCallRequest(request);
218
+ expect(result.request.requestContext.headers.Authorization).toBe(`Bearer ${apiKey}`);
219
+ }
220
+ });
221
+ });
222
+ describe('all methods add the same header', () => {
223
+ it('should add consistent headers across all methods', async () => {
224
+ const request = {
225
+ jsonrpc: '2.0',
226
+ method: 'test',
227
+ params: {},
228
+ id: 1,
229
+ };
230
+ const toolCallResult = await hook.processToolCallRequest(request);
231
+ const toolsListResult = await hook.processToolsListRequest(request);
232
+ const initializeResult = await hook.processInitializeRequest(request);
233
+ const expectedHeader = `Bearer ${testApiKey}`;
234
+ expect(toolCallResult.request.requestContext.headers.Authorization).toBe(expectedHeader);
235
+ expect(toolsListResult.request.requestContext.headers.Authorization).toBe(expectedHeader);
236
+ expect(initializeResult.request.requestContext.headers.Authorization).toBe(expectedHeader);
237
+ });
238
+ });
239
+ });
240
+ //# sourceMappingURL=apiKeyHook.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apiKeyHook.test.js","sourceRoot":"","sources":["../../../../src/proxy/hooks/apiKeyHook.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export { createClientProxy } from './client.js';
2
+ export { ApiKeyHook } from './hooks/apiKeyHook.js';
3
+ export { createServerProxy } from './server.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/proxy/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { createClientProxy } from './client.js';
2
+ export { ApiKeyHook } from './hooks/apiKeyHook.js';
3
+ export { createServerProxy } from './server.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/proxy/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,18 @@
1
+ import { type PassthroughProxy } from '@civic/passthrough-mcp-server';
2
+ import type { Address } from 'viem';
3
+ /**
4
+ * Creates a server-side proxy that:
5
+ * 1. Accepts x402 payments from clients
6
+ * 2. Adds an API key to authenticate with the upstream MCP server
7
+ *
8
+ * This allows monetizing access to API-key-protected MCP servers via micropayments.
9
+ *
10
+ * @param upstreamUrl - The URL of the API-key-protected MCP server to proxy to
11
+ * @param apiKey - The API key to authenticate with the upstream server
12
+ * @param paymentWallet - The wallet address to receive payments
13
+ * @param toolPricing - Mapping of tool names to prices (e.g., { "my-tool": "$0.01" })
14
+ * @param port - The port for the proxy to listen on (default: 5000)
15
+ * @returns The proxy instance
16
+ */
17
+ export declare function createServerProxy(upstreamUrl: string, apiKey: string, paymentWallet: Address | string, toolPricing: Record<string, string>, port?: number): Promise<PassthroughProxy>;
18
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/proxy/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuC,KAAK,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAC3G,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAKpC;;;;;;;;;;;;;GAaG;AACH,wBAAsB,iBAAiB,CACrC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,OAAO,GAAG,MAAM,EAC/B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACnC,IAAI,GAAE,MAAa,GAClB,OAAO,CAAC,gBAAgB,CAAC,CAkB3B"}
@@ -0,0 +1,35 @@
1
+ import { createPassthroughProxy } from '@civic/passthrough-mcp-server';
2
+ import { makePaymentAwareServerTransport } from '../server.js';
3
+ import { ApiKeyHook } from './hooks/apiKeyHook.js';
4
+ /**
5
+ * Creates a server-side proxy that:
6
+ * 1. Accepts x402 payments from clients
7
+ * 2. Adds an API key to authenticate with the upstream MCP server
8
+ *
9
+ * This allows monetizing access to API-key-protected MCP servers via micropayments.
10
+ *
11
+ * @param upstreamUrl - The URL of the API-key-protected MCP server to proxy to
12
+ * @param apiKey - The API key to authenticate with the upstream server
13
+ * @param paymentWallet - The wallet address to receive payments
14
+ * @param toolPricing - Mapping of tool names to prices (e.g., { "my-tool": "$0.01" })
15
+ * @param port - The port for the proxy to listen on (default: 5000)
16
+ * @returns The proxy instance
17
+ */
18
+ export async function createServerProxy(upstreamUrl, apiKey, paymentWallet, toolPricing, port = 5000) {
19
+ // Create the payment-aware server transport
20
+ const paymentAwareTransport = makePaymentAwareServerTransport(paymentWallet, toolPricing);
21
+ // Create the API key hook
22
+ const apiKeyHook = new ApiKeyHook(apiKey);
23
+ // Create and return the proxy
24
+ return createPassthroughProxy({
25
+ sourceTransportType: 'custom',
26
+ sourceTransport: paymentAwareTransport,
27
+ target: {
28
+ url: upstreamUrl,
29
+ transportType: 'httpStream',
30
+ },
31
+ hooks: [apiKeyHook],
32
+ autoStart: true,
33
+ });
34
+ }
35
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/proxy/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,sBAAsB,EAAyB,MAAM,+BAA+B,CAAC;AAE3G,OAAO,EAAE,+BAA+B,EAAE,MAAM,cAAc,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAGnD;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,WAAmB,EACnB,MAAc,EACd,aAA+B,EAC/B,WAAmC,EACnC,OAAe,IAAI;IAEnB,4CAA4C;IAC5C,MAAM,qBAAqB,GAAG,+BAA+B,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC;IAE1F,0BAA0B;IAC1B,MAAM,UAAU,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;IAE1C,8BAA8B;IAC9B,OAAO,sBAAsB,CAAC;QAC5B,mBAAmB,EAAE,QAAQ;QAC7B,eAAe,EAAE,qBAAqB;QACtC,MAAM,EAAE;YACN,GAAG,EAAE,WAAW;YAChB,aAAa,EAAE,YAAY;SAC5B;QACD,KAAK,EAAE,CAAC,UAAU,CAAC;QACnB,SAAS,EAAE,IAAI;KAChB,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=server.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.test.d.ts","sourceRoot":"","sources":["../../../src/proxy/server.test.ts"],"names":[],"mappings":""}