Mọi nền tảng hiện đại đều cung cấp cho agent của bạn ba tùy chọn tích hợp giống nhau: một máy chủ MCP để đăng ký, một khóa API để lưu trữ và làm mới, hoặc một tệp kỹ năng để cài đặt nhằm dạy agent cách thực hiện hai tùy chọn đầu tiên. Một thứ để cấu hình. Một thứ để rò rỉ. Một thứ trở nên lỗi thời.
Oberik cung cấp cho agent của bạn quyền truy cập ssh để thay thế.
Không phải cho bạn, bạn đang đóng vai trò như một proxy trong ngữ cảnh này, nó thực sự cấp quyền truy cập SSH cho agent của bạn.
1 ssh ssh.oberik.com
SSH là bề mặt mà một coding agent sử dụng bất cứ khi nào nó cần tương tác với Oberik (ví dụ: tạo một workspace, đặt giới hạn khả năng của nó, tạo token, trò chuyện với agent mà chúng tôi lưu trữ, v.v.). Không có tệp cấu hình, không có token trong biến môi trường, không có gì phải cài đặt. Máy của bạn đã có sẵn client, và nó đã biết cách giữ thông tin xác thực duy nhất liên quan.
Tại sao không phải MCP?
Nói ngắn gọn, vấn đề đầu ra.
MCP đã trở thành tiêu chuẩn của ngành vì nó giải quyết một vấn đề thực tế. Bạn viết một công cụ một lần, và mọi agent đều có thể gọi nó theo cùng một cách. Chúng tôi không phản đối điều đó. Oberik tải các máy chủ MCP của riêng bạn trực tiếp vào agent mà chúng tôi lưu trữ, theo từng tenant, và đó là một cách tốt để agent vươn tới các công cụ. Chúng tôi đang nói về một hướng khác ở đây: cách mà một thứ gì đó cấu hình tài khoản ngay từ đầu.
Dù dễ sử dụng, MCP có một điểm yếu cốt lõi: khi một công cụ chạy, toàn bộ đầu ra được đẩy vào ngữ cảnh của mô hình. Mô hình phải đọc tất cả. Nó không thể quyết định "Tôi chỉ muốn trường thứ ba" vì vào thời điểm văn bản đến, việc lọc đã thất bại.
MCP hỗ trợ lọc và phân trang về mặt nguyên tắc. Trong thực tế, ai đó phải xây dựng điều đó vào mọi công cụ và khi nó bị thiếu, điều có thể xảy ra khá thường xuyên nhờ vibe coding, mô hình chỉ nuốt chửng payload thô và trả giá bằng token và sự chú ý.
Với SSH, agent tự tạo ra chế độ xem của riêng mình thay vì chấp nhận chế độ xem mà một công cụ đưa ra.
1$ ssh ssh.oberik.com 'documents --json' | jq -r '.data[].name'2$ ssh ssh.oberik.com 'audit --limit 20 --json' | jq -r '.data[] | "\(.at) \(.command)"'
Bộ lọc chạy trong một pipe trên máy. Tức thì, miễn phí, chính xác như những gì agent muốn. Mô hình đọc một dòng thay vì mười trang.
Có hai điều làm cho điều này hoạt động. Đầu tiên, mọi phản hồi đều sử dụng định dạng một dòng như {"ok":…, "command":…, "message":…, "data":…}. Điều đó làm cho jq trở thành cách đọc đầu ra dự định, không phải là một giải pháp thay thế.
Chế độ JSON cũng giữ cho tương tác không làm gián đoạn luồng của bạn. Nếu một lệnh thiếu một trường bắt buộc, nó sẽ cho bạn biết những gì còn thiếu thay vì mở một biểu mẫu. Nếu một lệnh có thể gây hại, nó sẽ yêu cầu bạn chạy lại với --yes thay vì dừng lại để yêu cầu xác nhận.
Đối với một dòng có nhiều lệnh, hãy đặt format json; ở đầu. Điều đó đặt định dạng một lần, vì vậy bạn không cần lặp lại cờ.
Có một chi tiết đáng biết. Cờ phải nằm trong dấu ngoặc kép. ssh ssh.oberik.com --json 'documents' không hoạt động vì ssh coi các tùy chọn sau đích đến là của riêng nó. Nó bỏ qua cờ, và client phản hồi bằng đầu ra sử dụng của chính nó. Vì đầu ra đó không đề cập đến Oberik hay cờ, nó có thể làm cho máy chủ trông như bị hỏng.
Điều chúng tôi muốn nói ở đây là, chúng tôi đã huấn luyện các mô hình này sử dụng máy tính, hãy để chúng sử dụng máy tính.

Tại sao không phải API?
Nói ngắn gọn, vấn đề thông tin xác thực.
Đừng hiểu lầm, chúng tôi có một API trong Oberik và nó rất tốt. Đó là thứ mà sản phẩm của bạn gọi trong quá trình sản xuất, và đó là thứ mà chính cổng SSH gọi bên dưới.
Nhưng nếu bạn nhìn vào những gì nó yêu cầu từ người gọi:
- lấy một token
- lưu trữ nó
- làm mới nó
- giữ nó khỏi nhật ký và khỏi ngữ cảnh của mô hình.
Mỗi bước trong số đó trở thành trách nhiệm của agent và ngữ cảnh của agent không phải là một nơi an toàn cho một bí mật. Bất kỳ ai đã từng thấy một mô hình lặp lại các biến môi trường của chính nó đều biết điều này. Ý tôi là nếu bạn chú ý, bạn sẽ nhận ra coding agent yêu thích của bạn hành động như thể nó nhắm mắt làm ngơ theo mặc định khi nó cảm thấy một khóa nhạy cảm trong prompt của bạn. Tuy nhiên, một khóa được dán vào agent không chỉ nằm trong lịch sử shell; nó cũng đi đến nhà cung cấp mô hình, vào nhật ký, vào bất kỳ bản ghi nào mà harness giữ.
API có ở đó, nhưng nó không phải là con đường chính mà chúng tôi thiết kế để các agent tự thiết lập trên đó. Qua SSH, agent giữ một loại thông tin xác thực duy nhất mà hệ điều hành của bạn đã được xây dựng để bảo vệ, một khóa SSH, và nửa riêng tư không bao giờ được truyền đi. Xác thực với Oberik không đặt bất cứ thứ gì bí mật vào ngữ cảnh của mô hình, bởi vì không có gì để đặt ở đó.
Tại sao không phải CLI?
Nói ngắn gọn, vấn đề lỗi thời.
Cài đặt một CLI là một cam kết yêu cầu từ mọi harness của người tích hợp và chúng tôi không muốn trở nên táo bạo như vậy khi chúng tôi chỉ mới bắt đầu những bước đầu tiên. Thành thật mà nói, chúng tôi hoàn toàn không muốn một CLI vì về cơ bản nó là một bản sao đông lạnh của sản phẩm. Mặt phẳng điều khiển của Oberik sẽ phát triển một tính năng khi chúng tôi nhận được nhiều phản hồi hơn, điều đó có nghĩa là nếu chúng tôi chọn CLI, chúng tôi sẽ liên tục phải phát hành bản cập nhật mới và yêu cầu người dùng cập nhật.
Về cơ bản, chúng tôi đã giải quyết vấn đề đó vì bề mặt SSH của chúng tôi được tạo ra, không phải được viết. Mọi route trong mặt phẳng điều khiển của chúng tôi đều đăng ký cùng với mô tả của nó và mô tả đó là lệnh SSH. Một route được thêm vào bảng điều khiển sẽ xuất hiện ngay lập tức qua SSH, vì vậy chúng tôi không cần lo lắng về việc thay đổi cổng.
Không có gì để cập nhật, bởi vì không có gì được cài đặt.
Tại sao không phải một kỹ năng?
Nói ngắn gọn, vấn đề hướng dẫn.
Cách tiếp cận thịnh hành để vận chuyển cùng với bất kỳ sản phẩm hướng đến agent nào là kỹ năng. Một quy trình bằng văn bản mà agent của bạn cài đặt, hướng dẫn nó cách gọi sản phẩm. Kỹ năng thực sự hữu ích, nhưng về cơ bản nó là một tệp README ưa thích. Một kỹ năng là tài liệu, không phải là một khả năng. Nó không cung cấp cho agent của bạn một cách để hành động; nó vẫn cần MCP hoặc API bên dưới để làm bất cứ điều gì, và bạn cũng thừa hưởng vấn đề đó.
Trên hết, một kỹ năng là một bản sao đông lạnh của cách sử dụng một sản phẩm đang thay đổi. Cùng một sự lỗi thời như CLI. Nó nằm trong ngữ cảnh của agent trước khi agent làm bất cứ điều gì, tiêu tốn sự chú ý và token vào các hướng dẫn mà bề mặt có thể chỉ in ra khi được yêu cầu.
Câu trả lời của chúng tôi cho "làm thế nào agent biết Oberik có thể làm gì" không phải là một tệp mà nó cài đặt. Đó là một lệnh gọi để khám phá cho agent:
1$ ssh ssh.oberik.com 'discover' # mọi lệnh, tham số của nó và loại của chúng2$ ssh ssh.oberik.com 'docs' # mọi trang, với nội dung bao gồm3$ ssh ssh.oberik.com 'docs search capability' # các dòng đề cập đến một cái gì đó
Bề mặt tự mô tả chính nó, tại thời điểm kết nối, từ sản phẩm trực tiếp. Và docs là cùng một văn bản với trang web tài liệu, vì vậy không có gì là bản tóm tắt của một thứ khác. Các hướng dẫn không bao giờ có thể trở nên lỗi thời, bởi vì chúng là sản phẩm.
Tại sao lại là SSH?
Nói ngắn gọn, nó giải quyết tất cả năm vấn đề cùng một lúc.
- Khóa là thông tin xác thực mà agent thực sự có thể giữ. Xác thực khóa SSH đã hàng thập kỷ tuổi, đã được thử nghiệm hàng tỷ lần và giao thức xác minh chữ ký trước khi chúng tôi xem xét dấu vân tay. Chúng tôi không cảm thấy cần phải phát minh lại bánh xe ở đây. Chúng tôi chỉ ngừng yêu cầu mô hình trông nom một bí mật và để máy làm công việc duy nhất mà nó luôn được xây dựng để làm.
- Bạn vẫn nằm trong vòng lặp mà không cần chia sẻ mật khẩu. Khi agent chưa có khóa, chẳng hạn như trong lần kết nối đầu tiên với Oberik, nó sẽ bắt đầu một luồng đăng nhập thiết bị. Agent chạy
login link, lệnh này trả về ngay lập tức một URL và một mã và hiển thị cả hai cho bạn. Bạn mở URL trong trình duyệt của riêng mình. Trang xác định chính xác dấu vân tay khóa sẽ được đính kèm, cung cấp cho bạn các tùy chọn để chấp thuận hoặc từ chối và hiển thị một mã mà bạn có thể so sánh với mã được in bởi agent. Trong khi đó, agent chạylogin waitvà chờ quyết định của bạn. Đây là các lệnh riêng biệt theo thiết kế. Nếu một lệnh vừa tạo liên kết vừa chờ đợi, agent sẽ chỉ hiển thị liên kết cho bạn sau khi yêu cầu đã hết hạn. Khi bạn chấp thuận, khóa được đăng ký và tất cả các kết nối trong tương lai sẽ tự động được đăng nhập. Bạn sẽ không cần một liên kết khác. Không có bí mật nào được ghi vào lịch sử trò chuyện của agent vì quy trình không sử dụng một bí mật nào. - Đầu ra được thiết kế cho các pipe. Yêu cầu JSON với
--jsontrên một lệnh, hoặc sử dụngformat json;một lần ở đầu một dòng, và mọi phản hồi sẽ trả về dưới dạng một phong bì một dòng. Điều đó làm chojq '.data[0].name'trở thành cách đọc đầu ra dự định, không phải là một giải pháp thay thế. Bộ lọc chạy trên máy, vì vậy mô hình chỉ thấy những gì còn lại sau khi lọc. Lỗi sử dụng cùng một phong bì và bao gồm trạng thái HTTP cơ bản. Điều đó cho phép một lần thử lại phân biệt 429 với 400. Các pipe cũng hoạt động theo cả hai hướng. Cổng không thể đọc đĩa của bạn, vì vậy các lệnh chấp nhận tệp lấy tên tệp làm đối số và đọc nội dung của tệp từ kết nối. Ví dụ:ssh ssh.oberik.com 'document upload handbook.pdf' < handbook.pdftải tệp lên. - Không cần cài đặt. Không có gì để đăng ký, không có gì để lưu trữ, không có gì để giữ trong ngữ cảnh. Không có máy chủ MCP trong cấu hình agent của bạn, không có token trong biến môi trường, không có CLI trên PATH, không có tệp kỹ năng. Chúng tôi xây dựng một sản phẩm dành cho nhà phát triển, vì vậy chúng tôi đã sử dụng công cụ đã có sẵn và mọi agent đều biết cách sử dụng: SSH.
- Tự mô tả và cẩn thận theo thiết kế.
discoverin danh mục lệnh đầy đủ. Nó bao gồm mọi lệnh, tham số và loại của chúng, và bất kỳ yêu cầu xác nhận nào. Danh mục được tạo trực tiếp từ sản phẩm. Nó cũng cho client biết trường nào mong đợi byte tệp thay vì một chuỗi, vì vậy việc tải lên không thể bị đoán sai. Điều nó không cho phép là nhắm mục tiêu một hàng theo số của nó. Các lệnh có tính hủy diệt yêu cầu một tên, và máy chủ kiểm tra tên đó với dự án được chọn bởi kết nối. Nếu Staging được yêu cầu trong khi Support Bot được chọn, máy chủ trả về 400 và để workspace không bị ảnh hưởng.
Không có gì để dạy, bởi vì bề mặt tự dạy chính nó.
Đây là cách luồng đăng nhập Oberik trông như thế nào:

Luồng đăng nhập Oberik
Một cánh cửa SSH vào sản phẩm của bạn có phải là một rủi ro không?
Đó là một câu hỏi công bằng, nhưng thực tế gần như ngược lại.
Cổng không có trạng thái hoặc đặc quyền riêng. Mọi lệnh đều chạy qua một phiên mặt phẳng điều khiển HTTP, giống như trong ứng dụng React. Do đó, một client SSH không thể làm nhiều hơn những gì cùng một tài khoản có thể làm trong trình duyệt. Nếu bạn đăng xuất, thu hồi khóa hoặc xóa tài khoản, thay đổi sẽ có hiệu lực ngay lập tức vì không có gì khác để thu hồi.
Terminal này được tiếp xúc với internet công cộng, vì vậy bất kỳ ai cũng có thể kết nối ẩn danh. Mọi lệnh đều được ghi lại, bao gồm danh tính kết nối, địa chỉ IP, khóa và kết quả. Thông tin xác thực không bao giờ được lưu trữ. Mật khẩu được nhập bằng login, hoặc khóa nhà cung cấp được truyền qua --values, được thay thế bằng <redacted> trước khi bản ghi được ghi. Hệ thống cũng lưu trữ một hàm băm của lệnh gốc để các lệnh lặp lại có thể được tương quan mà không làm cho thông tin xác thực có thể khôi phục được. Các bản ghi được giữ lại trong 30 ngày hoặc 100.000 lệnh, tùy theo điều kiện nào đến trước.
Các lần đăng nhập thất bại liên tiếp trở nên chậm hơn thay vì kích hoạt khóa. Một người nào đó đã quên mật khẩu họ đã sử dụng có thể tiếp tục thử mà không gặp nhiều trở ngại, trong khi một vòng lặp thử lại tự động sử dụng sai mật khẩu trở nên kém hữu ích hơn. Đó là sự đánh đổi dự định.
TLDR
Mọi người khác cung cấp cho agent của bạn một API, một máy chủ MCP hoặc một tệp kỹ năng. Chúng tôi đã cho nó một terminal. Hóa ra đó là thứ nó muốn.





